# -*- coding: utf-8 -*-
"""
lories._core._registrator
~~~~~~~~~~~~~~~~~~~~~~~~~
"""
from __future__ import annotations
import re
from abc import abstractmethod
from copy import deepcopy
from typing import Any, Collection, Dict, Generic, Optional, Type, TypeVar, Union, overload
from lories._core._configurations import Configurations
from lories._core._configurator import _Configurator
from lories._core._context import _Context
from lories._core._entity import _Entity
from lories.util import validate_key
[docs]
class _Registrator(_Configurator, _Entity):
INCLUDES: Collection[str] = ()
TYPE: str = "registrator"
@property
@abstractmethod
def context(self) -> RegistratorContext: ...
# noinspection PyShadowingBuiltins
@classmethod
def _build_id(
cls,
id: Optional[str] = None,
key: Optional[str] = None,
context: Optional[RegistratorContext] = None,
configs: Optional[Configurations] = None,
) -> str:
if configs is not None:
if id is None:
if configs.has_member(cls.TYPE) and "id" in configs[cls.TYPE]:
id = configs[cls.TYPE]["id"]
elif "id" in configs:
id = configs["id"]
if key is None:
if configs.has_member(cls.TYPE) and "key" in configs[cls.TYPE]:
key = configs[cls.TYPE]["key"]
elif "key" in configs:
key = configs["key"]
else:
key = validate_key("_".join(re.split(r"[^\w-]", configs.key)))
if key is None:
raise ValueError(f"Unable to build '{cls.__name__}' for missing ID")
if id is None and context is not None and isinstance(context, _Registrator):
id = f"{context.id}.{key}"
else:
id = key
return id
@classmethod
def _build_key(cls, key: Optional[str], configs: Optional[Configurations]) -> str:
if configs is not None:
if configs.has_member(cls.TYPE) and "key" in configs[cls.TYPE]:
key = configs[cls.TYPE]["key"]
elif "key" in configs:
key = configs["key"]
else:
if configs.has_member(cls.TYPE) and "name" in configs[cls.TYPE]:
key = validate_key(configs[cls.TYPE]["name"])
elif "name" in configs:
key = validate_key(configs["name"])
elif key is None:
key = validate_key("_".join(re.split(r"[^\w-]", configs.key)))
if key is None:
raise ValueError(f"Unable to build '{cls.__name__}' for missing key")
return key
@classmethod
def _build_name(cls, name: Optional[str], configs: Optional[Configurations]) -> str:
if configs is not None:
if configs.has_member(cls.TYPE) and "name" in configs[cls.TYPE]:
name = configs[cls.TYPE]["name"]
elif "name" in configs:
name = configs["name"]
return name
@classmethod
def _build_defaults(
cls,
configs: Configurations,
includes: Optional[Collection[str]] = (),
**kwargs,
) -> Dict[str, Any]:
defaults = {k: deepcopy(v) for k, v in configs.items() if k in cls.INCLUDES or k in includes}
defaults.update(**kwargs)
return defaults
Registrator = TypeVar("Registrator", bound=_Registrator)
# noinspection PyAbstractClass, PyShadowingBuiltins
[docs]
class _RegistratorContext(_Context[Registrator], Generic[Registrator]):
TYPE: str = "registrators"
@overload
def get_all(self) -> Collection[Registrator]: ...
@overload
def get_all(self, type: str, *other: str) -> Collection[Registrator]: ...
@overload
def get_all(self, type: Type[Registrator], *other: Type[Registrator]) -> Collection[Registrator]: ...
def get_all(self, *types: str | Type[Registrator]) -> Collection[Registrator]: ...
@overload
def get_first(self) -> Collection[Registrator]: ...
@overload
def get_first(self, type: str) -> Collection[Registrator]: ...
@overload
def get_first(self, type: str, *other: str) -> Collection[Registrator]: ...
@overload
def get_first(self, type: Type[Registrator], *other: Type[Registrator]) -> Collection[Registrator]: ...
def get_first(self, *types: str | Type[Registrator]) -> Optional[Registrator]: ...
@overload
def get_last(self) -> Collection[Registrator]: ...
@overload
def get_last(self, type: str, *other: str) -> Collection[Registrator]: ...
@overload
def get_last(self, type: Type[Registrator], *other: Type[Registrator]) -> Collection[Registrator]: ...
def get_last(self, *types: str | Type[Registrator]) -> Optional[Registrator]: ...
@overload
def has_type(self, type: str, *other: str) -> bool: ...
@overload
def has_type(self, type: Type[Registrator], *other: Type[Registrator]) -> bool: ...
def has_type(self, *types: str | Type[Registrator]) -> bool: ...
RegistratorContext = TypeVar(
name="RegistratorContext",
bound=Union[_RegistratorContext[_Registrator], _Registrator],
)