serializer

Serializer that handles (de)serialization of arbitrary nested objects, using built-in or custom strategies through registered hooks for different classes.

parityos_serialization.serializer.serialize_raise(obj: Any, _serializer: Serializer[TypedDataT, ClassTaggerT]) Any

Catch-all hook that raises for any object.

parityos_serialization.serializer.serialize_pass_through(obj: T, _serializer: Serializer[TypedDataT, ClassTaggerT]) T

Catch-all hook that just passes through anything it gets unaltered.

parityos_serialization.serializer.serialize_type(cls: type, serializer: Serializer[TypedDataT, ClassTaggerT]) str

Serialize a type by its class tags from the serializer’s ClassTagger.

parityos_serialization.serializer.serialize_generic_alias(alias: GenericAlias, serializer: Serializer[TypedDataT, ClassTaggerT]) GenericAliasDict

Serialize a GenericAlias as a dict containing its origin and args.

parityos_serialization.serializer.serialize_set_deterministic(obj: Set[SupportsLT], serializer: Serializer[TypedDataT, ClassTaggerT]) list[Any]

Serialize a set as sorted list of serialized elements.

The elements of the set must be sortable.

parityos_serialization.serializer.serialize_iterable(obj: Iterable[Any], serializer: Serializer[TypedDataT, ClassTaggerT]) list[Any]

Serialize any iterable as a list of serialized elements.

parityos_serialization.serializer.serialize_mapping(obj: Mapping[Any, Any], serializer: Serializer[TypedDataT, ClassTaggerT]) list[list[Any]]

Serialize a mapping safely as list of (key, value) pairs, which doesn’t require serialized keys to be hashable.

parityos_serialization.serializer.serialize_mapping_deterministic(obj: Mapping[SupportsLT, SupportsLT], serializer: Serializer[TypedDataT, ClassTaggerT]) list[list[Any]]

Like serialize_mapping but deterministic by sorting (key, value) pairs. This requires mappings of sortable keys and values as input.

parityos_serialization.serializer.serialize_mapping_hashable_keys(obj: Mapping[Any, Any], serializer: Serializer[TypedDataT, ClassTaggerT]) dict[Any, Any]

Serialize a mapping to a dict of serialized keys to serialized values, assuming serialized keys are hashable.

parityos_serialization.serializer.serialize_enum(obj: Enum, _serializer: Serializer[TypedDataT, ClassTaggerT]) str

Serialize an enum object by its name.

parityos_serialization.serializer.serialize_attrs(obj: AttrsInstance, serializer: Serializer[TypedDataT, ClassTaggerT]) dict[str, Any]

Serialize an attrs class as dict of field name to its serialized value.

parityos_serialization.serializer.serialize_dataclass(obj: DataclassInstance, serializer: Serializer[TypedDataT, ClassTaggerT]) dict[str, Any]

Serialize a dataclass class as dict of field name to its serialized value.

parityos_serialization.serializer.serialize_from_pickle_interface(obj: object, serializer: Serializer[TypedDataT, ClassTaggerT]) Any

Serialize an object by using the pickle interface __getstate__.

If the object uses the default object.__getstate__ implementation, combine __dict__ and __slots__ entries into a single dict[str, Any].

parityos_serialization.serializer.deserialize_raise(_data: Any, cls: type[Any], _serializer: Serializer[TypedDataT, ClassTaggerT]) Any

Catch-all hook that raises for any object.

parityos_serialization.serializer.deserialize_pass_through(data: T, _cls: type[T], _serializer: Serializer[TypedDataT, ClassTaggerT]) T

Catch-all hook that just passes through anything it gets unaltered.

parityos_serialization.serializer.deserialize_type(data: str, _: type, serializer: Serializer[TypedDataT, ClassTaggerT]) type | Any

Deserialize a type from its class tag from the serializer’s ClassTagger.

parityos_serialization.serializer.deserialize_generic_alias(data: GenericAliasDict, _: type, serializer: Serializer[TypedDataT, ClassTaggerT])

Deserialize a GenericAlias from a dict containing its origin and args.

