|
4 | 4 |
|
5 | 5 | from configparser import ConfigParser |
6 | 6 | from dataclasses import dataclass, field |
7 | | -from typing import TYPE_CHECKING, Callable, Type, Optional, TypeVar, Generic |
| 7 | +from typing import TYPE_CHECKING, Callable, Type, Optional, TypeVar, Generic, ClassVar, Any |
8 | 8 |
|
9 | 9 | if TYPE_CHECKING: |
10 | 10 | from core import Node |
@@ -41,23 +41,73 @@ def __hash__(self): |
41 | 41 |
|
42 | 42 |
|
43 | 43 | class DataObjectFactory(Generic[T]): |
44 | | - _instance: Optional[DataObjectFactory] = None |
45 | | - _registry: dict[Type[T], Type[T]] = {} |
46 | | - |
47 | | - def __new__(cls) -> DataObjectFactory: |
| 44 | + """ |
| 45 | + A singleton factory for creating data objects with registration support. |
| 46 | +
|
| 47 | + This class provides a central registry for data object types and a factory |
| 48 | + method for instantiating them. It uses a singleton pattern to ensure a single |
| 49 | + instance is shared across the application. |
| 50 | +
|
| 51 | + Type Parameters: |
| 52 | + T: The base type for objects created by this factory |
| 53 | +
|
| 54 | + Attributes: |
| 55 | + _instance: The singleton instance of this class |
| 56 | + _registry: Dictionary mapping object types to their implementation classes |
| 57 | + """ |
| 58 | + _instance: Optional['DataObjectFactory[T]'] = None |
| 59 | + # Using class variable storage that's independent of the generic type parameter |
| 60 | + _registry: ClassVar[dict[Any, Any]] = {} |
| 61 | + |
| 62 | + def __new__(cls) -> 'DataObjectFactory[T]': |
| 63 | + """ |
| 64 | + Creates a singleton instance of the factory. |
| 65 | +
|
| 66 | + Returns: |
| 67 | + The singleton instance of DataObjectFactory |
| 68 | + """ |
48 | 69 | if cls._instance is None: |
49 | 70 | cls._instance = super(DataObjectFactory, cls).__new__(cls) |
50 | 71 | return cls._instance |
51 | 72 |
|
52 | 73 | @classmethod |
53 | 74 | def register(cls, t: Optional[Type[T]] = None) -> Callable[[Type[T]], Type[T]]: |
| 75 | + """ |
| 76 | + Decorator for registering implementation classes with the factory. |
| 77 | +
|
| 78 | + Args: |
| 79 | + t: Optional type to use as the registration key. If not provided, |
| 80 | + the implementation class itself is used as the key. |
| 81 | +
|
| 82 | + Returns: |
| 83 | + A decorator function that registers the decorated class |
| 84 | +
|
| 85 | + Example: |
| 86 | + @DataObjectFactory.register(BaseClass) |
| 87 | + class Implementation(BaseClass): |
| 88 | + pass |
| 89 | + """ |
| 90 | + |
54 | 91 | def inner_wrapper(wrapped_class: Type[T]) -> Type[T]: |
55 | | - cls._registry[t or wrapped_class] = wrapped_class |
| 92 | + DataObjectFactory._registry[t or wrapped_class] = wrapped_class |
56 | 93 | return wrapped_class |
57 | 94 |
|
58 | 95 | return inner_wrapper |
59 | 96 |
|
60 | 97 | @classmethod |
61 | 98 | def new(cls, t: Type[T], **kwargs) -> T: |
| 99 | + """ |
| 100 | + Creates a new instance of the registered implementation class. |
| 101 | +
|
| 102 | + Args: |
| 103 | + t: The type to instantiate (must be registered) |
| 104 | + **kwargs: Arguments to pass to the constructor |
| 105 | +
|
| 106 | + Returns: |
| 107 | + A new instance of the requested type |
| 108 | +
|
| 109 | + Raises: |
| 110 | + KeyError: If the requested type is not registered |
| 111 | + """ |
62 | 112 | # noinspection PyArgumentList |
63 | | - return cls._registry[t](**kwargs) |
| 113 | + return DataObjectFactory._registry[t](**kwargs) |
0 commit comments