Open ghost opened 4 years ago
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.
When a dataclass contains a union of dataclasses it will always deserialise the field as the first dataclass listed in the union.
This can be fixed using the following patch:
Will submit a PR which fixes the issue and adds a test for this behaviour.