parityos_serialization.serializer.deserialize_sequence(data: Iterable[Any], cls: Callable[[Iterable[Any]], SequenceT], serializer: Serializer[TypedDataT, ClassTaggerT]) SequenceT

Deserialize a sequence from an iterable by constructing it from an iterable of its deserialized elements.

parityos_serialization.serializer.deserialize_mapping(obj: Iterable[list[Any]] | Mapping[Any, Any], cls: Callable[[dict[KT, VT]], MappingT], serializer: Serializer[TypedDataT, ClassTaggerT]) MappingT

Deserialize a mapping from either a list of serialized (key, value) pairs or a mapping from serialized keys to serialized values.

parityos_serialization.serializer.deserialize_enum(obj: str, cls: type[EnumT], _serializer: Serializer[TypedDataT, ClassTaggerT]) EnumT

Deserialize an enum object from its name.

parityos_serialization.serializer.deserialize_class_from_keywords(data: Mapping[str, Any], cls: type[T], keywords: Set[str], serializer: Serializer[TypedDataT, ClassTaggerT]) T

Deserialize a class from its dict representation by passing a dict of attribute name to deserialized value as **kwargs to its constructor.

This hook can be used for any class which can be constructed by just passing its fields, like e.g. dataclasses or attrs classes.

Parameters:
  • data – A mapping of field name to serialized values.

  • cls – The class of the object to be constructed from the serialized data.

  • keywords – The expected keywords that cls’s constructor accepts

  • serializer – Serializer for deserializing the serialized values in data.

Returns:

An instance of cls constructed from deserialized data as kwargs.

Raises:

DataError – If cls can’t be constructed from the passed deserialized data.

parityos_serialization.serializer.deserialize_attrs_class(data: dict[str, Any], cls: type[AttrsT], serializer: Serializer[TypedDataT, ClassTaggerT]) AttrsT

Deserialize an attrs class from its name to serialized value representation by deserializing the values and filtering out fields that don’t appear in cls.__init__.

parityos_serialization.serializer.deserialize_dataclass(data: dict[str, Any], cls: type[DataClassT], serializer: Serializer[TypedDataT, ClassTaggerT]) DataClassT

Deserialize a dataclass from its name to serialized value representation by deserializing the values and filtering out fields that don’t appear in cls.__init__.

parityos_serialization.serializer.deserialize_from_pickle_interface(data: Any, cls: type[T], serializer: Serializer[TypedDataT, ClassTaggerT]) T

Deserialize a class by using the pickle interface __setstate__.

If cls has a custom __setstate__, data can be anything that is compatible with this custom method in its deserialized form.

Otherwise, data is assumed to come from the default object.__getstate__ implementation with __dict__ and __slots__ entries combined into a single dict[str, Any].

class parityos_serialization.serializer.HookPair(serialize_hook: SerializeHook[T, TypedDataT, ClassTaggerT], deserialize_hook: DeserializeHook[T, TypedDataT, ClassTaggerT])

Bases: Generic[T, TypedDataT, ClassTaggerT]

Class holding a pair of matching deserialization and serialization hooks.

This class is e.g. used to initialize a Serializer with a custom fallback strategy.

class parityos_serialization.serializer.FallBackStrategy(value)

Bases: Enum

Enum class representing different strategies to deal with objects that are not caught by any serialization or deserialization hooks.

RAISE = HookPair(serialize_hook=<function serialize_raise>, deserialize_hook=<function deserialize_raise>)

raise an error for objects that are not covered otherwise.

PASS_THROUGH = HookPair(serialize_hook=<function serialize_pass_through>, deserialize_hook=<function deserialize_pass_through>)

treat uncaught objects as pass-through classes.

PICKLE_INTERFACE = HookPair(serialize_hook=<function serialize_from_pickle_interface>, deserialize_hook=<function deserialize_from_pickle_interface>)

use catch-all hooks utilizing the pickle interface

class parityos_serialization.serializer.Serializer(typed_data_converter: TypedDataConverter[TypedDataT], class_tagger: ClassTaggerT, pass_through_classes: Iterable[type], fallback_strategy: FallBackStrategy | HookPair[Any, TypedDataT, ClassTaggerT])

