From 761579de882c9c3880618903cd602b2487957aeb Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Tue, 7 Jan 2025 13:13:10 +0100 Subject: [PATCH] Fix AttributeError when using generic SerializableType subclass 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. --- mashumaro/types.py | 2 ++ tests/test_generics_pep_695.py | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/mashumaro/types.py b/mashumaro/types.py index 82c34caf..35091742 100644 --- a/mashumaro/types.py +++ b/mashumaro/types.py @@ -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 @@ -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 diff --git a/tests/test_generics_pep_695.py b/tests/test_generics_pep_695.py index 72ed7f89..31211b9f 100644 --- a/tests/test_generics_pep_695.py +++ b/tests/test_generics_pep_695.py @@ -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 @@ -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]: @@ -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]