pyhocon icon indicating copy to clipboard operation
pyhocon copied to clipboard

Tests fail on Python 3.8.1

Open mhjacks opened this issue 6 years ago • 8 comments

I'm working on getting pyhocon packaged in Fedora. The tests currently succeed on Python 3.7 (and released Fedoras) but currently fail on Python 3.8.1 (which will be in the next released fedora). Here are the details from the test log - this is as of 0.3.53 as well as master version 0ded0b3:

`======================================= test session starts ======================================== platform linux -- Python 3.8.1, pytest-5.3.2, py-1.8.1, pluggy-0.13.1 rootdir: /home/mjackson/gitwork/pyhocon collected 232 items

tests/test_config_parser.py ................................................................ [ 27%] ................................................................FF.............F.F..F.FF.F.. [ 67%] .....F.....F.............F............ [ 83%] tests/test_config_tree.py ...................... [ 93%] tests/test_converter.py ........ [ 96%] tests/test_tool.py ........ [100%]

============================================= FAILURES ============================================= ____________________________ TestConfigParser.test_optional_with_merge _____________________________

self = <test_config_parser.TestConfigParser object at 0x7f80457444f0>

def test_optional_with_merge(self):
    unresolved = ConfigFactory.parse_string(
        """
        foo: 42
        foo: ${?a}
        """, resolve=False)
    source = ConfigFactory.parse_string(
        """
        b: 14
        """)
  config = unresolved.with_fallback(source)

tests/test_config_parser.py:1366:


pyhocon/config_tree.py:396: in with_fallback result = ConfigTree.merge_configs(copy.deepcopy(config), copy.deepcopy(self)) /usr/lib64/python3.8/copy.py:172: in deepcopy y = _reconstruct(x, memo, *rv) /usr/lib64/python3.8/copy.py:269: in _reconstruct state = deepcopy(state, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:204: in _deepcopy_list append(deepcopy(a, memo)) /usr/lib64/python3.8/copy.py:172: in deepcopy y = _reconstruct(x, memo, *rv) /usr/lib64/python3.8/copy.py:269: in _reconstruct state = deepcopy(state, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo)


x = ([[ConfigSubstitution: a]], {}) memo = {140188896938560: [42], 140188899284208: <[AttributeError("'ConfigValues' object has no attribute 'tokens'") raised in repr()] ConfigValues object at 0x7f80456460a0>, 140188899845248: {}, 140188899972608: {'root': True}, ...} _nil = []

def deepcopy(x, memo=None, _nil=[]):
    """Deep copy operation on arbitrary Python objects.

    See the module's __doc__ string for more info.
    """

    if memo is None:
        memo = {}

    d = id(x)
    y = memo.get(d, _nil)
    if y is not _nil:
        return y

    cls = type(x)

    copier = _deepcopy_dispatch.get(cls)
    if copier is not None:
        y = copier(x, memo)
    else:
        if issubclass(cls, type):
            y = _deepcopy_atomic(x, memo)
        else:
            copier = getattr(x, "__deepcopy__", None)
            if copier is not None:
              y = copier(memo)

E TypeError: 'str' object is not callable

/usr/lib64/python3.8/copy.py:153: TypeError ___________________________ TestConfigParser.test_fallback_with_resolve ____________________________

self = <test_config_parser.TestConfigParser object at 0x7f8045736310>

def test_fallback_with_resolve(self):
    config3 = ConfigFactory.parse_string("c=5")
    config2 = ConfigFactory.parse_string("b=${c}", resolve=False)
  config1 = ConfigFactory.parse_string("a=${b}", resolve=False) \
        .with_fallback(config2, resolve=False) \
        .with_fallback(config3)

tests/test_config_parser.py:1374:


pyhocon/config_tree.py:396: in with_fallback result = ConfigTree.merge_configs(copy.deepcopy(config), copy.deepcopy(self)) /usr/lib64/python3.8/copy.py:172: in deepcopy y = _reconstruct(x, memo, *rv) /usr/lib64/python3.8/copy.py:269: in _reconstruct state = deepcopy(state, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:204: in _deepcopy_list append(deepcopy(a, memo)) /usr/lib64/python3.8/copy.py:172: in deepcopy y = _reconstruct(x, memo, *rv) /usr/lib64/python3.8/copy.py:269: in _reconstruct state = deepcopy(state, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo)


x = ([[ConfigSubstitution: c]], {}) memo = {140188894991104: {'root': True}, 140188899066160: <[AttributeError("'ConfigValues' object has no attribute 'tokens'") raised in repr()] ConfigValues object at 0x7f804549a550>, 140188899266688: {}, 140188899569792: [], ...} _nil = []

def deepcopy(x, memo=None, _nil=[]):
    """Deep copy operation on arbitrary Python objects.

    See the module's __doc__ string for more info.
    """

    if memo is None:
        memo = {}

    d = id(x)
    y = memo.get(d, _nil)
    if y is not _nil:
        return y

    cls = type(x)

    copier = _deepcopy_dispatch.get(cls)
    if copier is not None:
        y = copier(x, memo)
    else:
        if issubclass(cls, type):
            y = _deepcopy_atomic(x, memo)
        else:
            copier = getattr(x, "__deepcopy__", None)
            if copier is not None:
              y = copier(memo)

E TypeError: 'str' object is not callable

/usr/lib64/python3.8/copy.py:153: TypeError ______________________ TestConfigParser.test_fallback_substitutions_overwrite ______________________

self = <test_config_parser.TestConfigParser object at 0x7f8045bebe50>

def test_fallback_substitutions_overwrite(self):
    config1 = ConfigFactory.parse_string(
        """
        a = {
            b: 1
            c: 2
        }
        """
    )

    config2 = ConfigFactory.parse_string(
        """
        a.b = 4
        a.d = 3
        """
    )

    config3 = config1.with_fallback(config2)

    assert config3['a'] == {
        'b': 1,
        'c': 2,
        'd': 3
    }

    config4 = ConfigFactory.parse_string(
        """
        name: foo
        """
    )

    config5 = ConfigFactory.parse_string(
        u"""
        longName: "long "${?name}
        """,
        resolve=False
    )
  config6 = config4.with_fallback(config5)

tests/test_config_parser.py:1693:


pyhocon/config_tree.py:396: in with_fallback result = ConfigTree.merge_configs(copy.deepcopy(config), copy.deepcopy(self)) /usr/lib64/python3.8/copy.py:172: in deepcopy y = _reconstruct(x, memo, *rv) /usr/lib64/python3.8/copy.py:269: in _reconstruct state = deepcopy(state, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:204: in _deepcopy_list append(deepcopy(a, memo)) /usr/lib64/python3.8/copy.py:172: in deepcopy y = _reconstruct(x, memo, *rv) /usr/lib64/python3.8/copy.py:269: in _reconstruct state = deepcopy(state, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo)


x = ([[ConfigQuotedString: long ], [ConfigSubstitution: name]], {}) memo = {140188895576704: <[AttributeError("'ConfigValues' object has no attribute 'tokens'") raised in repr()] ConfigValues object at 0x7f80458e3400>, 140188897727424: [], 140188899356992: {'root': True}, 140188899358592: {}, ...} _nil = []

def deepcopy(x, memo=None, _nil=[]):
    """Deep copy operation on arbitrary Python objects.

    See the module's __doc__ string for more info.
    """

    if memo is None:
        memo = {}

    d = id(x)
    y = memo.get(d, _nil)
    if y is not _nil:
        return y

    cls = type(x)

    copier = _deepcopy_dispatch.get(cls)
    if copier is not None:
        y = copier(x, memo)
    else:
        if issubclass(cls, type):
            y = _deepcopy_atomic(x, memo)
        else:
            copier = getattr(x, "__deepcopy__", None)
            if copier is not None:
              y = copier(memo)

E TypeError: 'str' object is not callable

/usr/lib64/python3.8/copy.py:153: TypeError ___________________ TestConfigParser.test_fallback_self_ref_substitutions_append ___________________

self = <test_config_parser.TestConfigParser object at 0x7f8045758d60>

def test_fallback_self_ref_substitutions_append(self):
    config1 = ConfigFactory.parse_string(
        """
        list = [ 1, 2, 3 ]
        """
    )
    config2 = ConfigFactory.parse_string(
        """
        list = ${list} [ 4, 5, 6 ]
        """,
        resolve=False
    )
  config2 = config2.with_fallback(config1)

tests/test_config_parser.py:1731:


pyhocon/config_tree.py:396: in with_fallback result = ConfigTree.merge_configs(copy.deepcopy(config), copy.deepcopy(self)) /usr/lib64/python3.8/copy.py:172: in deepcopy y = _reconstruct(x, memo, *rv) /usr/lib64/python3.8/copy.py:269: in _reconstruct state = deepcopy(state, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:204: in _deepcopy_list append(deepcopy(a, memo)) /usr/lib64/python3.8/copy.py:172: in deepcopy y = _reconstruct(x, memo, *rv) /usr/lib64/python3.8/copy.py:269: in _reconstruct state = deepcopy(state, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo)


x = ([[ConfigSubstitution: list], [4, 5, 6]], {}) memo = {140188895021120: {}, 140188896049536: {'root': True}, 140188898020160: ConfigTree(), 140188898631296: <[AttributeError("'ConfigValues' object has no attribute 'tokens'") raised in repr()] ConfigValues object at 0x7f8045758100>, ...} _nil = []

def deepcopy(x, memo=None, _nil=[]):
    """Deep copy operation on arbitrary Python objects.

    See the module's __doc__ string for more info.
    """

    if memo is None:
        memo = {}

    d = id(x)
    y = memo.get(d, _nil)
    if y is not _nil:
        return y

    cls = type(x)

    copier = _deepcopy_dispatch.get(cls)
    if copier is not None:
        y = copier(x, memo)
    else:
        if issubclass(cls, type):
            y = _deepcopy_atomic(x, memo)
        else:
            copier = getattr(x, "__deepcopy__", None)
            if copier is not None:
              y = copier(memo)

E TypeError: 'str' object is not callable

/usr/lib64/python3.8/copy.py:153: TypeError ____________________ TestConfigParser.test_self_merge_ref_substitutions_object2 ____________________

self = <test_config_parser.TestConfigParser object at 0x7f80458105b0>

def test_self_merge_ref_substitutions_object2(self):
    config1 = ConfigFactory.parse_string(
        """
        x : { v1: 1 }
        b1 : {v2: 2 }
        b = [${b1}]
        """,
        resolve=False
    )
    config2 = ConfigFactory.parse_string(
        """
        b2 : ${x} {v2: 3}
        b += [${b2}]
        """,
        resolve=False
    )
    merged = ConfigTree.merge_configs(config1, config2)
  ConfigParser.resolve_substitutions(merged)

tests/test_config_parser.py:1786:


pyhocon/config_parser.py:580: in resolve_substitutions cls._fixup_self_references(config, accept_unresolved) pyhocon/config_parser.py:484: in _fixup_self_references _, _, current_item = cls._do_substitute(substitution, value) pyhocon/config_parser.py:536: in _do_substitute config_values.put(substitution.index, copy.deepcopy(formatted_resolved_value)) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:204: in _deepcopy_list append(deepcopy(a, memo)) /usr/lib64/python3.8/copy.py:172: in deepcopy y = _reconstruct(x, memo, *rv) /usr/lib64/python3.8/copy.py:269: in _reconstruct state = deepcopy(state, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo)


x = ([[ConfigSubstitution: b1]], {}) memo = {140188896917120: [], 140188898434112: {}, 140188899471072: <[AttributeError("'ConfigValues' object has no attribute 'tokens'") raised in repr()] ConfigValues object at 0x7f8045978940>} _nil = []

def deepcopy(x, memo=None, _nil=[]):
    """Deep copy operation on arbitrary Python objects.

    See the module's __doc__ string for more info.
    """

    if memo is None:
        memo = {}

    d = id(x)
    y = memo.get(d, _nil)
    if y is not _nil:
        return y

    cls = type(x)

    copier = _deepcopy_dispatch.get(cls)
    if copier is not None:
        y = copier(x, memo)
    else:
        if issubclass(cls, type):
            y = _deepcopy_atomic(x, memo)
        else:
            copier = getattr(x, "__deepcopy__", None)
            if copier is not None:
              y = copier(memo)

E TypeError: 'str' object is not callable

/usr/lib64/python3.8/copy.py:153: TypeError ___________________ TestConfigParser.test_fallback_self_ref_substitutions_merge ____________________

self = <test_config_parser.TestConfigParser object at 0x7f804560e700>

def test_fallback_self_ref_substitutions_merge(self):
    config1 = ConfigFactory.parse_string(
        """
        dict = { x: 1 }
        """
    )
    config2 = ConfigFactory.parse_string(
        """
        dict = ${dict} { y: 2 }
        """,
        resolve=False
    )
  config2 = config2.with_fallback(config1)

tests/test_config_parser.py:1825:


pyhocon/config_tree.py:396: in with_fallback result = ConfigTree.merge_configs(copy.deepcopy(config), copy.deepcopy(self)) /usr/lib64/python3.8/copy.py:172: in deepcopy y = _reconstruct(x, memo, *rv) /usr/lib64/python3.8/copy.py:269: in _reconstruct state = deepcopy(state, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:204: in _deepcopy_list append(deepcopy(a, memo)) /usr/lib64/python3.8/copy.py:172: in deepcopy y = _reconstruct(x, memo, *rv) /usr/lib64/python3.8/copy.py:269: in _reconstruct state = deepcopy(state, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo)


x = ([[ConfigSubstitution: dict], ConfigTree([('y', 2)])], {}) memo = {140188895631728: <[AttributeError("'ConfigValues' object has no attribute 'tokens'") raised in repr()] ConfigValues object at 0x7f8045480460>, 140188896864000: {}, 140188898730112: {'root': True}, 140188899170240: [], ...} _nil = []

def deepcopy(x, memo=None, _nil=[]):
    """Deep copy operation on arbitrary Python objects.

    See the module's __doc__ string for more info.
    """

    if memo is None:
        memo = {}

    d = id(x)
    y = memo.get(d, _nil)
    if y is not _nil:
        return y

    cls = type(x)

    copier = _deepcopy_dispatch.get(cls)
    if copier is not None:
        y = copier(x, memo)
    else:
        if issubclass(cls, type):
            y = _deepcopy_atomic(x, memo)
        else:
            copier = getattr(x, "__deepcopy__", None)
            if copier is not None:
              y = copier(memo)

E TypeError: 'str' object is not callable

/usr/lib64/python3.8/copy.py:153: TypeError _______________ TestConfigParser.test_fallback_self_ref_substitutions_concat_string ________________

self = <test_config_parser.TestConfigParser object at 0x7f804541a520>

def test_fallback_self_ref_substitutions_concat_string(self):
    config1 = ConfigFactory.parse_string(
        """
        string = abc
        """
    )
    config2 = ConfigFactory.parse_string(
        """
        string = ${string}def
        """,
        resolve=False
    )
  result = config2.with_fallback(config1)

tests/test_config_parser.py:1840:


pyhocon/config_tree.py:396: in with_fallback result = ConfigTree.merge_configs(copy.deepcopy(config), copy.deepcopy(self)) /usr/lib64/python3.8/copy.py:172: in deepcopy y = _reconstruct(x, memo, *rv) /usr/lib64/python3.8/copy.py:269: in _reconstruct state = deepcopy(state, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:204: in _deepcopy_list append(deepcopy(a, memo)) /usr/lib64/python3.8/copy.py:172: in deepcopy y = _reconstruct(x, memo, *rv) /usr/lib64/python3.8/copy.py:269: in _reconstruct state = deepcopy(state, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo)


x = ([[ConfigSubstitution: string], 'def'], {}) memo = {140188894413568: [], 140188896562752: {}, 140188897958208: {'root': True}, 140188897959808: {}, ...} _nil = []

def deepcopy(x, memo=None, _nil=[]):
    """Deep copy operation on arbitrary Python objects.

    See the module's __doc__ string for more info.
    """

    if memo is None:
        memo = {}

    d = id(x)
    y = memo.get(d, _nil)
    if y is not _nil:
        return y

    cls = type(x)

    copier = _deepcopy_dispatch.get(cls)
    if copier is not None:
        y = copier(x, memo)
    else:
        if issubclass(cls, type):
            y = _deepcopy_atomic(x, memo)
        else:
            copier = getattr(x, "__deepcopy__", None)
            if copier is not None:
              y = copier(memo)

E TypeError: 'str' object is not callable

/usr/lib64/python3.8/copy.py:153: TypeError _________________________ TestConfigParser.test_object_field_substitution __________________________

self = <test_config_parser.TestConfigParser object at 0x7f804550ea90>

def test_object_field_substitution(self):
  config = ConfigFactory.parse_string(
        """
        A = ${Test}

        Test {
            field1 = 1
            field2 = ${Test.field1}"2"
            field3 = ${Test.field2}"3"
        }
        """
    )

tests/test_config_parser.py:1860:


pyhocon/config_parser.py:150: in parse_string return ConfigParser().parse(content, basedir, resolve, unresolved_value) pyhocon/config_parser.py:423: in parse has_unresolved = cls.resolve_substitutions(config, allow_unresolved) pyhocon/config_parser.py:616: in resolve_substitutions unresolved, new_substitutions, result = cls._do_substitute(substitution, resolved_value, is_optional_resolved) pyhocon/config_parser.py:536: in _do_substitute config_values.put(substitution.index, copy.deepcopy(formatted_resolved_value)) /usr/lib64/python3.8/copy.py:172: in deepcopy y = _reconstruct(x, memo, *rv) /usr/lib64/python3.8/copy.py:295: in _reconstruct value = deepcopy(value, memo) /usr/lib64/python3.8/copy.py:172: in deepcopy y = _reconstruct(x, memo, *rv) /usr/lib64/python3.8/copy.py:269: in _reconstruct state = deepcopy(state, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo)


x = ([[ConfigSubstitution: Test.field1], [ConfigQuotedString: 2]], {}) memo = {140188895522240: <[AttributeError("'ConfigValues' object has no attribute 'tokens'") raised in repr()] ConfigValues object at 0x7f804596d3a0>, 140188895929088: [{'root': False}], 140188899267904: {}, 140188900014592: {'root': False}, ...} _nil = []

def deepcopy(x, memo=None, _nil=[]):
    """Deep copy operation on arbitrary Python objects.

    See the module's __doc__ string for more info.
    """

    if memo is None:
        memo = {}

    d = id(x)
    y = memo.get(d, _nil)
    if y is not _nil:
        return y

    cls = type(x)

    copier = _deepcopy_dispatch.get(cls)
    if copier is not None:
        y = copier(x, memo)
    else:
        if issubclass(cls, type):
            y = _deepcopy_atomic(x, memo)
        else:
            copier = getattr(x, "__deepcopy__", None)
            if copier is not None:
              y = copier(memo)

E TypeError: 'str' object is not callable

/usr/lib64/python3.8/copy.py:153: TypeError __________________________________ TestConfigParser.test_issue_75 __________________________________

self = <test_config_parser.TestConfigParser object at 0x7f8045505f40>

def test_issue_75(self):
  config = ConfigFactory.parse_string(
        """base : {
          bar: ["a"]
        }

        sub : ${base} {
          baz: ${base.bar} ["b"]
        }

        sub2: ${sub}
        """
    )

tests/test_config_parser.py:1983:


pyhocon/config_parser.py:150: in parse_string return ConfigParser().parse(content, basedir, resolve, unresolved_value) pyhocon/config_parser.py:423: in parse has_unresolved = cls.resolve_substitutions(config, allow_unresolved) pyhocon/config_parser.py:616: in resolve_substitutions unresolved, new_substitutions, result = cls._do_substitute(substitution, resolved_value, is_optional_resolved) pyhocon/config_parser.py:536: in _do_substitute config_values.put(substitution.index, copy.deepcopy(formatted_resolved_value)) /usr/lib64/python3.8/copy.py:172: in deepcopy y = _reconstruct(x, memo, *rv) /usr/lib64/python3.8/copy.py:295: in _reconstruct value = deepcopy(value, memo) /usr/lib64/python3.8/copy.py:172: in deepcopy y = _reconstruct(x, memo, *rv) /usr/lib64/python3.8/copy.py:269: in _reconstruct state = deepcopy(state, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo)


x = ([[ConfigSubstitution: base.bar], ['b']], {}) memo = {140188895405968: <[AttributeError("'ConfigValues' object has no attribute 'tokens'") raised in repr()] ConfigValues o...f804587d6d0>, 140188897406080: [{'root': False}, ['a']], 140188897705408: {'root': False}, 140188898938240: ['a'], ...} _nil = []

def deepcopy(x, memo=None, _nil=[]):
    """Deep copy operation on arbitrary Python objects.

    See the module's __doc__ string for more info.
    """

    if memo is None:
        memo = {}

    d = id(x)
    y = memo.get(d, _nil)
    if y is not _nil:
        return y

    cls = type(x)

    copier = _deepcopy_dispatch.get(cls)
    if copier is not None:
        y = copier(x, memo)
    else:
        if issubclass(cls, type):
            y = _deepcopy_atomic(x, memo)
        else:
            copier = getattr(x, "__deepcopy__", None)
            if copier is not None:
              y = copier(memo)

E TypeError: 'str' object is not callable

/usr/lib64/python3.8/copy.py:153: TypeError ___________________________ TestConfigParser.test_complex_substitutions ____________________________

self = <test_config_parser.TestConfigParser object at 0x7f804576fca0>

def test_complex_substitutions(self):
  config = ConfigFactory.parse_string(
        """
        a: 1
        b: ${c} {
          pa: [${a}]
          pb: ${b.pa}
        }
        c: { }
        d: { pc: ${b.pa} }
        e: ${b}
        """, resolve=True)

tests/test_config_parser.py:2064:


pyhocon/config_parser.py:150: in parse_string return ConfigParser().parse(content, basedir, resolve, unresolved_value) pyhocon/config_parser.py:423: in parse has_unresolved = cls.resolve_substitutions(config, allow_unresolved) pyhocon/config_parser.py:616: in resolve_substitutions unresolved, new_substitutions, result = cls._do_substitute(substitution, resolved_value, is_optional_resolved) pyhocon/config_parser.py:536: in _do_substitute config_values.put(substitution.index, copy.deepcopy(formatted_resolved_value)) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:204: in _deepcopy_list append(deepcopy(a, memo)) /usr/lib64/python3.8/copy.py:172: in deepcopy y = _reconstruct(x, memo, *rv) /usr/lib64/python3.8/copy.py:269: in _reconstruct state = deepcopy(state, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo)


x = ([[ConfigSubstitution: a]], {}) memo = {140188894682240: [], 140188897488192: {}, 140188922134192: <[AttributeError("'ConfigValues' object has no attribute 'tokens'") raised in repr()] ConfigValues object at 0x7f8046e7b700>} _nil = []

def deepcopy(x, memo=None, _nil=[]):
    """Deep copy operation on arbitrary Python objects.

    See the module's __doc__ string for more info.
    """

    if memo is None:
        memo = {}

    d = id(x)
    y = memo.get(d, _nil)
    if y is not _nil:
        return y

    cls = type(x)

    copier = _deepcopy_dispatch.get(cls)
    if copier is not None:
        y = copier(x, memo)
    else:
        if issubclass(cls, type):
            y = _deepcopy_atomic(x, memo)
        else:
            copier = getattr(x, "__deepcopy__", None)
            if copier is not None:
              y = copier(memo)

E TypeError: 'str' object is not callable

/usr/lib64/python3.8/copy.py:153: TypeError ______________________________ TestConfigParser.test_mutation_values _______________________________

self = <test_config_parser.TestConfigParser object at 0x7f8045744fd0>

def test_mutation_values(self):
  config = ConfigFactory.parse_string(
        """
        common : {
        }

        b1 = []

        var = "wrong"

        compilerCommon : ${common} {
            VAR : ${var}
        }

        substrate-suite: {
            VAR  : "right"
        }
        b1 = [
          ${compilerCommon} ${substrate-suite}
          ${compilerCommon} ${substrate-suite}
        ]

        b2 = [
          ${compilerCommon} ${substrate-suite}
          ${compilerCommon} ${substrate-suite}
        ]
        """)

tests/test_config_parser.py:2240:


pyhocon/config_parser.py:150: in parse_string return ConfigParser().parse(content, basedir, resolve, unresolved_value) pyhocon/config_parser.py:423: in parse has_unresolved = cls.resolve_substitutions(config, allow_unresolved) pyhocon/config_parser.py:616: in resolve_substitutions unresolved, new_substitutions, result = cls._do_substitute(substitution, resolved_value, is_optional_resolved) pyhocon/config_parser.py:536: in _do_substitute config_values.put(substitution.index, copy.deepcopy(formatted_resolved_value)) /usr/lib64/python3.8/copy.py:172: in deepcopy y = _reconstruct(x, memo, *rv) /usr/lib64/python3.8/copy.py:295: in _reconstruct value = deepcopy(value, memo) /usr/lib64/python3.8/copy.py:172: in deepcopy y = _reconstruct(x, memo, *rv) /usr/lib64/python3.8/copy.py:269: in _reconstruct state = deepcopy(state, memo) /usr/lib64/python3.8/copy.py:146: in deepcopy y = copier(x, memo) /usr/lib64/python3.8/copy.py:229: in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo)


x = ([[ConfigSubstitution: var]], {}) memo = {140188895441088: [{'root': False}], 140188895444416: {'root': False}, 140188896502592: {}, 140188898064320: ConfigTree(), ...} _nil = []

def deepcopy(x, memo=None, _nil=[]):
    """Deep copy operation on arbitrary Python objects.

    See the module's __doc__ string for more info.
    """

    if memo is None:
        memo = {}

    d = id(x)
    y = memo.get(d, _nil)
    if y is not _nil:
        return y

    cls = type(x)

    copier = _deepcopy_dispatch.get(cls)
    if copier is not None:
        y = copier(x, memo)
    else:
        if issubclass(cls, type):
            y = _deepcopy_atomic(x, memo)
        else:
            copier = getattr(x, "__deepcopy__", None)
            if copier is not None:
              y = copier(memo)

E TypeError: 'str' object is not callable

/usr/lib64/python3.8/copy.py:153: TypeError ========================================= warnings summary ========================================= tests/test_config_parser.py::TestConfigParser::test_parse_URL_from_invalid /home/mjackson/gitwork/pyhocon/pyhocon/config_parser.py:128: DeprecationWarning: The 'warn' method is deprecated, use 'warning' instead logger.warn('Cannot include url %s. Resource is inaccessible.', url)

tests/test_config_parser.py::TestConfigParser::test_include_missing_file /home/mjackson/gitwork/pyhocon/pyhocon/config_parser.py:103: DeprecationWarning: The 'warn' method is deprecated, use 'warning' instead logger.warn('Cannot include file %s. File does not exist or cannot be read.', filename)

-- Docs: https://docs.pytest.org/en/latest/warnings.html ============================ 11 failed, 221 passed, 2 warnings in 2.50s ============================`

