With the last release, there is a RecursionError: maximum recursion depth exceeded during the serialisation of dataclasses using the Union decorator. The issue comes from the changes introduced in #77. Union is passed down through the MRO and creates an infinite recursion.
A simple solution is to add a check at:
|
if isinstance(item, setting_type): |
We should avoid yielding a Union. Possibly adding a inheritable attribute to ClassDecoratorSetting that identifies which decorators should be inherited. Then the previous line becomes something like: if isinstance(item, setting_type) and (klass is type_ or item.inheritable):.
Small example to reproduce the error:
from dataclasses import dataclass
from databind.core import ObjectMapper, Union
from databind.json import JsonModule
@Union(style=Union.FLAT)
@dataclass
class Base:
x: float = 0.0
@Union.register(Base, "a")
@dataclass
class A(Base):
pass
@Union.register(Base, "b")
@dataclass
class B(Base):
y: float = 0.0
mapper = ObjectMapper()
mapper.module.register(JsonModule())
try:
result = mapper.deserialize({"type": "a", "x": 1.0}, Base)
print(f"OK deserialize Base: {result}")
except RecursionError:
print("FAIL deserialize Base: RecursionError")
try:
result = mapper.serialize(A(x=1.0), Base)
print(f"OK serialize Base: {result}")
except RecursionError:
print("FAIL serialize Base: RecursionError")
try:
result = mapper.deserialize([{"type": "a", "x": 1.0}, {"type": "b", "x": 2.0, "y": 3.0}], list[Base])
print(f"OK deserialize list[Base]: {result}")
except RecursionError:
print("FAIL deserialize list[Base]: RecursionError")
try:
result = mapper.serialize([A(x=1.0), B(x=2.0, y=3.0)], list[Base])
print(f"OK serialize list[Base]: {result}")
except RecursionError:
print("FAIL serialize list[Base]: RecursionError")
nit: The version in the __init__ files still point to 3.5.2.
With the last release, there is a
RecursionError: maximum recursion depth exceededduring the serialisation of dataclasses using theUniondecorator. The issue comes from the changes introduced in #77.Unionis passed down through the MRO and creates an infinite recursion.A simple solution is to add a check at:
python-databind/databind/src/databind/core/settings.py
Line 206 in a11f4a4
We should avoid yielding a
Union. Possibly adding ainheritableattribute toClassDecoratorSettingthat identifies which decorators should be inherited. Then the previous line becomes something like:if isinstance(item, setting_type) and (klass is type_ or item.inheritable):.Small example to reproduce the error:
nit: The version in the
__init__files still point to3.5.2.