From 3952fd7437083d07cbb7dc9f6ec7e9c79726d171 Mon Sep 17 00:00:00 2001 From: Gabriel Dugny Date: Sun, 24 Mar 2024 14:25:18 +0100 Subject: [PATCH] fix: type component registry --- django_components/component.py | 1 + django_components/component_registry.py | 34 ++++++++++++++++--------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/django_components/component.py b/django_components/component.py index b6fac51f..d840db87 100644 --- a/django_components/component.py +++ b/django_components/component.py @@ -164,6 +164,7 @@ def _get_dir_path_from_component_module_path(component_module_path: str, candida class Component(View, metaclass=SimplifiedInterfaceMediaDefiningClass): # Either template_name or template must be set on subclass OR subclass must implement get_template() with # non-null return. + class_hash: ClassVar[int] template_name: ClassVar[Optional[str]] = None template: Optional[str] = None js: Optional[str] = None diff --git a/django_components/component_registry.py b/django_components/component_registry.py index 209592d7..54e099eb 100644 --- a/django_components/component_registry.py +++ b/django_components/component_registry.py @@ -1,44 +1,54 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Callable, Type, TypeVar + +if TYPE_CHECKING: + from django_components import component + +_TC = TypeVar("_TC", bound=Type["component.Component"]) + + class AlreadyRegistered(Exception): pass -class NotRegistered(Exception): +class NotRegistered(Exception) : pass -class ComponentRegistry(object): - def __init__(self): - self._registry = {} # component name -> component_class mapping +class ComponentRegistry: + def __init__(self) -> None: + self._registry: dict[str, type[component.Component]] = {} # component name -> component_class mapping - def register(self, name=None, component=None): + def register(self, name: str, component: type[component.Component]) -> None: existing_component = self._registry.get(name) if existing_component and existing_component.class_hash != component.class_hash: raise AlreadyRegistered('The component "%s" has already been registered' % name) self._registry[name] = component - def unregister(self, name): + def unregister(self, name: str) -> None: self.get(name) del self._registry[name] - def get(self, name): + def get(self, name: str) -> type[component.Component]: if name not in self._registry: raise NotRegistered('The component "%s" is not registered' % name) return self._registry[name] - def all(self): + def all(self) -> dict[str, type[component.Component]]: return self._registry - def clear(self): + def clear(self) -> None: self._registry = {} # This variable represents the global component registry -registry = ComponentRegistry() +registry: ComponentRegistry = ComponentRegistry() -def register(name): +def register(name: str) -> Callable[[_TC], _TC]: """Class decorator to register a component. Usage: @@ -48,7 +58,7 @@ def register(name): ... """ - def decorator(component): + def decorator(component: _TC) -> _TC: registry.register(name=name, component=component) return component