mhjacks avatar Dec 29 '19 23:12 mhjacks

The problem comes from this line in pyparsing:

class ParseResults(object):
    def __getattr__(self, name):
        try:
            return self[name]
        except KeyError:
            return ""    # <-- here

When copy.deepcopy()ing a ConfigTree with a ParseResults in it, that ParseResults is asked for its __deepcopy__ attribute. It doesn't have one, but pretends to do so by returning that empty string.

ElkMonster avatar Feb 18 '20 12:02 ElkMonster

Is there an open issue on pyparsing for this? (I couldn't find one.) Or is there a local workaround possible?

scottj97 avatar Mar 01 '20 02:03 scottj97

@scottj97 Yes, you can build your own version of pyparsing. Simply change __get_attr__ to raise AttributeError:

def __getattr__(self, name):
        try:
            return self[name]
        except KeyError:
            raise AttributeError(name)

This fixes the problem with pyhocon, but it is unknown whether there are any side effects. There might be some reasons why they implemented it this way, considering pyparsing is a pretty mature project as it seems to me (well, at least has existed for pretty long). That's also why I didn't create an issue on pyparsing (but I put it on my reconsider-later list…).

Note on package creation: (Preamble: I'm not the most advanced Python packaging guy, the following is just what I did to get it done.) Creating the package with 'python setup.py …' fails due to the changed code. Packaging this package will somehow create a self-reference: setuptools imports pyparsing, which loads the local (just modified) pyparsing version, and something internal happens to rely on the code that we've modified, so we get an AttributeError, and the build fails. To circumvent this, use 'python -I', which ignores the local version and uses the globally installed package instead.

ElkMonster avatar Mar 04 '20 17:03 ElkMonster

Hi, any updates here? Also seeing these issues, trying to move to 3.8 with my company.

Solved this by monkey-patching

import pyparsing
class ParseResults(pyparsing.ParseResults):
    def __getattr__(self, item):
        if item == '__deepcopy__':
            raise AttributeError(item)
        try:
            return self[item]
        except KeyError:
            return ""
pyparsing.ParseResults = ParseResults

MichelEdkrantz avatar May 10 '20 09:05 MichelEdkrantz

The following tests fail for me (Win) on Python 3.7 and Python 2.7 image

USSX-Hares avatar Aug 18 '20 05:08 USSX-Hares

Hi.

Are there any updates? pyhocon still cannot be used on python3.8 and above.

dolfinus avatar Dec 05 '20 15:12 dolfinus

Looks like release 0.3.57 includes a fix for this from #245, have you tried that?

scottj97 avatar Dec 05 '20 15:12 scottj97

Haven't checked yet. Thanks!

dolfinus avatar Dec 05 '20 16:12 dolfinus