forked from OpenBMB/ChatDev
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathregistry.py
More file actions
executable file
·74 lines (55 loc) · 2.34 KB
/
registry.py
File metadata and controls
executable file
·74 lines (55 loc) · 2.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
"""Generic registry utilities for pluggable backend components."""
from dataclasses import dataclass, field
from importlib import import_module
from typing import Any, Callable, Dict, Iterable, Optional
class RegistryError(RuntimeError):
"""Raised when registering duplicated or invalid entries."""
@dataclass(slots=True)
class RegistryEntry:
name: str
loader: Callable[[], Any]
metadata: Dict[str, Any] = field(default_factory=dict)
def load(self) -> Any:
return self.loader()
class Registry:
"""Lightweight registry with lazy module loading support."""
def __init__(self, namespace: str) -> None:
self.namespace = namespace
self._entries: Dict[str, RegistryEntry] = {}
def register(
self,
name: str,
*,
loader: Callable[[], Any] | None = None,
target: Any | None = None,
metadata: Optional[Dict[str, Any]] = None,
module_path: str | None = None,
attr_name: str | None = None,
) -> None:
if name in self._entries:
raise RegistryError(f"Duplicate registration for '{name}' in {self.namespace}")
if loader is None:
if target is None and module_path is None:
raise RegistryError("Must provide loader, target, or module_path/attr_name")
if target is not None:
loader = lambda target=target: target
else:
if not attr_name:
raise RegistryError("module_path requires attr_name")
def _lazy_loader(mod_path: str = module_path, attr: str = attr_name) -> Any:
module = import_module(mod_path)
return getattr(module, attr)
loader = _lazy_loader
entry = RegistryEntry(name=name, loader=loader, metadata=dict(metadata or {}))
self._entries[name] = entry
def get(self, name: str) -> RegistryEntry:
try:
return self._entries[name]
except KeyError as exc:
raise RegistryError(f"Unknown entry '{name}' in {self.namespace}") from exc
def names(self) -> Iterable[str]:
return self._entries.keys()
def items(self) -> Iterable[tuple[str, RegistryEntry]]:
return self._entries.items()
def metadata_for(self, name: str) -> Dict[str, Any]:
return dict(self.get(name).metadata)