Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions mashumaro/core/meta/types/pack.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,12 @@ def pack_any(spec: ValueSpec) -> Expression | None:
return spec.expression


def _resolve_type_alias_type(t: type) -> type:
while is_type_alias_type(t):
t = t.__value__ # type: ignore[attr-defined]
return t


def pack_union(
spec: ValueSpec, args: tuple[type, ...], prefix: str = "union"
) -> Expression:
Expand Down Expand Up @@ -330,7 +336,7 @@ def pack_union(
)
if packer not in packers:
if packer == "value" and not issubclass(
get_type_origin(type_arg), Collection
get_type_origin(_resolve_type_alias_type(type_arg)), Collection
):
packers.insert(0, packer)
else:
Expand All @@ -344,6 +350,7 @@ def pack_union(
for packer in packers:
packer_arg_type_names = []
for packer_arg_type in packer_arg_types[packer]:
packer_arg_type = _resolve_type_alias_type(packer_arg_type)
if is_generic(packer_arg_type):
packer_arg_type = get_type_origin(packer_arg_type)
packer_arg_type_name = clean_id(type_name(packer_arg_type))
Expand All @@ -359,7 +366,7 @@ def pack_union(
else:
packer_arg_type_check = f"is {packer_arg_type_names[0]}"
if packer == "value" and not issubclass(
packer_arg_type, Collection
_resolve_type_alias_type(packer_arg_type), Collection
):
with lines.indent(
f"if value.__class__ {packer_arg_type_check}:"
Expand Down
11 changes: 11 additions & 0 deletions tests/test_pep_695.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
GenericPassthroughSerializable,
)

type ScalarAlias = int


def test_type_alias_type_with_dataclass_dict_mixin():
type MyDate = date
Expand All @@ -39,6 +41,15 @@ def test_type_alias_type_with_codecs():
assert encoder.encode(obj) == "2024-04-15"


def test_type_alias_type_with_union_value_packer():
@dataclass
class MyClass(DataClassDictMixin):
x: ScalarAlias | list[int]

assert MyClass(1).to_dict() == {"x": 1}
assert MyClass([1, 2]).to_dict() == {"x": [1, 2]}


@pytest.mark.parametrize("deferred_ann", [False, True])
def test_pep695_generic_serialization_strategy(deferred_ann):
if deferred_ann:
Expand Down
Loading