diff --git a/pyhocon/config_parser.py b/pyhocon/config_parser.py index 7ffdb88..a504697 100644 --- a/pyhocon/config_parser.py +++ b/pyhocon/config_parser.py @@ -38,11 +38,11 @@ def fixed_get_attr(self, item): use_urllib2 = False try: # For Python 3.0 and later - from urllib.request import urlopen from urllib.error import HTTPError, URLError + from urllib.request import urlopen except ImportError: # pragma: no cover # Fall back to Python 2's urllib2 - from urllib2 import urlopen, HTTPError, URLError + from urllib2 import HTTPError, URLError, urlopen use_urllib2 = True try: @@ -643,9 +643,11 @@ def resolve_substitutions(cls, config, accept_unresolved=False): continue is_optional_resolved, resolved_value = cls._resolve_variable(config, substitution) - if isinstance(resolved_value, ConfigValues) and overridden_value and not isinstance( - overridden_value, ConfigValues): - unresolved, _, _ = cls._do_substitute(substitution, overridden_value, is_optional_resolved) + if isinstance(resolved_value, ConfigValues) : + value_to_be_substitute = resolved_value + if overridden_value and not isinstance(overridden_value, ConfigValues): + value_to_be_substitute = overridden_value + unresolved, _, _ = cls._do_substitute(substitution, value_to_be_substitute, is_optional_resolved) any_unresolved = unresolved or any_unresolved if not unresolved and substitution in substitutions: substitutions.remove(substitution) @@ -656,6 +658,7 @@ def resolve_substitutions(cls, config, accept_unresolved=False): continue cache_values = [] + if isinstance(overridden_value, ConfigValues): cache_values = cache.get(substitution) if cache_values is None: diff --git a/setup.py b/setup.py index 2d6b631..7127c77 100755 --- a/setup.py +++ b/setup.py @@ -26,7 +26,7 @@ def run_tests(self): setup( name='pyhocon', - version='0.3.59', + version='0.3.61', description='HOCON parser for Python', long_description='pyhocon is a HOCON parser for Python. Additionally we provide a tool (pyhocon) to convert any HOCON ' 'content into json, yaml and properties format.', diff --git a/tests/test_config_parser.py b/tests/test_config_parser.py index 34e78cd..e81fdcd 100644 --- a/tests/test_config_parser.py +++ b/tests/test_config_parser.py @@ -14,10 +14,12 @@ # Python 2 from urllib import pathname2url -from pyparsing import ParseBaseException, ParseException, ParseSyntaxException import mock import pytest -from pyhocon import (ConfigFactory, ConfigParser, ConfigSubstitutionException, ConfigTree, HOCONConverter) +from pyparsing import ParseBaseException, ParseException, ParseSyntaxException + +from pyhocon import (ConfigFactory, ConfigParser, ConfigSubstitutionException, + ConfigTree, HOCONConverter) from pyhocon.exceptions import (ConfigException, ConfigMissingException, ConfigWrongTypeException) @@ -1486,7 +1488,6 @@ def test_include_dict(self): """.format(tmp_file=incl_name) ) assert config3['a'] == expected_res - finally: os.remove(incl_name) @@ -1747,6 +1748,21 @@ def test_cascade_optional_substitution(self): 'retries_msg': 'You have 3 retries' } + def test_override_optional_substitution(self): + config = ConfigFactory.parse_string( + """ + a = 3 + test = ${a} + test = ${?b} + result = ${test} + """) + assert config == { + 'a' : 3, + 'test': 3, + 'result': 3 + } + + def test_substitution_cycle(self): with pytest.raises(ConfigSubstitutionException): ConfigFactory.parse_string(