stouputils.collections.registry module#

class Registry(
*args: Any,
key_getter: Callable[[T], str] | None = None,
**kwargs: Any,
)[source]#

Bases: dict[str, T], Generic

Dictionary that registers any object by decorator.

key_getter: Callable[[T], str] | None[source]#

Callable taking an object and returning its key, or None to use the object’s name.

register(function: T, /) T[source]#
register(
*,
name: str | None = None,
) Callable[[T], T]

Register a callable by its own name or a custom name.

Python applies stacked decorators from bottom to top. Put register outermost when the registry should keep the fully decorated callable.

>>> FUNCS = Registry[Callable[[int], int]]()
>>> from stouputils import handle_error
>>> @FUNCS.register
... @handle_error
... def measured(value: int) -> int: return value * 5
>>> FUNCS["measured"] is measured
True
>>> class Shape:
...     @classmethod
...     def get_name(cls) -> str: return cls.__name__.lower()
>>> SHAPES = Registry[type[Shape]](key_getter=lambda cls: cls.get_name())
>>> @SHAPES.register
... class Circle(Shape): pass
>>> @SHAPES.register(name="square")
... class Square(Shape): pass
>>> sorted(SHAPES), SHAPES["circle"] is Circle
(['circle', 'square'], True)
>>> @SHAPES.register()
... class NotAShape: pass
Traceback (most recent call last):
...
AttributeError: type object 'NotAShape' has no attribute 'get_name'
>>> @SHAPES.register(name="circle")
... class Duplicate(Shape): pass
Traceback (most recent call last):
...
KeyError: "The name 'circle' is already registered."