Bases: Generic[TypedDataT, ClassTaggerT]

Serializer that handles (de)serialization of built-in and custom class objects.

This class is not preconfigured and contains no hooks for (de)serializing any data types.

To register classes that are serialized by being passed though unaltered, pass them as pass_through_classes at initialization.

To register custom hooks for (de)serializing objects of certain types, use register_class_serialization_hook and register_class_deserialization_hook.

To register custom hooks for (de)serializing objects that fulfill certain predicates, use register_predicate_serialization_hook and register_predicate_deserialization_hook.

To define a strategy for dealing with objects that are neither pass-through classes nor caught by any hooks by passing either a variant of FallBackStrategy or a custom matching pair of catch-all serialization and deserialization hooks in form of a HookPair to fallback_strategy.

This class assumes no defaults.

Parameters:
  • typed_data_converter – Data converter that combines and extracts serialized data and type information in form of a class tag.

  • class_tagger – Class tagger object that manages mapping between classes and their class tags.

  • pass_through_classes – Classes for which objects are serialized by being returned unaltered.

  • fallback_strategy – Strategy for dealing with objects that are not caught by any hooks. Can be a preconfigured strategy from the FallBackStrategy enum or a custom HookPair.

property typed_data_converter: TypedDataConverter[TypedDataT]

This attribute can be set with the typed_data_converter parameter at initialization.

Returns:

This Serializer’s TypedDataConverter.

property class_tagger: ClassTaggerT

This attribute can be set with the class_tagger parameter at initialization.

Returns:

This Serializer’s ClassTagger.

property pass_through_classes: frozenset[type]

This attribute can be set with the pass_through_classes parameter at initialization.

Returns:

This serializer’s pass-through classes.

register_pass_through_class(cls: type)

Register a pass-through class.

Pass-through classes are classes for which instances get serialized and deserialized by passing them through unaltered. If this serializer already has hooks registered for cls they become irrelevant.

Parameters:

cls – Class to be registered as pass-through class.

deregister_pass_through_class(cls: type)

Deregister pass-through class.

Pass-through classes are classes for which instances get serialized and deserialized by passing them through unaltered.

Be sure to register hooks or a fallback strategy that deal with instances of cls appropriately after calling this method.

Parameters:

cls – Class to be deregistered as pass-through class.

serialize(obj: Any) Any

Central method for serializing objects with this Serializer.

Objects are serialized in the following order of preference, where cls is the class returned from self.class_tagger.get_class_from_object.

  1. If obj’s class is one of this Serializer’s pass_through_classes, the object is

    returned unaltered.

  2. If obj’s class or any of its base classes has a class serialization hook registered

    for it, the corresponding serialization hook is used.

  3. If any of the registered serialization predicates evaluate to True on obj, its

    corresponding serialization hook is used. Predicate-Hook pairs are evaluated in reverse, i.e. most recently registered predicates are evaluated first.

  4. If none of the above apply, the selected fallback strategy is applied.

Any serialized data coming from 2. or 3. gets class information injected in form of a class tag by using self.typed_data_converter.inject_class_tag, if the type of the serialized data is different from obj’s original type.

Parameters:

obj – Object to be serialized.

Returns:

Serialized data of obj, possibly together with a class tag.

register_class_serialization_hook(cls: type[T], serialize_fun: Callable[[T, Serializer[TypedDataT, ClassTaggerT]], Any])

Register a custom serialization function for class cls.

Hint

Make sure to also register a corresponding deserialization hook using register_class_deserialization_hook or manage deserialization of this type otherwise.

Parameters:
  • cls – The class for which to use serialize_fun.

  • serialize_funSerializeHook for serializing objects of type cls. Must take an object of type T and a serializer and return its serialized representation. The additional serializer can be used to for serializing elements of nested data types. It must be configured with the same TypedDataConverter and ClassTagger type as self for consistency.

register_predicate_serialization_hook(predicate: Callable[[T], bool], serialize_fun: Callable[[T, Serializer[TypedDataT, ClassTaggerT]], Any])

