Source code for beagles.base

"""Base classes and methods for other BEAGLES modules"""
from typing import Union, AnyStr, List, Type, Callable
from abc import abstractmethod
from beagles.base.box import *
from beagles.base.constants import *
from beagles.base.errors import *
from beagles.base.flags import *
from beagles.base.shape import *
from beagles.base.stringBundle import *
from beagles.base.timer import *
import beagles.base.version

PreprocessedBox = PreprocessedBox
"""
:class:`PreprocessedBox`
"""

ProcessedBox = ProcessedBox
"""
:class:`ProcessedBox`
"""

PostprocessedBox = PostprocessedBox
"""
:class:`PostprocessedBox`
"""

Flags = Flags
"""
:class:`Flags`
"""

Shape = Shape
"""
:class:`Shape`
"""

Timer = Timer
"""
:class:`Timer`
"""

StringBundle = StringBundle
"""
:class:`StringBundle`
"""

getStr = getStr
"""Convenience function to grab strings from :class:`StringBundle`

    Args:
        strId: resource ID for the string to get

    Returns:
        str matching the resource ID
"""


[docs]class Subsystem(object): token: dict class __metaclass__(type): msg = 'Subsystem objects should have a constructor() not an __init__().' def __init__(cls, *args, **kwargs): super(type, cls).__init__(*args, **kwargs) if cls.__init__ is not Subsystem.__init__: raise NotImplementedError(cls.msg)
[docs] @abstractmethod def constructor(self, *args, **kwargs): raise NotImplementedError
[docs]class SubsystemPrototype(object): create_key = object() constructor: Subsystem.constructor token: dict def __init__(self, create_key, *args, **kwargs): msg = "SubsystemPrototype subclasses must define a create classmethod" if not create_key == self.create_key: raise NotImplementedError(msg) self.constructor(*args, **kwargs)
[docs] @classmethod def get_register(cls) -> dict: token_register = dict() for subclass in cls.__subclasses__(): token_register.update(subclass.token) return token_register
[docs] @classmethod @abstractmethod def create(cls, *args): raise NotImplementedError(cls.msg)
[docs]def register_subsystem(token: Union[AnyStr, List], prototype: Type[SubsystemPrototype]) -> Callable: """Decorator to register :class:`Subsystem` metadata tokens to a :class:`SubsystemPrototype` Example: Can be used with a single text token... .. code-block:: python @register_subsystem(token='[detection]', prototype=Framework) class Yolo(Subsystem): ... .. code-block:: pycon >>> Yolo.token {'[detection]': Yolo} Or can be be used with multiple token splitting on space... .. code-block:: python @register_subsystem(token='sse l1 l2 smooth sparse softmax', prototype=Framework) class NeuralNet(Subsystem): ... .. code-block:: pycon >>> NeuralNet.token {'sse': NeuralNet, l1: NeuralNet, l2: NeuralNet, ...} Returns: A registered :class:`Subsystem` with :attr:`Subsystem.token` set to `{cls: token}` and it's :attr:`__mro__` overridden with `prototype`. Raises: TypeError: If :class:`Subsystem` or :class:`SubsystemPrototype` isn't in the registered class MRO """ def raise_error(klass, name, mro): msg = f'{klass} not found in {name} MRO: {mro}' raise TypeError(msg) if SubsystemPrototype not in prototype.__mro__: raise_error(SubsystemPrototype, prototype.__name__, prototype.__mro__) def decorator(cls: type(Subsystem)) -> Subsystem: error = True if Subsystem not in cls.__mro__ else False if error and SubsystemPrototype not in cls.__mro__: raise_error(Subsystem, cls.__name__, cls.__mro__) types = token.split(' ') multi = dict(zip(types, list([cls]) * len(types))) single = {token: cls} cls.token = single if len(types) == 1 else multi cls.__bases__ = (prototype,) return cls return decorator