fix escaped strings when the escaped string is in the second dict to be merged
missed a subtlety with the first fix for this issue that the if the escaped string
is in the second (or later) dict to be merged the parameters.merge method will wrap
the object to be merged, in this case the object to be merged should be deep copied
instead
diff --git a/reclass/datatypes/parameters.py b/reclass/datatypes/parameters.py
index 7467594..ac15925 100644
--- a/reclass/datatypes/parameters.py
+++ b/reclass/datatypes/parameters.py
@@ -181,7 +181,7 @@
else:
return self._update_value(cur, new)
- def merge(self, other):
+ def merge(self, other, wrap=True):
"""Merge function (public edition).
Call _merge_recurse on self with either another Parameter object or a
@@ -197,9 +197,15 @@
self._unrendered = None
if isinstance(other, dict):
- wrapped = self._wrap_dict(other, DictPath(self._settings.delimiter))
+ if wrap:
+ wrapped = self._wrap_dict(other, DictPath(self._settings.delimiter))
+ else:
+ wrapped = copy.deepcopy(other)
elif isinstance(other, self.__class__):
- wrapped = self._wrap_dict(other._base, DictPath(self._settings.delimiter))
+ if wrap:
+ wrapped = self._wrap_dict(other._base, DictPath(self._settings.delimiter))
+ else:
+ wrapped = copy.deepcopy(other._base)
else:
raise TypeError('Cannot merge %s objects into %s' % (type(other),
self.__class__.__name__))
diff --git a/reclass/datatypes/tests/test_parameters.py b/reclass/datatypes/tests/test_parameters.py
index 405f757..bb9ec35 100644
--- a/reclass/datatypes/tests/test_parameters.py
+++ b/reclass/datatypes/tests/test_parameters.py
@@ -572,5 +572,23 @@
self.assertEqual(error.exception.message, "-> \n Cannot resolve ${beta}, at alpha")
self.assertEqual(std_err.text(), err1)
+ def test_escaped_string_in_ref_dict_1(self):
+ # test with escaped string in first dict to be merged
+ p1 = Parameters({'a': { 'one': '${a_ref}' }, 'b': { 'two': '\${not_a_ref}' }, 'c': '${b}', 'a_ref': 123}, SETTINGS, '')
+ p2 = Parameters({'c': '${a}'}, SETTINGS, '')
+ r = { 'a': { 'one': 123 }, 'b': { 'two': '${not_a_ref}' }, 'c': { 'one': 123, 'two': '${not_a_ref}' }, 'a_ref': 123}
+ p1.merge(p2)
+ p1.interpolate()
+ self.assertEqual(p1.as_dict(), r)
+
+ def test_escaped_string_in_ref_dict_2(self):
+ # test with escaped string in second dict to be merged
+ p1 = Parameters({'a': { 'one': '${a_ref}' }, 'b': { 'two': '\${not_a_ref}' }, 'c': '${a}', 'a_ref': 123}, SETTINGS, '')
+ p2 = Parameters({'c': '${b}'}, SETTINGS, '')
+ r = { 'a': { 'one': 123 }, 'b': { 'two': '${not_a_ref}' }, 'c': { 'one': 123, 'two': '${not_a_ref}' }, 'a_ref': 123}
+ p1.merge(p2)
+ p1.interpolate()
+ self.assertEqual(p1.as_dict(), r)
+
if __name__ == '__main__':
unittest.main()
diff --git a/reclass/values/valuelist.py b/reclass/values/valuelist.py
index 99fbd23..46d8ec7 100644
--- a/reclass/values/valuelist.py
+++ b/reclass/values/valuelist.py
@@ -109,7 +109,7 @@
if isinstance(output, dict) and isinstance(new, dict):
p1 = Parameters(output, self._settings, None, merge_initialise = False)
p2 = Parameters(new, self._settings, None, merge_initialise = False)
- p1.merge(p2)
+ p1.merge(p2, wrap=False)
output = p1.as_dict()
continue
elif isinstance(output, list) and isinstance(new, list):