Skip to content

type_serializer.py

ofrak.service.serialization.serializers.type_serializer

TypeSerializer (SerializerInterface)

Serialize and deserialize classes (not instances) into PJSONType

Implementation: the module path and name of the class are encoded into a single string.

obj_to_pjson(self, cls, _type_hint)

Serialize the object to PJSON. Note that the generic self._service.to_pjson can be used here.

Source code in ofrak/service/serialization/serializers/type_serializer.py
def obj_to_pjson(self, cls: Type, _type_hint: Any) -> str:
    module = inspect.getmodule(cls)
    if module is None:
        raise TypeError(f"Can't find the module where {cls} was defined")
    import_path = module.__name__
    cls_name = cls.__name__
    return f"{import_path}.{cls_name}"

pjson_to_obj(self, pjson_obj, _type_hint)

Deserialize PJSON into the object. Note that the generic self._service.from_pjson can be used here.

Source code in ofrak/service/serialization/serializers/type_serializer.py
def pjson_to_obj(self, pjson_obj: str, _type_hint: Any) -> Type:
    module_path, cls_name = pjson_obj.rsplit(".", maxsplit=1)
    # To avoid executing arbitrary code, only allow deserialization from modules
    # which are already loaded.
    try:
        module = sys.modules[module_path]
    except KeyError:
        raise ValueError(f"Can't deserialize {pjson_obj}: module not already loaded")
    cls = getattr(module, cls_name)
    return cls

is_metaclass(type_hint)

Will recognize Type, Type[X], and metaclasses

Source code in ofrak/service/serialization/serializers/type_serializer.py
def is_metaclass(type_hint):
    """Will recognize Type, Type[X], and metaclasses"""
    return any(
        [
            type_hint == Type,
            get_origin(type_hint) == type,
            inspect.isclass(type_hint) and issubclass(type_hint, type),
        ]
    )