Skip to content
This repository has been archived by the owner on Aug 19, 2023. It is now read-only.

Unions of dataclasses always deserialise as the first dataclass #118

Open
ghost opened this issue Nov 26, 2019 · 0 comments
Open

Unions of dataclasses always deserialise as the first dataclass #118

ghost opened this issue Nov 26, 2019 · 0 comments

Comments

@ghost
Copy link

ghost commented Nov 26, 2019

When a dataclass contains a union of dataclasses it will always deserialise the field as the first dataclass listed in the union.

>>> from dataclasses import dataclass
>>> from typing import Union
>>>
>>> from dataclasses_jsonschema import JsonSchemaMixin
>>>
>>>
>>> @dataclass
... class A(JsonSchemaMixin):
...     a: str
...
>>>
>>> @dataclass
... class B(JsonSchemaMixin):
...     b: str
...
>>>
>>> @dataclass
... class C(JsonSchemaMixin):
...     c: Union[A, B]
...
>>> a_variant = C(A("a"))
>>> b_variant = C(B("a"))
>>> print(C.from_json(a_variant.to_json()))
C(c=A(a='a'))
>>> print(C.from_json(b_variant.to_json()))
C(c=A(a=None))

This can be fixed using the following patch:

diff --git a/dataclasses_jsonschema/__init__.py b/dataclasses_jsonschema/__init__.py
index 58fe500..3d46fc2 100644
--- a/dataclasses_jsonschema/__init__.py
+++ b/dataclasses_jsonschema/__init__.py
@@ -398,7 +398,7 @@ class JsonSchemaMixin:
             # Replace any nested dictionaries with their targets
             field_type_name = cls._get_field_type_name(field_type)
             if cls._is_json_schema_subclass(field_type):
-                def decoder(_, ft, val): return ft.from_dict(val, validate=False)
+                def decoder(_, ft, val): return ft.from_dict(val)
             elif is_nullable(field_type):
                 def decoder(f, ft, val): return cls._decode_field(f, unwrap_nullable(ft), val)
             elif is_optional(field_type):
@@ -412,7 +412,7 @@ class JsonSchemaMixin:
                     try:
                         decoded = cls._decode_field(field, variant, value)
                         break
-                    except (AttributeError, TypeError, ValueError):
+                    except (AttributeError, TypeError, ValueError, ValidationError):
                         continue
                 if decoded is not None:
                     return decoded

Will submit a PR which fixes the issue and adds a test for this behaviour.

@ghost ghost mentioned this issue Nov 26, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

0 participants