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),
]
)