Coverage for src / lexigram / contracts / plugins.py: 100%

13 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-08-19 05:41 +0800

1"""Plugin descriptor contract type. 

2 

3A ``PluginDescriptor`` is metadata-only — discovering it via the 

4``lexigram.plugins`` entry-point group (``EP_PLUGINS``) never imports or 

5instantiates the plugin's actual DI ``Provider``. That keeps listing 

6available plugins (e.g. for an admin UI) cheap even when a plugin's 

7provider class is heavy to import. 

8""" 

9 

10from __future__ import annotations 

11 

12from dataclasses import dataclass 

13 

14__all__ = ["PluginDescriptor"] 

15 

16 

17@dataclass(frozen=True) 

18class PluginDescriptor: 

19 """Metadata describing an admin-manageable plugin. 

20 

21 ``provider_entry_point`` is the entry-point *name* (not dotted path) 

22 this descriptor maps to within the ``lexigram.providers`` (``EP_PROVIDERS``) 

23 group — the identifier that goes into the ``disabled`` set passed to 

24 ``lexigram.plugins.discovery.discover_providers``. 

25 

26 ``requires``/``conflicts`` name other plugins' ``provider_entry_point`` 

27 values. They are advisory metadata: the boot engine evaluates them via 

28 ``validate_plan`` and skips plugins whose dependencies are missing or 

29 whose conflicts are enabled, logging non-fatal issues — boot is never 

30 blocked. 

31 """ 

32 

33 name: str 

34 display_name: str 

35 description: str 

36 icon: str 

37 provider_entry_point: str 

38 version: str = "" 

39 requires: tuple[str, ...] = () 

40 conflicts: tuple[str, ...] = ()