Skip to content

Cylic data dependencies cause infinite recursion #62

@buckley-w-david

Description

@buckley-w-david
  • Dataclass Wizard version: 0.22.1
  • Python version: 3.10.5
  • Operating System: Linux 5.18.7-arch1-1

Description

I am modeling some data that is self-referential, as in it may contain references to other object of its own type. In attempting to use dataclass-wizard to parse a dict of this data I received the following error

...
    return typing._eval_type(base_type, base_globals, _TYPING_LOCALS)
  File "/usr/lib/python3.10/typing.py", line 327, in _eval_type
    return t._evaluate(globalns, localns, recursive_guard)
  File "/usr/lib/python3.10/typing.py", line 693, in _evaluate
    type_ = _type_check(
  File "/usr/lib/python3.10/typing.py", line 164, in _type_check
    arg = _type_convert(arg, module=module, allow_special_forms=allow_special_forms)
  File "/usr/lib/python3.10/typing.py", line 141, in _type_convert
    if isinstance(arg, str):
RecursionError: maximum recursion depth exceeded while calling a Python object

What I Did

Here is a simple script to reproduce the issue

from typing import Optional
from dataclasses import dataclass
from dataclass_wizard import asdict, fromdict

@dataclass
class A:
    a: Optional['A'] = None

a = A(a=A(a=A(a=A())))
d = asdict(a)
print(d) # {'a': {'a': {'a': {'a': None}}}}
print(fromdict(A, d))

Any potential cyclic data dependency will trigger this issue, not just strictly self-referential ones.

from typing import Optional
from dataclasses import dataclass
from dataclass_wizard import asdict, fromdict

@dataclass
class A:
    b: Optional['B'] = None

@dataclass
class B:
    a: Optional['A'] = None

a = A(b=B(a=A(b=B(a=None))))
d = asdict(a)
print(d)  # {'b': {'a': {'b': {'a': None}}}}
print(fromdict(A, d))

I did a bit of digging in the code before submitting the issue to get an understanding of why this was happening, and I'm not sure it's an easy fix 😬

Not really expecting speedy resolution assuming you even want to support this kind of use case.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions