Coverage for src/lexigram/features/module.py: 100%
18 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-26 02:04 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-26 02:04 +0800
1"""Feature flags module for dependency injection."""
3from __future__ import annotations
5from typing import Any
7from lexigram.contracts.feature_flags import FlagProviderProtocol
8from lexigram.di.module import DynamicModule, Module, module
9from lexigram.features.di.provider import FeatureFlagsProvider
12@module()
13class FeatureFlagsModule(Module):
14 """In-memory and extensible feature flag evaluation.
16 Call :meth:`configure` to seed initial flag state from a
17 :class:`~lexigram.features.config.FeatureFlagsConfig`.
19 Usage::
21 from lexigram.features.config import FeatureFlagsConfig
23 @module(
24 imports=[
25 FeatureFlagsModule.configure(
26 FeatureFlagsConfig(initial_flags={"beta_feature": True})
27 )
28 ]
29 )
30 class AppModule(Module):
31 pass
32 """
34 @classmethod
35 def configure(cls, config: Any | None = None) -> DynamicModule:
36 """Create a FeatureFlagsModule with explicit configuration.
38 Args:
39 config: :class:`~lexigram.features.config.FeatureFlagsConfig`
40 or ``None`` for framework defaults (all flags disabled).
42 Returns:
43 A :class:`~lexigram.di.module.DynamicModule` descriptor.
44 """
45 from lexigram.features.config import FeatureFlagsConfig
47 if config is not None and not isinstance(config, FeatureFlagsConfig):
48 raise TypeError(
49 f"config must be FeatureFlagsConfig, got {type(config).__name__}"
50 )
52 return DynamicModule(
53 module=cls,
54 providers=[FeatureFlagsProvider(config=config)],
55 exports=[FlagProviderProtocol],
56 )
58 @classmethod
59 def stub(cls, config: Any = None) -> DynamicModule:
60 """Return an in-memory FeatureFlagsModule for testing.
62 Registers the feature flag provider with no flags enabled by
63 default. Suitable for unit and integration tests.
65 Returns:
66 A DynamicModule with all flags disabled.
67 """
68 from lexigram.features.config import FeatureFlagsConfig
70 return DynamicModule(
71 module=cls,
72 providers=[FeatureFlagsProvider(config=FeatureFlagsConfig())],
73 exports=[FlagProviderProtocol],
74 )
77__all__ = ["FeatureFlagsModule"]