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

Custom Serializer doesn't work with top-level data. #514

Open
Jasha10 opened this issue Apr 18, 2024 · 0 comments
Open

Custom Serializer doesn't work with top-level data. #514

Jasha10 opened this issue Apr 18, 2024 · 0 comments
Labels
bug Bug report or fix

Comments

@Jasha10
Copy link

Jasha10 commented Apr 18, 2024

It seems that custom serializers don't work if the custom data type is at the top level.

For example, suppose I implement a custom serializer for MyClass, and I wrap MyClass inside a dataclass MyWrapper.

When I call serde.to_dict(MyWrapper(MyClass(...))), the custom serializer for MyClass works as expected.
When I call serde.to_dict(MyClass(...)), however, the custom serializer is not used.

This is unexpected; I would expect serde.to_dict(MyClass(...)) to invoke the custom serializer too.

In the below example, the second assertion fails.

# serde_partial.py

from plum import dispatch
import serde
from typing import Any
from dataclasses import dataclass


Type = type  # You should prefer to use type[...] instead of Type[...]!


class MyClass:
    def __init__(self, a, b):
        self.a = a
        self.b = b
    def __eq__(self, other):
        return self.a == other.a and self.b == other.b

class MySerializer:
    @dispatch
    def serialize(self, value: MyClass) -> dict[str, Any]:
        return {'a': value.a, 'b': value.b}

class MyDeserializer:
    @dispatch
    def deserialize(self, cls: Type[MyClass], value: dict[str, Any]) -> MyClass:
        return MyClass(value['a'], value['b'])


serde.add_serializer(MySerializer())
serde.add_deserializer(MyDeserializer())

@dataclass
class MyWrapper:
    value: MyClass

# When MyClass is wrapped inside a dataclass, to_dict and from_dict work correctly
obj = MyWrapper(MyClass(1, 2))
expected = {'value': {'a': 1, 'b': 2}}
result = serde.to_dict(obj)
assert isinstance(result, dict)
assert result == expected
assert serde.from_dict(MyWrapper, result) == obj

# When MyClass is not wrapped inside a dataclass, to_dict fails to serialize it
obj = MyClass(1, 2)
expected = {'a': 1, 'b': 2}
result = serde.to_dict(obj)
assert isinstance(result, dict), f"Expected dict, got {type(result)}"  # ASSERTION FAILS
$ python serde_partial.py
Traceback (most recent call last):
  File "/home/homestar/tmp/serde_partial.py", line 49, in <module>
    assert isinstance(result, dict), f"Expected dict, got {type(result)}"  # ASSERTION FAILS
AssertionError: Expected dict, got <class '__main__.MyClass'>
@yukinarit yukinarit added the bug Bug report or fix label Apr 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Bug report or fix
Projects
None yet
Development

No branches or pull requests

2 participants