Module xtelligent_serial.data_structs
Expand source code
from .struct_descriptor import describe_struct_family, DescriptorInterface
from .struct_registry import register_struct_family
__all__ = [
'describe_struct_family',
'register_struct_family',
'DescriptorInterface',
]
Sub-modules
xtelligent_serial.data_structs.struct_descriptor
xtelligent_serial.data_structs.struct_registry
Functions
def describe_struct_family(name, is_instance:
, get_fields: ) ‑> DescriptorInterface -
Expand source code
def describe_struct_family(name, is_instance: is_instance_callback, get_fields: get_fields_callback) -> DescriptorInterface: return DescriptorInterface2(name, is_instance, get_fields)
def register_struct_family(descriptor: DescriptorInterface) ‑> FamilyRegistry
-
Expand source code
def register_struct_family(descriptor: DescriptorInterface) -> FamilyRegistry: def ds_struct(t: Type, raw_data: Mapping): type_fields = {f.name:f for f in descriptor.get_fields(t)} def pick_type(field: Field, value: Any) -> Type: return field.type or type(value) names_to_type = {k:pick_type(f, raw_data.get(k)) for k, f in type_fields.items()} kwargs = {k: deserialize(names_to_type[k], v) for k, v in raw_data.items() if k in type_fields} return t(**kwargs) def register_specific_type(t: Type): f = dispatcher.get(t) if f: return f def ds(raw_data: Mapping): # pylint: disable=invalid-name return ds_struct(t, raw_data) dispatcher[t] = ds return ds class StructProxy(ABC): @classmethod def __subclasshook__(cls, subclass): if descriptor.is_instance(subclass): register_specific_type(subclass) return True return False def ds_hook(raw_data, **kwargs): # check kwargs for type and dispatch accordingly. t = kwargs.get('type') if not t: raise ValueError('No type argument supplied') f = dispatcher.get(t) if not f: raise NotImplementedError(f'No serializer for type {t}') return f(raw_data) # Duplicate registrations cause ambiguous dispatch exceptions. if descriptor.name in registries: return registries[descriptor.name] register_deserializer(StructProxy, ds_hook) class Registry: @classmethod def has(cls, t: Type) -> bool: return issubclass(t, StructProxy) and t in dispatcher registries[descriptor.name] = Registry return Registry
Classes
class DescriptorInterface
-
Describes a family of classes/structs such as dataclass or attrs.
Expand source code
class DescriptorInterface: '''Describes a family of classes/structs such as dataclass or attrs.''' @property def name(self) -> str: '''Name of the family/API (dataclass, attrs)''' raise NotImplementedError() def is_instance(self, target: Any) -> bool: '''Returns True if an instance is from that family. Note that the API may not leverage inheritance for membership.''' raise NotImplementedError() def get_fields(self, t: Type) -> Iterable[Field]: '''Returns the fields of a type in the family/API. The result is an Iterable of dataclasses.Field instances.''' raise NotImplementedError()
Instance variables
var name : str
-
Name of the family/API (dataclass, attrs)
Expand source code
@property def name(self) -> str: '''Name of the family/API (dataclass, attrs)''' raise NotImplementedError()
Methods
def get_fields(self, t: Type) ‑> Iterable[dataclasses.Field]
-
Returns the fields of a type in the family/API. The result is an Iterable of dataclasses.Field instances.
Expand source code
def get_fields(self, t: Type) -> Iterable[Field]: '''Returns the fields of a type in the family/API. The result is an Iterable of dataclasses.Field instances.''' raise NotImplementedError()
def is_instance(self, target: Any) ‑> bool
-
Returns True if an instance is from that family. Note that the API may not leverage inheritance for membership.
Expand source code
def is_instance(self, target: Any) -> bool: '''Returns True if an instance is from that family. Note that the API may not leverage inheritance for membership.''' raise NotImplementedError()