Coverage for src / lexigram / contracts / core / registry.py: 0%
26 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-15 18:57 +0800
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-15 18:57 +0800
1"""Registry protocol for the Lexigram Framework.
3The concrete implementation lives in ``lexigram.core.registry``.
4"""
6from __future__ import annotations
8from collections.abc import Iterable
9from typing import Any, Protocol, TypeVar, runtime_checkable
11K = TypeVar("K")
12V = TypeVar("V")
15@runtime_checkable
16class RegistryProtocol(Protocol[K, V]):
17 """Structural protocol for registry-like containers.
19 Any class that exposes the core registry interface (register, get,
20 resolve, has, unregister, keys, clear) satisfies this protocol without
21 explicit inheritance.
22 """
24 def register(
25 self,
26 key: K,
27 value: V | None = None,
28 *,
29 allow_overwrite: bool | None = None,
30 ) -> Any:
31 """Register an item or use as a decorator."""
32 ...
34 def get(self, key: K, default: V | None = None) -> V | None:
35 """Retrieve an item by key, returning *default* if absent."""
36 ...
38 def resolve(self, key: K) -> V:
39 """Resolve an item, raising ``RegistryKeyError`` if not found."""
40 ...
42 def has(self, key: K) -> bool:
43 """Return ``True`` if *key* is registered."""
44 ...
46 def unregister(self, key: K) -> V | None:
47 """Remove and return the item registered under *key*."""
48 ...
50 def keys(self) -> Iterable[K]:
51 """Return all registered keys."""
52 ...
54 def values(self) -> Iterable[V]:
55 """Return all registered values."""
56 ...
58 def items(self) -> Iterable[tuple[K, V]]:
59 """Return all registered key-value pairs."""
60 ...
62 def all_keys(self) -> set[K]:
63 """Return all keys, including those with pending factories."""
64 ...
66 def clear(self) -> None:
67 """Remove all registered items and factories."""
68 ...
71@runtime_checkable
72class BackendRegistryProtocol(Protocol[V]):
73 """Structural protocol for factory-chain backend registries.
75 A backend registry holds factory classes each capable of answering
76 ``can_create(config)`` and constructing an instance. The first matching
77 factory is selected at runtime.
79 Example::
81 class CacheBackendRegistry(BackendRegistryProtocol[CacheBackendProtocol]):
82 def select(self, config: dict) -> CacheBackendProtocol: ...
83 """
85 def select(self, config: dict[str, Any]) -> V:
86 """Return the first backend whose ``can_create`` accepts *config*.
88 Args:
89 config: Backend configuration dictionary.
91 Returns:
92 A backend instance matching the config.
94 Raises:
95 ValueError: When no registered backend can handle *config*.
96 """
97 ...
99 def register_backend(self, key: str, backend_cls: type[V]) -> None:
100 """Register a backend factory class under *key*.
102 Args:
103 key: Unique backend identifier.
104 backend_cls: Backend class implementing the backend protocol.
105 """
106 ...
109@runtime_checkable
110class StrategyRegistryProtocol(Protocol[K, V]): # type: ignore[misc]
111 """Structural protocol for pluggable strategy registries.
113 A strategy registry maps named keys to algorithm implementations and
114 instantiates them on demand.
116 Example::
118 class ChunkingStrategyRegistry(
119 StrategyRegistryProtocol[str, ChunkerProtocol]
120 ):
121 def instantiate(self, key: str, **kwargs) -> ChunkerProtocol: ...
122 """
124 def register_strategy(self, key: K, strategy_cls: type[V]) -> None:
125 """Register a strategy class.
127 Args:
128 key: Strategy name or enum key.
129 strategy_cls: Class implementing the strategy protocol.
130 """
131 ...
133 def instantiate(self, key: K, **kwargs: Any) -> V:
134 """Instantiate and return a strategy for *key*.
136 Args:
137 key: Strategy identifier.
138 **kwargs: Constructor arguments forwarded to the strategy class.
140 Returns:
141 An instance of the strategy.
143 Raises:
144 RegistryKeyError: When *key* is not registered.
145 """
146 ...
149__all__ = [
150 "BackendRegistryProtocol",
151 "RegistryProtocol",
152 "StrategyRegistryProtocol",
153]