Source code for dazzler.system._component

import secrets

from ._undefined import UNDEFINED


__all__ = [
    'Aspect', 'Component', 'prepare_aspects'
]


# noinspection PyProtectedMember
def prepare_aspect(value):
    if value is not UNDEFINED:
        if isinstance(value, Component):
            return value._prepare()
        if isinstance(value, (list, tuple)):
            return [prepare_aspect(y) for y in value]
        if isinstance(value, dict):
            return prepare_aspects(value)
    return value


# noinspection PyProtectedMember
def prepare_aspects(aspects: dict):
    data = {}
    for aspect, value in aspects.items():
        if value is not UNDEFINED:
            data[aspect] = prepare_aspect(value)
    return data


def _generate_identity():
    return hex(secrets.randbits(40)).lstrip('0x')


# noinspection PyProtectedMember
[docs]class Aspect: """ Aspects of component are represented on both backend and frontend. """
[docs] def __init__( self, name=None, default=UNDEFINED, required=False, children=False, docstring=None, ): self.name = name self.default = default self.required = required self.children = children self.__doc__ = docstring
def __set_name__(self, owner, name): self.name = name owner._aspects_keys.append(name) if self.children: owner._children.append(name) def __get__(self, instance, owner): if instance is None: return self value = instance._aspects.get(self.name, UNDEFINED) return value def __set__(self, instance, value): if self.default is not UNDEFINED \ and self.default == value \ and not instance._initialized: return instance._aspects[self.name] = value
[docs]class Component: _aspects_keys = [] _package_name = '' _children = []
[docs] def __init__( self, aspects, identity: str = None, ): self.identity = identity or _generate_identity() self._initialized = False self._aspects = {} for k, v in aspects.items(): if k in ('self', 'args', 'kwargs', 'identity'): continue setattr(self, k, v) self._initialized = True
def _prepare(self) -> dict: return { 'name': self.__class__.__name__, 'identity': self.identity, 'package': self._package_name, 'aspects': prepare_aspects(self._aspects), } def __repr__(self): return f'<[{self._package_name}.{self.__class__.__name__}]' \ f' ({self.identity})>'