Skip to content

Commit

Permalink
Fix AttributeError when using generic SerializableType subclass
Browse files Browse the repository at this point in the history
When using PEP 695 syntax to create a generic class, some
private attributes are set up by the runtime in __init_subclass__().
Those attributes are needed when specializing the generic class.

SerializableType did not call super().__init_subclass__() and
thus those attributes were missing, leading to an AttributeError.
  • Loading branch information
Feuermurmel committed Jan 7, 2025
1 parent 9df4c59 commit 761579d
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 0 deletions.
2 changes: 2 additions & 0 deletions mashumaro/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def __init_subclass__(
] = Sentinel.MISSING,
**kwargs: Any,
):
super().__init_subclass__(**kwargs)
if use_annotations is not Sentinel.MISSING:
cls.__use_annotations__ = use_annotations

Expand Down Expand Up @@ -61,6 +62,7 @@ def __init_subclass__(
] = Sentinel.MISSING,
**kwargs: Any,
):
super().__init_subclass__(**kwargs)
if use_annotations is not Sentinel.MISSING:
cls.__use_annotations__ = use_annotations

Expand Down
21 changes: 21 additions & 0 deletions tests/test_generics_pep_695.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from mashumaro import DataClassDictMixin
from mashumaro.mixins.json import DataClassJSONMixin
from mashumaro.types import SerializableType
from tests.entities import MyGenericDataClass, SerializableTypeGenericList


Expand All @@ -18,6 +19,18 @@ class Bar(Foo):
pass


@dataclass
class GenericSerializableType[T](SerializableType):
value: object

def _serialize(self):
return self.value

@classmethod
def _deserialize(cls, value):
return cls(value)


def test_one_generic():
@dataclass
class A[T]:
Expand Down Expand Up @@ -238,3 +251,11 @@ def test_self_referenced_generic_no_max_recursion_error():
assert Bar.from_dict({"x": 42, "y": {"x": 33, "y": None}}) == obj
assert obj.to_json() == '{"x": 42, "y": {"x": 33, "y": null}}'
assert Bar.from_json('{"x": 42, "y": {"x": 33, "y": null}}') == obj


# Regression test for https://github.com/Fatal1ty/mashumaro/issues/274.
def test_generic_serializable_type_getitem():
@dataclass
class DataClass(DataClassDictMixin):
# Simply specializing the type would lead to an AttributeError.
x: GenericSerializableType[int]

0 comments on commit 761579d

Please sign in to comment.