yukinarit/pyserde

Serialization error for Union with a dataclass arg

Closed this issue · 3 comments

Given the following nested setup:

from dataclasses import dataclass

from serde import serde, to_dict


@serde
@dataclass
class Bar:
    num: float = 20


@serde
@dataclass
class Foo:
    b: Bar | int


f = Foo(Bar())

print(to_dict(f))

I get this error:

Traceback (most recent call last):
  File "pyserde/issue.py", line 20, in <module>
    print(to_dict(f))
  File "pyserde/serde/se.py", line 451, in to_dict
    return to_obj(  # type: ignore
  File "pyserde/serde/se.py", line 379, in to_obj
    raise SerdeError(e) from None
serde.compat.SerdeError: Can not serialize Bar(num=20) of type Bar for Union[Bar, int]

Looking at the auto-generated code, it appears this if statement resolves to False. However, if you replace

  if is_instance(obj, union_args[{{loop.index0}}]):

with

  if type(obj) is union_args[{{loop.index0}}]:

Then everything works. Haven't had a chance to dig too deep into what the cause of this could be yet.

Seeing this issue on latest pypi release and main, Python 3.10.12, tested on MacOS and Linux.

@kykosic
If you replace num: float = 20 with num: float = 20.0, it works.

Oh wow indeed it does. Do you know if there's any documentation that explains this behavior?

@kykosic
Unfortunately there is not documentation that explain this precisely. I will do it when I have time.