biqqles / dataclassy

A fast and flexible reimplementation of data classes
https://pypi.org/project/dataclassy
Mozilla Public License 2.0
81 stars 9 forks source link

Circular references to dataclasses cause infinite recursion in __repr__ #48

Closed lost-theory closed 3 years ago

lost-theory commented 3 years ago

This issue is similar to #11, but it happens on circular references of dataclass objects rather than a single dataclass with a property that references itself.

Here's how to reproduce infinite recursion in dataclassy's __repr__ method with dataclassy==0.10.2 installed from pypi:

from dataclassy import dataclass
from typing import Optional

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

@dataclass
class B:
    c: Optional["C"] = None

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

a = A()
b = B()
c = C(a=a)
a.b, b.c = b, c
print(repr(a))

Causes this traceback:

...
  File "dataclassy/dataclass.py", line 231, in __repr__
    field_values = ', '.join(f'{f}=...' if v is self
  File "dataclassy/dataclass.py", line 232, in <genexpr>
    else f'{f}={v!r}' for f, v in values(self, show_internals).items())
  File "dataclassy/dataclass.py", line 232, in __repr__
    else f'{f}={v!r}' for f, v in values(self, show_internals).items())
  File "dataclassy/functions.py", line 37, in values
    return {f: getattr(dataclass, f) for f in fields(dataclass, internals)}
  File "dataclassy/functions.py", line 28, in fields
    assert is_dataclass(dataclass)
  File "dataclassy/functions.py", line 16, in is_dataclass
    return isinstance(obj, DataClassMeta) or is_dataclass_instance(obj)
  File "dataclassy/functions.py", line 21, in is_dataclass_instance
    return isinstance(type(obj), DataClassMeta)
RecursionError: maximum recursion depth exceeded while calling a Python object
'''

This was fixed in this commit: https://github.com/biqqles/dataclassy/commit/0246588

Then reverted in this commit: https://github.com/biqqles/dataclassy/commit/73ebd10

If you add recursive_repr back then the issue goes away.

biqqles commented 3 years ago

Sorry, stupid mistake. I was concerned about the "overhead" of recursive_repr or something and obviously didn't think it through.

biqqles commented 3 years ago

Fix released in v0.10.3.

lost-theory commented 3 years ago

No worries, thanks for the quick fix!