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

[BUG] Extending de/encoders do not work with from __future__ import annotations #547

Open
orilg opened this issue Sep 29, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@orilg
Copy link

orilg commented Sep 29, 2024

Description

Writing my own class to be used as a dataclass field, I extend the json encoder / decoder with dataclasses_json.cfg.global_config.encoders/decoders.
When adding from __future__ import annotations the type turns to str and the encoder / decoder I've added to cfg does not automatically detect it as that type.

workaround : adding the same encoder/decoder to cfg with key cls.name in addition to cls

Code snippet that reproduces the issue

from __future__ import annotations
from typing import Any
from dataclasses import dataclass
from dataclasses_json import DataClassJsonMixin, cfg


class MyNestedClass:
    def __init__(self, my_str: str, my_int: int =1) -> None:
        self._my_str = my_str
        self._my_int = my_int

    def __eq__(self, other: Any) -> bool:
        if not isinstance(other, MyNestedClass):
            return False
        return (self._my_str, self._my_int) == (other._my_str, self._my_int)

    def to_dict(self) -> dict[str,str]:
        return {"my_str" : self._my_str}

    @classmethod
    def from_dict(cls, asdict:dict[str,str]) -> "MyNestedClass":
        return MyNestedClass(my_str=asdict['my_str'])

cfg.global_config.encoders[MyNestedClass] = MyNestedClass.to_dict
cfg.global_config.decoders[MyNestedClass] = MyNestedClass.from_dict

@dataclass
class MyClass(DataClassJsonMixin):
    my_nested_inst: MyNestedClass

class_with_nested = MyClass(MyNestedClass('asdf'))
print(f"class_with_nested : {class_with_nested}")
print(f"MyClass.from_json(class_with_nested.to_json()) : {MyClass.from_json(class_with_nested.to_json())}")
assert class_with_nested ==  MyClass.from_json(class_with_nested.to_json())

This is what I get

class_with_nested : MyClass(my_nested_inst=<__main__.MyNestedClass object at 0x7982297b8810>)
MyClass.from_json(class_with_nested.to_json()) : MyClass(my_nested_inst={'my_str': 'asdf'})
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
Cell In[1], line 33
     31 print(f"class_with_nested : {class_with_nested}")
     32 print(f"MyClass.from_json(class_with_nested.to_json()) : {MyClass.from_json(class_with_nested.to_json())}")
---> 33 assert class_with_nested ==  MyClass.from_json(class_with_nested.to_json())

AssertionError:

Describe the results you expected

class_with_nested : MyClass(my_nested_inst=<__main__.MyNestedClass object at 0x7982297b8810>)

MyClass.from_json(class_with_nested.to_json()) : MyClass(my_nested_inst==<__main__.MyNestedClass object at 0xXXXXX>)

# No assertion : class_with_nested ==  MyClass.from_json(class_with_nested.to_json()) is True

Python version you are using

3.11.4

Environment description

asttokens==2.4.1
dataclasses-json==0.6.7
decorator==5.1.1
executing==2.1.0
ipython==8.27.0
jedi==0.19.1
marshmallow==3.22.0
matplotlib-inline==0.1.7
mypy-extensions==1.0.0
packaging==24.1
parso==0.8.4
pexpect==4.9.0
prompt_toolkit==3.0.48
ptyprocess==0.7.0
pure_eval==0.2.3
Pygments==2.18.0
six==1.16.0
stack-data==0.6.3
traitlets==5.14.3
typing-inspect==0.9.0
typing_extensions==4.12.2
wcwidth==0.2.13
@orilg orilg added the bug Something isn't working label Sep 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant