Skip to content

Commit 0282736

Browse files
authored
Merge pull request #302 from Fatal1ty/fix-union-short-path-for-collections
Don't add short path for collections in Union with no_copy option
2 parents ca7367d + 54276fa commit 0282736

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

mashumaro/core/meta/types/pack.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,9 @@ def pack_union(
329329
spec.copy(type=type_arg, expression="value", owner=spec.type)
330330
)
331331
if packer not in packers:
332-
if packer == "value":
332+
if packer == "value" and not issubclass(
333+
get_type_origin(type_arg), Collection
334+
):
333335
packers.insert(0, packer)
334336
else:
335337
packers.append(packer)
@@ -356,7 +358,9 @@ def pack_union(
356358
)
357359
else:
358360
packer_arg_type_check = f"is {packer_arg_type_names[0]}"
359-
if packer == "value":
361+
if packer == "value" and not issubclass(
362+
packer_arg_type, Collection
363+
):
360364
with lines.indent(
361365
f"if value.__class__ {packer_arg_type_check}:"
362366
):

tests/test_union.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55

66
import pytest
77

8-
from mashumaro import DataClassDictMixin
8+
from mashumaro import DataClassDictMixin, pass_through
99
from mashumaro.codecs.basic import encode
10+
from mashumaro.config import BaseConfig
11+
from mashumaro.dialect import Dialect
1012
from tests.utils import same_types
1113

1214

@@ -139,3 +141,27 @@ def test_union_encoding():
139141
encoded = encode(value, Union[variants])
140142
assert value == encoded
141143
assert same_types(value, encoded)
144+
145+
146+
def test_union_no_copy_list_with_dataclass_items_or_passed_through_items():
147+
class NoCopyListDialect(Dialect):
148+
no_copy_collections = (list,)
149+
150+
@dataclass
151+
class Item(DataClassDictMixin):
152+
value: int
153+
154+
@dataclass
155+
class Container(DataClassDictMixin):
156+
items: Union[list[Item], list[str]]
157+
158+
class Config(BaseConfig):
159+
dialect = NoCopyListDialect
160+
serialization_strategy = {str: {"serialize": lambda x: str(x)}}
161+
162+
item1 = Item(1)
163+
item2 = Item(2)
164+
items = [item1, item2]
165+
container = Container(items=items)
166+
data = container.to_dict()
167+
assert data == {"items": [{"value": 1}, {"value": 2}]}

0 commit comments

Comments
 (0)