Register a custom serialization function for objects that fulfill a predicate.

In contrast to register_class_serialization_hook this method allows to register serialization hooks that get triggered by inspecting the object itself rather than its class or base classes.

The registered serialize_fun gets triggered whenever predicate evaluates to True on an object.

Hint

Make sure to also register appropriate hooks for deserializing objects covered by the registered predicate-hook pair.

Parameters:

Examples

It is possible to register a hook for all objects that have an attribute of a certain name my_attr with the following

>>> serializer.register_predicate_serialization_hook(
>>>     lambda obj: hasattr(obj, "my_attr"), serialize_fun
>>> )
serialize_object(obj: Any, serializer: Serializer[TypedDataT, ClassTaggerT]) Any

Catch-all serialization hook that gets triggered if no registered class serialization hooks catch obj.

Serialization predicate-hook pairs are evaluated here in reversed order of registration. If no predicates apply, this serializer’s fallback strategy is applied.

Parameters:
  • obj – Object to be serialized.

  • serializer – Serializer passed on to predicate hooks and fallback strategy.

Returns:

Serialized data without class information.

deserialize(typed_data: Any) Any

Central method for deserializing objects with this Serializer.

Objects are deserialized in the following order of preference, where cls is the target class corresponding to the class tag contained in typed_data:

  1. If typed_data is one of pass_through_classes, the data is returned unaltered.

  2. If cls or any of its base classes has a class deserialization hook registered for it,

    the corresponding deserialization hook is used.

  3. If any of the registered deserialization predicates evaluate to True on the target

    cls or typed_data, the corresponding deserialization hook is used. Predicate-hook pairs are evaluated in reverse, i.e. most recently registered predicates are evaluated first.

  4. If none of the above apply, the selected fallback strategy is applied.

The class tag to determine the target cls for 2. or 3. is extracted from typed_data using self.typed_data_converter.extract_class_tag, if typed_data is of type TypedDataT compatible with self.typed_data_converter. Otherwise cls is taken as type(typed_data).

Parameters:

typed_data – Data to be deserialized.

Returns:

Deserialized object corresponding to the serialized data in typed_data.

register_class_deserialization_hook(cls: type[T], deserialize_fun: Callable[[Any, type[T], Serializer[TypedDataT, ClassTaggerT]], T])

Register a custom deserialization function for class cls.

Hint

Make sure to also register a corresponding serialization hook using register_class_serialization_hook or manage serialization of cls objects otherwise.

Parameters:
  • cls – The class for which to use deserialize_fun.

  • deserialize_funDeserializeHook for deserializing objects of type cls. It must take data of any type, a target class type[T] and a serializer and return the deserialized object of class T from the data. The additional serializer can be used to deserialize elements of nested data types. It must be configured with the same TypedDataConverter and ClassTagger type as self for consistency.

register_predicate_deserialization_hook(predicate: Callable[[T, type], bool], deserialize_fun: Callable[[Any, type[T], Serializer[TypedDataT, ClassTaggerT]], T])

Register a custom deserialization function for data or classes that fulfill a predicate.

In contrast to register_class_deserialization_hook this method allows to register deserialization hooks that get triggered by inspecting the data or the target class itself ‘ rather than triggering a deserialization hook merely on the target class’s mro.

The registered deserialize_fun gets triggered whenever predicate evaluates to True on the passed data or target class.

Hint

Make sure to also register appropriate hooks for serializing objects covered by the registered predicate-hook pair.

Parameters:

Examples

Register a hook for all data that is of list type

>>> serializer.register_predicate_deserialization_hook(
>>>     lambda data, _: isinstance(data, list), deserialize_fun
>>> )

Register a hook for all target classes that have a class variable dim of value 2

>>> serializer.register_predicate_deserialization_hook(
>>>     lambda _, cls: getattr(cls, "dim", None) == 2, deserialize_fun
>>> )
deserialize_object(data: Any, cls: type[T], serializer: Serializer[TypedDataT, ClassTaggerT]) T

Catch-all deserialization hook that gets triggered if no registered class deserialization hooks catch data.

