Coverage for src/lexigram/admin/contributors/registry.py: 0%

26 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-24 23:18 +0800

1"""Contributor registry — registry-based dispatch for admin contributors.""" 

2 

3from __future__ import annotations 

4 

5from collections.abc import Sequence 

6 

7from lexigram.contracts.admin.protocols import AdminContributorProtocol 

8 

9 

10class ContributorRegistry: 

11 """Registry that collects and manages admin contributors. 

12 

13 Follows the Registry pattern (AGENTS.md §6.3): empty ``__init__``, 

14 ``with_defaults()`` classmethod for pre-populated instances. 

15 """ 

16 

17 def __init__(self) -> None: 

18 self._contributors: dict[str, AdminContributorProtocol] = {} 

19 

20 @classmethod 

21 def with_defaults(cls) -> ContributorRegistry: 

22 """Create a registry (no built-in contributors by default).""" 

23 return cls() 

24 

25 def register(self, contributor: AdminContributorProtocol) -> None: 

26 """Register a contributor, keyed by its name.""" 

27 self._contributors[contributor.name] = contributor 

28 

29 def get(self, name: str) -> AdminContributorProtocol | None: 

30 """Get a contributor by name, or None.""" 

31 return self._contributors.get(name) 

32 

33 def get_all(self) -> Sequence[AdminContributorProtocol]: 

34 """Get all contributors sorted by priority (lower = first).""" 

35 return sorted( 

36 self._contributors.values(), 

37 key=_priority_or_default, 

38 ) 

39 

40 def get_by_group(self, group: str) -> Sequence[AdminContributorProtocol]: 

41 """Get contributors in a specific group, sorted by priority.""" 

42 return sorted( 

43 [c for c in self._contributors.values() if c.group == group], 

44 key=_priority_or_default, 

45 ) 

46 

47 

48def _priority_or_default(contributor: AdminContributorProtocol) -> int: 

49 """Return contributor priority, or a high default when missing (mocks, tests).""" 

50 try: 

51 p = contributor.priority 

52 if not isinstance(p, int): 

53 return 9999 

54 return p 

55 except Exception: # noqa: BLE001 — fallback for test doubles 

56 return 9999 

57 

58 

59__all__ = ["ContributorRegistry"]