Coverage for src/lexigram/features/backends/chained.py: 100%

18 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-26 02:04 +0800

1"""Layered provider that queries multiple providers in order. 

2 

3The first provider that returns a non-*None* flag definition wins. 

4This allows environment overrides to take precedence over code-defined 

5defaults without modifying either provider. 

6""" 

7 

8from __future__ import annotations 

9 

10from typing import TYPE_CHECKING 

11 

12from lexigram.features.backends.base import AbstractFlagProvider 

13 

14if TYPE_CHECKING: 

15 from lexigram.features.types import Flag 

16 

17 

18class ChainedProvider(AbstractFlagProvider): 

19 """Layered provider that queries multiple providers in order. 

20 

21 The first provider that returns a non-*None* flag definition wins. 

22 When merging all flags, earlier providers take precedence over later ones. 

23 """ 

24 

25 def __init__(self, providers: list[AbstractFlagProvider]) -> None: 

26 self._providers = providers 

27 

28 # -- AbstractFlagProvider interface ------------------------------------- 

29 

30 async def get_flag_definition(self, name: str) -> Flag | None: 

31 """Return the first match across the provider chain, or *None*.""" 

32 for provider in self._providers: 

33 flag = await provider.get_flag_definition(name) 

34 if flag is not None: 

35 return flag 

36 return None 

37 

38 async def get_all_flags(self) -> dict[str, Flag]: 

39 """Merge flags from all providers; earlier providers take precedence.""" 

40 merged: dict[str, Flag] = {} 

41 # iterate in reverse so highest-priority providers overwrite 

42 for provider in reversed(self._providers): 

43 merged.update(await provider.get_all_flags()) 

44 return merged 

45 

46 

47__all__ = ["ChainedProvider"]