Deserialization predicates are evaluated here in reversed order of registration. If no predicates apply, this serializer’s fallback strategy is applied.

Parameters:
  • data – Pure serialized data without class information.

  • cls – Target class to construct from data.

  • serializer – Serializer passed to predicate and fallback hooks.

Returns:

Deserialized object of type cls.

parityos_serialization.serializer.SerializeHook

Type for callables for serializing an object of type T to serialized data.

The additionally passed serializer is meant to be used to serialize any potential internal data.

Parameters:
  • obj (T) – Object to serialize.

  • serializer (Serializer[TypedDataT, ClassTaggerT]) – serializer for serializing internal data.

Returns:

serialized data

Return type:

Any

alias of Callable[[T, Serializer[TypedDataT, ClassTaggerT]], Any]

parityos_serialization.serializer.DeserializeHook

Type of callables for deserializing an object of type T from serialized data.

The additionally passed serializer is meant to be used to deserialize any potential internal data.

Parameters:
  • data (Any) – Serialized data.

  • cls (type[T]) – Target class to deserialize to.

  • serializer (Serializer[TypedDataT, ClassTaggerT]) – Serializer for deserializing internal data.

Returns:

Deserialized object of type T constructed from data.

Return type:

obj (T)

alias of Callable[[Any, type[T], Serializer[TypedDataT, ClassTaggerT]], T]

class parityos_serialization.serializer.DeterministicJsonSerializer(typed_data_converter: TypedDataConverter[TypedDataT] = <parityos_serialization.utils.typed_data_converter.DictTypedDataConverter object>, class_tagger: ClassTaggerT = <parityos_serialization.utils.class_tagger.NameClassTagger object>, fallback_strategy: Any, ~parityos_serialization.utils.typedefs.TypedDataT, ~parityos_serialization.utils.class_tagger.ClassTaggerT]=FallBackStrategy.RAISE)

Bases: Serializer[TypedDataT, ClassTaggerT]

Preconfigured serializer that serializes to data that can be directly exported to json format.

Any containers with undefined item order like sets or mappings are deterministically serialized by first sorting their elements.

Uses the following default set of pass-through classes:

Pass-through classes can be deregistered with deregister_pass_through_class while additional ones can be registered with register_pass_through_class.

Parameters:
  • typed_data_converter – Data converter that combines and extracts serialized data and type information in form of a class tag. Defaults to DictTypedDataConverter.

  • class_tagger – Class tagger object that manages mapping between classes and their class tags. Defaults to an empty NameClassTagger.

  • fallback_strategy – Strategy for dealing with objects that are not caught by any hooks. Can be a preconfigured strategy from the FallBackStrategy enum or a custom HookPair.

class parityos_serialization.serializer.FastJsonSerializer(typed_data_converter: TypedDataConverter[TypedDataT] = <parityos_serialization.utils.typed_data_converter.DictTypedDataConverter object>, class_tagger: ClassTaggerT = <parityos_serialization.utils.class_tagger.NameClassTagger object>, fallback_strategy: Any, ~parityos_serialization.utils.typedefs.TypedDataT, ~parityos_serialization.utils.class_tagger.ClassTaggerT]=FallBackStrategy.RAISE)

Bases: DeterministicJsonSerializer[TypedDataT, ClassTaggerT]

Preconfigured serializer that serializes to data that can be directly exported to json format.

This serializer derives from DeterministicJsonSerializer and differs from it only in the way it serializers containers with undefined item order like sets or mappings. Elements of such containers are not sorted for the sake of faster serialization, resulting in non-deterministic serialization results. That is, the same data might be serialized to different, non-equal serialized data, which is however equivalent and deserializes to the same original object.

Parameters:
  • typed_data_converter – Data converter that combines and extracts serialized data and type information in form of a class tag. Defaults to DictTypedDataConverter.

  • class_tagger – Class tagger object that manages mapping between classes and their class tags. Defaults to an empty NameClassTagger.

  • fallback_strategy – Strategy for dealing with objects that are not caught by any hooks. Can be a preconfigured strategy from the FallBackStrategy enum or a custom HookPair.