Skip to content

Commit

Permalink
fix: fix deserialization of unions if the type of a field with the sa…
Browse files Browse the repository at this point in the history
…me name differs between union members
  • Loading branch information
TristanSpeakEasy committed Jan 30, 2024
1 parent c26c3b9 commit a44c89c
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
2 changes: 1 addition & 1 deletion dataclasses_json/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ def _decode_generic(type_, value, infer_missing):
try:
res = _decode_dataclass(type_option, value, infer_missing)
break
except (KeyError, ValueError):
except (KeyError, ValueError, AttributeError):
continue
if res == value:
warnings.warn(
Expand Down
38 changes: 37 additions & 1 deletion tests/test_union.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ class Aux2:
class Aux3:
f2: str


@dataclass_json
@dataclass
class C4:
f1: Union[Aux1, Aux2]


@dataclass_json
@dataclass
class C12:
Expand Down Expand Up @@ -124,6 +126,31 @@ class C11:
"""
f1: Union[str, None] = None


@dataclass_json
@dataclass
class C13:
data: str


@dataclass_json
@dataclass
class C14:
content: str


@dataclass_json
@dataclass
class C15:
data: C13


@dataclass_json
@dataclass
class C16:
event: Union[C15, C13]


params = [
(C1(f1=12), {"f1": 12}, '{"f1": 12}'),
(C1(f1="str1"), {"f1": "str1"}, '{"f1": "str1"}'),
Expand Down Expand Up @@ -209,6 +236,7 @@ def test_deserialize_with_error(cls, data):
with pytest.raises(ValidationError):
assert s.load(data)


def test_deserialize_without_discriminator():
# determine based on type
json = '{"f1": {"f1": 1}}'
Expand Down Expand Up @@ -239,4 +267,12 @@ def test_deserialize_without_discriminator():
json = '{"f1": {"f3": "str2"}}'
s = C12.schema()
obj = s.loads(json)
assert type(obj.f1) == dict
assert type(obj.f1) == dict


def test_deserialize_with_mismatched_field_types():
json = '{"event": {"data": "Hello world!"} }'
s = C16.schema()
obj = s.loads(json)
assert obj.event is not None
assert obj.event.data == "Hello world!"

0 comments on commit a44c89c

Please sign in to comment.