Esempio n. 1
0
 def deserialization() -> Conversion:
     annotations: dict[str, Any] = {}
     deserialization_namespace: dict[str, Any] = {
         "__annotations__": annotations
     }
     for sub in rec_subclasses(cls):
         annotations[sub.__name__] = Tagged[sub]  # type: ignore
         # Add tagged fields for all its alternative constructors
         for constructor in _alternative_constructors.get(sub, ()):
             # Build the alias of the field
             alias = to_pascal_case(constructor.__name__)
             # object_deserialization uses get_type_hints, but the constructor
             # return type is stringified and the class not defined yet,
             # so it must be assigned manually
             constructor.__annotations__["return"] = sub
             # Add constructor tagged field with its conversion
             annotations[alias] = Tagged[sub]  # type: ignore
             deserialization_namespace[alias] = Tagged(
                 conversion(
                     # Use object_deserialization to wrap constructor as deserializer
                     deserialization=object_deserialization(
                         constructor, type_name(alias))))
     # Create the deserialization tagged union class
     deserialization_union = new_class(
         cls.__name__,
         (TaggedUnion, ),
         exec_body=lambda ns: ns.update(deserialization_namespace),
     )
     return Conversion(lambda obj: get_tagged(obj)[1],
                       source=deserialization_union,
                       target=cls)
Esempio n. 2
0
class Data2:
    data_field2: Field2 = field(
        metadata=flattened | conversion(Field2.from_field, Field2.to_field))