Merge pull request #19 from salt-formulas/andrew-fix-escapes
fix escaped strings in merged referenced dictionaries
diff --git a/reclass/datatypes/parameters.py b/reclass/datatypes/parameters.py
index e7199ab..ac15925 100644
--- a/reclass/datatypes/parameters.py
+++ b/reclass/datatypes/parameters.py
@@ -40,7 +40,7 @@
functionality and does not try to be a really mapping object.
'''
- def __init__(self, mapping, settings, uri):
+ def __init__(self, mapping, settings, uri, merge_initialise = True):
self._settings = settings
self._base = {}
self._uri = uri
@@ -51,10 +51,13 @@
self._needs_all_envs = False
self._keep_overrides = False
if mapping is not None:
- # we initialise by merging
- self._keep_overrides = True
- self.merge(mapping)
- self._keep_overrides = False
+ if merge_initialise:
+ # we initialise by merging
+ self._keep_overrides = True
+ self.merge(mapping)
+ self._keep_overrides = False
+ else:
+ self._base = copy.deepcopy(mapping)
#delimiter = property(lambda self: self._delimiter)
@@ -178,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
@@ -194,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 6201564..46d8ec7 100644
--- a/reclass/values/valuelist.py
+++ b/reclass/values/valuelist.py
@@ -107,9 +107,9 @@
deepCopied = False
else:
if isinstance(output, dict) and isinstance(new, dict):
- p1 = Parameters(output, self._settings, None)
- p2 = Parameters(new, self._settings, None)
- p1.merge(p2)
+ p1 = Parameters(output, self._settings, None, merge_initialise = False)
+ p2 = Parameters(new, self._settings, None, merge_initialise = False)
+ p1.merge(p2, wrap=False)
output = p1.as_dict()
continue
elif isinstance(output, list) and isinstance(new, list):