Class Hooks¶
To add support for e.g. complex we register class hooks using register_class_serialization_hook and register_class_deserialization_hook.
# Example 7:
from parityos_serialization.serializer import (
DeterministicJsonSerializer,
Serializer,
)
from parityos_serialization.utils.class_tagger import NameClassTagger
from parityos_serialization.utils.typedefs import (
TypedDataDict,
)
# serialization hook
def serialize_complex(
x: complex, _serializer: Serializer[TypedDataDict, NameClassTagger]
) -> dict[str, float]:
return {"real": x.real, "imag": x.imag}
# deserialization hook
def deserialize_complex(
data: dict[str, float],
_: type[complex],
_serializer: Serializer[TypedDataDict, NameClassTagger],
) -> complex:
return complex(data["real"], data["imag"])
serializer = DeterministicJsonSerializer()
serializer.register_class_serialization_hook(complex, serialize_complex)
serializer.register_class_deserialization_hook(complex, deserialize_complex)
serializer.class_tagger.register_classes(complex)
obj = complex(4, 2)
dct = serializer.serialize(obj)
obj2 = serializer.deserialize(dct)
assert obj == obj2
print(dct)
# {'_data': {'real': 4.0, 'imag': 2.0}, '_cls': 'complex'}
Here we have registered hooks that are used for all objects of type complex.
A class serialization hook is a function that takes an object of the registered class T and a serializer of class S and returns the serialized data.
This structure is formalized in the SerializeHook type alias. The class tag will be injected by the serializer automatically, so the hook does not need to do this.
A class deserialization hook is a function that takes the serialized data, the target class type[T] and a serializer of type S and returns an object of type T constructed from the serialized data. This structure is formalized in the DeserializeHook type alias. The unpacking of the class tag is done by the serializer automatically and the deserialization hook will receive already unpacked serialized data and the target class type[T].
Registering a class hook for a class that already has a hook registered overwrites the old hook.
Class hook resolution uses singledispatch’s resolution method based on the object’s mro. For a mechanism to register hooks more broadly across many classes, see Predicate Hooks.