Allow override Scalar (assumed for dict,list) by None
diff --git a/README-extentions.rst b/README-extentions.rst
index 554a62d..97d78af 100644
--- a/README-extentions.rst
+++ b/README-extentions.rst
@@ -92,6 +92,37 @@
the final value.
+Allow override list and dicts by empty entity,None instead of merge
+-------------------------------------------------------------------
+
+With settings:
+
+.. code-block:: yaml
+
+ allow_none_override: True # default True
+
+ # note dict,list over None is allowed and not configurable
+
+Referenced lists or dicts can now be overriden by None or empty type of dict, list:
+
+.. code-block:: yaml
+
+ # nodes/test.yml
+ parameters:
+ one:
+ a: 1
+ b: 2
+ two: {}
+ three: None
+
+ # classes/test1.yml
+ parameters:
+ one: ${two}
+
+ # classes/test2.yml
+ parameters:
+ three: ${one}
+
Nested References
-----------------
diff --git a/reclass/datatypes/tests/test_parameters.py b/reclass/datatypes/tests/test_parameters.py
index bb9ec35..577bdc4 100644
--- a/reclass/datatypes/tests/test_parameters.py
+++ b/reclass/datatypes/tests/test_parameters.py
@@ -193,6 +193,40 @@
p1.initialise_interpolation()
self.assertEqual(p1.as_dict()['key'], l[2])
+ def test_merge_none_over_list(self):
+ l = ['foo', 1, 2]
+ settings = Settings({'allow_none_override': True})
+ p1 = Parameters(dict(key=l[:2]), settings, '')
+ p2 = Parameters(dict(key=None), settings, '')
+ p1.merge(p2)
+ p1.initialise_interpolation()
+ self.assertEqual(p1.as_dict()['key'], None)
+
+ def test_merge_none_over_dict(self):
+ settings = Settings({'allow_none_override': True})
+ p1 = Parameters(dict(key=SIMPLE), settings, '')
+ p2 = Parameters(dict(key=None), settings, '')
+ p1.merge(p2)
+ p1.initialise_interpolation()
+ self.assertEqual(p1.as_dict()['key'], None)
+
+ # def test_merge_bare_dict_over_dict(self):
+ # settings = Settings({'allow_bare_override': True})
+ # p1 = Parameters(dict(key=SIMPLE), settings, '')
+ # p2 = Parameters(dict(key=dict()), settings, '')
+ # p1.merge(p2)
+ # p1.initialise_interpolation()
+ # self.assertEqual(p1.as_dict()['key'], {})
+
+ # def test_merge_bare_list_over_list(self):
+ # l = ['foo', 1, 2]
+ # settings = Settings({'allow_bare_override': True})
+ # p1 = Parameters(dict(key=l), settings, '')
+ # p2 = Parameters(dict(key=list()), settings, '')
+ # p1.merge(p2)
+ # p1.initialise_interpolation()
+ # self.assertEqual(p1.as_dict()['key'], [])
+
def test_merge_dicts(self):
mergee = {'five':5,'four':4,'None':None,'tuple':(1,2,3)}
p = Parameters(dict(dict=SIMPLE), SETTINGS, '')
diff --git a/reclass/defaults.py b/reclass/defaults.py
index ac8aa34..980bb92 100644
--- a/reclass/defaults.py
+++ b/reclass/defaults.py
@@ -29,6 +29,7 @@
OPT_ALLOW_SCALAR_OVER_LIST = False
OPT_ALLOW_LIST_OVER_SCALAR = False
OPT_ALLOW_DICT_OVER_SCALAR = False
+OPT_ALLOW_NONE_OVERRIDE = True
OPT_INVENTORY_IGNORE_FAILED_NODE = False
OPT_INVENTORY_IGNORE_FAILED_RENDER = False
diff --git a/reclass/settings.py b/reclass/settings.py
index a1e203e..44c58d8 100644
--- a/reclass/settings.py
+++ b/reclass/settings.py
@@ -9,6 +9,7 @@
self.allow_scalar_over_list = options.get('allow_scalar_over_list', OPT_ALLOW_SCALAR_OVER_LIST)
self.allow_list_over_scalar = options.get('allow_list_over_scalar', OPT_ALLOW_LIST_OVER_SCALAR)
self.allow_dict_over_scalar = options.get('allow_dict_over_scalar', OPT_ALLOW_DICT_OVER_SCALAR)
+ self.allow_none_override = options.get('allow_none_override', OPT_ALLOW_NONE_OVERRIDE)
self.automatic_parameters = options.get('automatic_parameters', AUTOMATIC_RECLASS_PARAMETERS)
self.default_environment = options.get('default_environment', DEFAULT_ENVIRONMENT)
self.delimiter = options.get('delimiter', PARAMETER_INTERPOLATION_DELIMITER)
@@ -38,6 +39,7 @@
and self.allow_scalar_over_list == other.allow_scalar_over_list \
and self.allow_list_over_scalar == other.allow_list_over_scalar \
and self.allow_dict_over_scalar == other.allow_dict_over_scalar \
+ and self.allow_none_override == other.allow_none_override \
and self.automatic_parameters == other.automatic_parameters \
and self.default_environment == other.default_environment \
and self.delimiter == other.delimiter \
diff --git a/reclass/values/scaitem.py b/reclass/values/scaitem.py
index 6fd3194..466d3c9 100644
--- a/reclass/values/scaitem.py
+++ b/reclass/values/scaitem.py
@@ -21,12 +21,12 @@
if item.type == Item.SCALAR:
return self
elif item.type == Item.LIST:
- if self._settings.allow_scalar_over_list:
+ if self._settings.allow_scalar_over_list or (self._settings.allow_none_override and self._value in [None, 'none', 'None']):
return self
else:
raise TypeError('allow scalar over list = False: cannot merge %s over %s' % (repr(self), repr(item)))
elif item.type == Item.DICTIONARY:
- if self._settings.allow_scalar_over_dict:
+ if self._settings.allow_scalar_over_dict or (self._settings.allow_none_override and self._value in [None, 'none', 'None']):
return self
else:
raise TypeError('allow scalar over dict = False: cannot merge %s over %s' % (repr(self), repr(item)))