Skip to content

Commit

Permalink
fix: deserialization of unions if the type of a field with the same n…
Browse files Browse the repository at this point in the history
…ame differs between union members (#511)
  • Loading branch information
TristanSpeakEasy authored Feb 1, 2024
1 parent c26c3b9 commit 8512afc
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!"

6 comments on commit 8512afc

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage

Coverage Report
FileStmtsMissCoverMissing
dataclasses_json
   cfg.py51492%80, 84–86
   core.py2601893%39–42, 52, 65, 67, 82, 84, 170, 198, 378–385, 389, 395
   mm.py2053085%33–36, 42–45, 53–56, 62–65, 88, 170–171, 176, 180, 184, 189, 193, 197, 205, 211, 216, 225, 230, 235, 244, 253–260
   stringcase.py25388%59, 76, 97
   undefined.py146299%25, 39
   utils.py1313673%12–25, 45–50, 61–65, 75, 100–101, 109–110, 125–133, 163, 182, 207
tests
   entities.py239399%22, 234, 240
   test_annotations.py814248%50–67, 78–102, 106–122
   test_api.py142497%88, 99, 139–140
   test_str_subclass.py22195%9
   test_union.py1531093%99–106, 120–127
TOTAL268215394% 

Tests Skipped Failures Errors Time
307 3 💤 0 ❌ 0 🔥 2.749s ⏱️

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage

Coverage Report
FileStmtsMissCoverMissing
dataclasses_json
   cfg.py51492%80, 84–86
   core.py2601893%39–42, 52, 65, 67, 82, 84, 170, 198, 378–385, 389, 395
   mm.py2053085%33–36, 42–45, 53–56, 62–65, 88, 170–171, 176, 180, 184, 189, 193, 197, 205, 211, 216, 225, 230, 235, 244, 253–260
   stringcase.py25388%59, 76, 97
   undefined.py146299%25, 39
   utils.py1313673%12–25, 45–50, 61–65, 75, 100–101, 109–110, 125–133, 163, 182, 207
tests
   entities.py239399%22, 234, 240
   test_annotations.py814248%50–67, 78–102, 106–122
   test_api.py142497%88, 99, 139–140
   test_str_subclass.py22195%9
   test_union.py1531093%99–106, 120–127
TOTAL268215394% 

Tests Skipped Failures Errors Time
307 3 💤 0 ❌ 0 🔥 2.815s ⏱️

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage

Coverage Report
FileStmtsMissCoverMissing
dataclasses_json
   cfg.py51492%80, 84–86
   core.py2591793%39–42, 52, 65, 67, 82, 84, 170, 378–385, 389, 395
   mm.py2042986%33–36, 42–45, 53–56, 62–65, 88, 170–171, 176, 180, 184, 189, 193, 197, 205, 211, 216, 225, 230, 235, 253–260
   stringcase.py25388%59, 76, 97
   undefined.py146299%25, 39
   utils.py1312978%12–25, 45–50, 61–65, 75, 100–101, 109–110, 163, 182, 207
tests
   entities.py239399%20, 234, 240
   test_annotations.py814248%50–67, 78–102, 106–122
   test_api.py142299%139–140
   test_str_subclass.py22195%9
TOTAL268013295% 

Tests Skipped Failures Errors Time
307 1 💤 0 ❌ 0 🔥 2.746s ⏱️

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage

Coverage Report
FileStmtsMissCoverMissing
dataclasses_json
   cfg.py51492%80, 84–86
   core.py2591793%39–42, 52, 65, 67, 82, 84, 170, 378–385, 389, 395
   mm.py2042986%33–36, 42–45, 53–56, 62–65, 88, 170–171, 176, 180, 184, 189, 193, 197, 205, 211, 216, 225, 230, 235, 253–260
   stringcase.py25388%59, 76, 97
   undefined.py146299%25, 39
   utils.py1312978%12–25, 45–50, 61–65, 75, 100–101, 109–110, 163, 182, 207
tests
   entities.py239399%22, 234, 240
   test_annotations.py814248%50–67, 78–102, 106–122
   test_api.py142199%139
   test_str_subclass.py22195%9
TOTAL268013195% 

Tests Skipped Failures Errors Time
307 1 💤 0 ❌ 0 🔥 2.880s ⏱️

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage

Coverage Report
FileStmtsMissCoverMissing
dataclasses_json
   cfg.py51492%80, 84–86
   core.py2601793%39–42, 52, 65, 67, 82, 84, 170, 378–385, 389, 395
   mm.py2042986%33–36, 42–45, 53–56, 62–65, 88, 170–171, 176, 180, 184, 189, 193, 197, 205, 211, 216, 225, 230, 235, 253–260
   stringcase.py25388%59, 76, 97
   undefined.py144299%25, 39
   utils.py1312978%12–25, 45–50, 61–65, 75, 100–101, 109–110, 163, 182, 207
tests
   entities.py218399%20, 234, 240
   test_annotations.py804248%50–67, 78–102, 106–122
   test_api.py140299%139–140
   test_str_subclass.py22195%9
TOTAL255413295% 

Tests Skipped Failures Errors Time
307 1 💤 0 ❌ 0 🔥 2.638s ⏱️

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage

Coverage Report
FileStmtsMissCoverMissing
dataclasses_json
   cfg.py51492%80, 84–86
   core.py2601893%39–42, 52, 65, 67, 82, 84, 170, 198, 378–385, 389, 395
   mm.py2053085%33–36, 42–45, 53–56, 62–65, 88, 170–171, 176, 180, 184, 189, 193, 197, 205, 211, 216, 225, 230, 235, 244, 253–260
   stringcase.py25388%59, 76, 97
   undefined.py146299%25, 39
   utils.py1313673%12–25, 45–50, 61–65, 75, 100–101, 109–110, 125–133, 163, 182, 207
tests
   entities.py239399%22, 234, 240
   test_annotations.py814248%50–67, 78–102, 106–122
   test_api.py142497%88, 99, 139–140
   test_str_subclass.py22195%9
   test_union.py1531093%99–106, 120–127
TOTAL268215394% 

Tests Skipped Failures Errors Time
307 3 💤 0 ❌ 0 🔥 4.417s ⏱️

Please sign in to comment.