diff --git a/pyhocon/config_parser.py b/pyhocon/config_parser.py index 6846589d..2ac789c6 100644 --- a/pyhocon/config_parser.py +++ b/pyhocon/config_parser.py @@ -535,7 +535,10 @@ def _resolve_variable(cls, config, substitution): """ variable = substitution.variable try: - return True, config.get(variable) + if substitution.self_ref: + return True, substitution.parent.overriden_value + else: + return True, config.get(variable) except ConfigMissingException: # default to environment variable value = os.environ.get(variable) @@ -859,10 +862,10 @@ def postParse(self, instring, loc, token_list): else: value = values[0] if isinstance(value, list) and operator == "+=": - value = ConfigValues([ConfigSubstitution(key, True, '', False, loc), value], False, loc) + value = ConfigValues([ConfigSubstitution(key, True, '', False, loc, self_ref=True), value], False, loc) config_tree.put(key, value, False) elif isinstance(value, unicode) and operator == "+=": - value = ConfigValues([ConfigSubstitution(key, True, '', True, loc), ' ' + value], True, loc) + value = ConfigValues([ConfigSubstitution(key, True, '', True, loc, self_ref=True), ' ' + value], True, loc) config_tree.put(key, value, False) elif isinstance(value, list): config_tree.put(key, value, False) diff --git a/pyhocon/config_tree.py b/pyhocon/config_tree.py index 9996df53..dab47968 100644 --- a/pyhocon/config_tree.py +++ b/pyhocon/config_tree.py @@ -602,7 +602,7 @@ def __repr__(self): # pragma: no cover class ConfigSubstitution(object): - def __init__(self, variable, optional, ws, instring, loc): + def __init__(self, variable, optional, ws, instring, loc, self_ref=False): self.variable = variable self.optional = optional self.ws = ws @@ -610,6 +610,7 @@ def __init__(self, variable, optional, ws, instring, loc): self.parent = None self.instring = instring self.loc = loc + self.self_ref = self_ref def raw_str(self): return self.variable diff --git a/tests/test_config_parser.py b/tests/test_config_parser.py index 13a130fc..1c0942a8 100644 --- a/tests/test_config_parser.py +++ b/tests/test_config_parser.py @@ -807,7 +807,7 @@ def test_self_ref_substitution_array(self): ) assert config.get("x") == [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6] - def test_self_append_array(self): + def test_self_extend_array(self): config = ConfigFactory.parse_string( """ x = [1,2] @@ -816,6 +816,37 @@ def test_self_append_array(self): ) assert config.get("x") == [1, 2, 3, 4] + def test_self_append_array(self): + config = ConfigFactory.parse_string( + """ + x = [1,2] + x += 3 + """ + ) + assert config.get("x") == [1, 2, 3] + + def test_self_extend_array_inside_dict(self): + config = ConfigFactory.parse_string( + """ + d { + x = [1,2] + x += [3,4] + } + """ + ) + assert config.get("d.x") == [1, 2, 3, 4] + + def test_self_append_array_inside_dict(self): + config = ConfigFactory.parse_string( + """ + d { + x = [1,2] + x += 3 + } + """ + ) + assert config.get("d.x") == [1, 2, 3] + def test_self_append_string(self): ''' Should be equivalent to @@ -830,6 +861,22 @@ def test_self_append_string(self): ) assert config.get("x") == "abc def" + def test_self_append_string_inside_dict(self): + ''' + Should be equivalent to + x = abc + x = ${?x} def + ''' + config = ConfigFactory.parse_string( + """ + d { + x = abc + x += def + } + """ + ) + assert config.get("d.x") == "abc def" + def test_self_append_non_existent_string(self): ''' Should be equivalent to x = ${?x} def @@ -841,7 +888,7 @@ def test_self_append_non_existent_string(self): ) assert config.get("x") == " def" - def test_self_append_nonexistent_array(self): + def test_self_extend_nonexistent_array(self): config = ConfigFactory.parse_string( """ x += [1,2] @@ -849,6 +896,14 @@ def test_self_append_nonexistent_array(self): ) assert config.get("x") == [1, 2] + def test_self_append_nonexistent_array(self): + config = ConfigFactory.parse_string( + """ + x += 1 + """ + ) + assert config.get("x") == [1] + def test_self_append_object(self): config = ConfigFactory.parse_string( """ @@ -858,6 +913,17 @@ def test_self_append_object(self): ) assert config.get("x") == {'a': 1, 'b': 2} + def test_self_append_object_inside_dict(self): + config = ConfigFactory.parse_string( + """ + d { + x = {a: 1} + x += {b: 2} + } + """ + ) + assert config.get("d.x") == {'a': 1, 'b': 2} + def test_self_append_nonexistent_object(self): config = ConfigFactory.parse_string( """