Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests fail on Python 3.8.1 #220

Open
mhjacks opened this issue Dec 29, 2019 · 8 comments
Open

Tests fail on Python 3.8.1 #220

mhjacks opened this issue Dec 29, 2019 · 8 comments

Comments

@mhjacks
Copy link

mhjacks commented Dec 29, 2019

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 ============================`

@ElkMonster
Copy link

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.

@scottj97
Copy link
Contributor

scottj97 commented Mar 1, 2020

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

@ElkMonster
Copy link

ElkMonster commented Mar 4, 2020

@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.

@MichelEdkrantz
Copy link

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

@USSX-Hares
Copy link
Contributor

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

@dolfinus
Copy link

dolfinus commented Dec 5, 2020

Hi.

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

@scottj97
Copy link
Contributor

scottj97 commented Dec 5, 2020

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

@dolfinus
Copy link

dolfinus commented Dec 5, 2020

Haven't checked yet. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants