Source code for jgdv.mixins.annotate.registrator

  1#!/usr/bin/env python3
  2"""
  3
  4
  5"""
  6# Imports:
  7from __future__ import annotations
  8
  9# ##-- stdlib imports
 10import datetime
 11import enum
 12import functools as ftz
 13import itertools as itz
 14import logging as logmod
 15import pathlib as pl
 16import re
 17import time
 18import collections
 19import contextlib
 20import hashlib
 21from copy import deepcopy
 22from uuid import UUID, uuid1
 23from weakref import ref
 24import atexit # for @atexit.register
 25import faulthandler
 26# ##-- end stdlib imports
 27
 28from . import _interface as API # noqa: N812
 29from .annotate import SubAnnotate_m
 30
 31# ##-- types
 32# isort: off
 33# General
 34import abc
 35import collections.abc
 36import typing
 37import types
 38from typing import cast, assert_type, assert_never
 39from typing import Generic, NewType, Never
 40from typing import no_type_check, final, override, overload
 41# Protocols and Interfaces:
 42from typing import Protocol, runtime_checkable
 43if typing.TYPE_CHECKING:
 44    from typing import Final, ClassVar, Any, Self
 45    from typing import Literal, LiteralString
 46    from typing import TypeGuard
 47    from collections.abc import Iterable, Iterator, Callable, Generator
 48    from collections.abc import Sequence, Mapping, MutableMapping, Hashable
 49
 50    from jgdv import Maybe
 51
 52# isort: on
 53# ##-- end types
 54
 55##-- logging
 56logging = logmod.getLogger(__name__)
 57##-- end logging
 58
 59# Vars:
 60
 61# Body:
 62
[docs] 63class SubRegistry_m(SubAnnotate_m): 64 """ Create Subclasses in a registry 65 66 By doing: 67 68 class MyReg(SubRegistry_m): 69 _registry : dict[str, type] = {} 70 71 class MyClass(MyReg['blah']: ... 72 73 MyClass is created as a subclass of MyReg, with a parameter set to 'blah'. 74 This is added into MyReg._registry 75 """ 76 _registry : ClassVar[dict] = {} 77 78 @classmethod 79 def __init_subclass__(cls, *args:Any, **kwargs:Any) -> None: # noqa: ANN401 80 logging.debug("Registry Subclass: %s : %s : %s", cls, args, kwargs) 81 super().__init_subclass__(*args, **kwargs) 82 match getattr(cls, "_registry", None): 83 case None: 84 logging.debug("Creating Registry: %s : %s : %s", cls.__name__, args, kwargs) 85 cls._registry = {} 86 case _: 87 pass 88 match cls.cls_annotation(): 89 case None: 90 logging.debug("No Annotation") 91 pass 92 case x if x in cls._registry and issubclass(cls, (current:=cls._registry[x])): 93 logging.debug("Overriding : %s : %s : %s : (%s) : %s", cls.__name__, args, kwargs, x, current) 94 cls._registry[x] = cls 95 case x if x not in cls._registry: 96 logging.debug("Registering: %s : %s : %s : (%s)", cls.__name__, args, kwargs, x) 97 cls._registry.setdefault(x, cls) 98 99 @classmethod 100 def __class_getitem__(cls:type, *params:Any) -> type: # type:ignore # noqa: ANN401 101 match cls._registry.get(params[0], None): # type: ignore[attr-defined] 102 case None: 103 logging.debug("No Registered annotation class: %s :%s", cls, params) 104 return super().__class_getitem__(*params) # type: ignore[misc] 105 case x: 106 return x 107
[docs] 108 @classmethod 109 def get_registered(cls, *, param:Maybe=None) -> Self: 110 param = param or cls.cls_annotation() 111 return cls._registry.get(param, cls)
112
[docs] 113 @classmethod 114 def maybe_subclass(cls, *, param:Maybe=None) -> Maybe[Self]: 115 param = param or cls.cls_annotation() 116 return cls._registry.get(param, None)