Skip to content

Commit

Permalink
Fix RecursionError on annotated serialization strategy for a dataclas…
Browse files Browse the repository at this point in the history
…s field
  • Loading branch information
Fatal1ty committed Apr 28, 2024
1 parent c076075 commit b00f834
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 3 deletions.
13 changes: 13 additions & 0 deletions mashumaro/core/meta/types/pack.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,19 @@ def _pack_with_annotated_serialization_strategy(
)
overridden_fn = f"__{spec.field_ctx.name}_serialize_{random_hex()}"
setattr(spec.attrs, overridden_fn, strategy.serialize)
new_spec = spec.copy(
type=value_type,
expression=(
f"{spec.self_attrs_name}.{overridden_fn}({spec.expression})"
),
)
field_metadata = new_spec.field_ctx.metadata
if field_metadata.get("serialization_strategy") is strategy:
new_spec.field_ctx.metadata = {
k: v
for k, v in field_metadata.items()
if k != "serialization_strategy"
}
return PackerRegistry.get(
spec.copy(
type=value_type,
Expand Down
10 changes: 9 additions & 1 deletion mashumaro/core/meta/types/unpack.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,15 @@ def _unpack_with_annotated_serialization_strategy(
)
overridden_fn = f"__{spec.field_ctx.name}_deserialize_{random_hex()}"
setattr(spec.attrs, overridden_fn, strategy.deserialize)
unpacker = UnpackerRegistry.get(spec.copy(type=value_type))
new_spec = spec.copy(type=value_type)
field_metadata = new_spec.field_ctx.metadata
if field_metadata.get("serialization_strategy") is strategy:
new_spec.field_ctx.metadata = {
k: v
for k, v in field_metadata.items()
if k != "serialization_strategy"
}
unpacker = UnpackerRegistry.get(new_spec)
return f"{spec.cls_attrs_name}.{overridden_fn}({unpacker})"


Expand Down
32 changes: 30 additions & 2 deletions tests/test_serialization_strategy.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from dataclasses import dataclass
from dataclasses import dataclass, field
from datetime import date
from typing import Generic, List, Sequence, TypeVar

from mashumaro import DataClassDictMixin
from mashumaro import DataClassDictMixin, field_options
from mashumaro.types import SerializationStrategy

T = TypeVar("T")
Expand Down Expand Up @@ -153,3 +153,31 @@ class Config:
assert MyDataClass.from_dict(
{"x": ["2023-02-12", "2023-02-12", "2023-02-12", "2023-02-12"]}
) == MyDataClass(["2023-02-12", "2023-02-12", "2023-02-12"])


def test_date_list_field_serialization_strategy_with_use_annotations():
@dataclass
class MyDataClass(DataClassDictMixin):
x: List[date] = field(
metadata=field_options(
serialization_strategy=(
TruncatedAnnotatedDateListSerializationStrategy()
)
)
)

obj = MyDataClass(
[
date(2023, 2, 12),
date(2023, 2, 12),
date(2023, 2, 12),
date(2023, 2, 12),
date(2023, 2, 12),
]
)
assert obj.to_dict() == {
"x": ["2023-02-12", "2023-02-12", "2023-02-12", "2023-02-12"]
}
assert MyDataClass.from_dict(
{"x": ["2023-02-12", "2023-02-12", "2023-02-12", "2023-02-12"]}
) == MyDataClass([date(2023, 2, 12), date(2023, 2, 12), date(2023, 2, 12)])

0 comments on commit b00f834

Please sign in to comment.