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

to_dict/to_json not working with postponed annotations for Generic dataclass, if typed class is defined in different module #90

Closed
AntonOvsyannikov opened this issue Dec 13, 2022 · 6 comments
Labels
bug Something isn't working

Comments

@AntonOvsyannikov
Copy link

  • mashumaro version: 3.1
  • Python version: 3.11
  • Operating System: Win11

Description

In all my modules I am using postponed annotations.

from __future__ import annotations

I define dataclass, inherited from Generic[T], where typevar is defined in same module. Than I derive some typed class and try to call to_dict(). If both classes are in same module enerything is ok. If typed class defined in different module I got UnresolvedTypeReferenceError

What I Did

m1.py

from __future__ import annotations  # w/o is ok
from dataclasses import dataclass
from typing import TypeVar, Generic

from mashumaro.mixins.json import DataClassJSONMixin

T = TypeVar("T")


@dataclass
class Foo(Generic[T], DataClassJSONMixin):
    x: T


@dataclass
class Bar(Foo[int]):
    ...

m2.py

from __future__ import annotations

from dataclasses import dataclass
from typing import TypeVar

from m1 import Foo, Bar


# T = TypeVar("T") # if I uncomment this line, the error goes away


@dataclass
class Baz(Foo[int]):
    ...


print(Bar(x=1).to_json())  # ok
print(Baz(x=1).to_json())  # mashumaro.exceptions.UnresolvedTypeReferenceError: Class Baz has unresolved type reference T in some of its fields
@AntonOvsyannikov AntonOvsyannikov changed the title to_dict not working with postponed annotations for Generic dataclass, if class is defined in different module to_dict/to_json not working with postponed annotations for Generic dataclass, if class is defined in different module Dec 13, 2022
@AntonOvsyannikov AntonOvsyannikov changed the title to_dict/to_json not working with postponed annotations for Generic dataclass, if class is defined in different module to_dict/to_json not working with postponed annotations for Generic dataclass, if typed class is defined in different module Dec 13, 2022
@Fatal1ty
Copy link
Owner

Hi @AntonOvsyannikov

Thank you for the illustrative example. In my production code I don't use postponed annotations, that's why this problem hadn't been discovered before you did :)

This bug seems to be caused by explicit passing globals of the Baz's module to typing.get_type_hints here. Without it typing.get_type_hints would get globals of the base class, in our example Foo, here. At first glance the fix is straightforward, but I have to think about this more carefully just so as not to break something else.

@Fatal1ty Fatal1ty added the bug Something isn't working label Dec 13, 2022
@Fatal1ty
Copy link
Owner

Hi @AntonOvsyannikov

I came to conclusion to remove explicit globals and locals passing to typing.get_type_hints that will definitely solve this issue. All the tests are passing and it seems not to break something. Anyway, it would be nice if you check this branch before going to release.

@mishamsk
Copy link
Contributor

mishamsk commented Jan 5, 2023

@Fatal1ty we are working with @AntonOvsyannikov on the same thing, so let me chime in here. I can confirm that the fix works for the sample code and probably in our real life code, however I stumbled on a new bug and can't fully test. See this #91

@Fatal1ty
Copy link
Owner

Fatal1ty commented Jan 9, 2023

Merged and will be available in an upcoming release.

@mishamsk
Copy link
Contributor

mishamsk commented Jan 9, 2023

@Fatal1ty thanks a lot!

@Fatal1ty
Copy link
Owner

Fixed in 3.3.1.

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

3 participants