Coverage for fast_depends/dependencies/provider.py: 100%

42 statements  

« prev     ^ index     » next       coverage.py v7.17.3, created at 2026-11-13 05:19 +0000

1from collections.abc import Callable, Hashable, Iterator 1abcdefghijklnopqrsmt

2from contextlib import contextmanager 1abcdefghijklnopqrsmt

3from typing import TYPE_CHECKING, Any, TypeAlias 1abcdefghijklnopqrsmt

4 

5from fast_depends.core import build_call_model 1abcdefghijklnopqrsmt

6 

7if TYPE_CHECKING: 1abcdefghijklnopqrsmt

8 from fast_depends.core import CallModel 

9 

10 

11Key: TypeAlias = Hashable 1abcdefghijklnopqrsmt

12 

13 

14class Provider: 1abcdefghijklnopqrsmt

15 dependencies: dict[Key, "CallModel"] 1abcdefghijklm

16 overrides: dict[Key, "CallModel"] 1abcdefghijklm

17 

18 def __init__(self) -> None: 1abcdefghijklnopqrsmt

19 self.dependencies = {} 1abcdefghijklnopqrsmt

20 self.overrides = {} 1abcdefghijklnopqrsmt

21 

22 def merge(self, provider: "Provider") -> "Provider": 1abcdefghijklnopqrsmt

23 p = Provider() 1abcdefghijklnopqrsmt

24 p.dependencies = self.dependencies | provider.dependencies 1abcdefghijklnopqrsmt

25 p.overrides = self.overrides | provider.overrides 1abcdefghijklnopqrsmt

26 return p 1abcdefghijklnopqrsmt

27 

28 def clear(self) -> None: 1abcdefghijklnopqrsmt

29 self.overrides = {} 1abcdefghijklnopqrsmt

30 

31 def add_dependant( 1abcdefghijklnopqrsmt

32 self, 

33 dependant: "CallModel", 

34 ) -> Key: 

35 key = self.__get_original_key(dependant.call) 1abcdefghijklnopqrsmt

36 self.dependencies[key] = dependant 1abcdefghijklnopqrsmt

37 return key 1abcdefghijklnopqrsmt

38 

39 def get_dependant(self, key: Key) -> "CallModel": 1abcdefghijklnopqrsmt

40 return self.overrides.get(key) or self.dependencies[key] 1abcdefghijklnopqrsmt

41 

42 def override( 1abcdefghijklnopqrsmt

43 self, 

44 original: Callable[..., Any], 

45 override: Callable[..., Any], 

46 ) -> None: 

47 key = self.__get_original_key(original) 1abcdefghijklnopqrsmt

48 

49 serializer_cls = None 1abcdefghijklnopqrsmt

50 

51 if original_dependant := self.dependencies.get(key): 1abcdefghijklnopqrsmt

52 serializer_cls = original_dependant.serializer_cls 1abcdefghijklnopqrsmt

53 

54 else: 

55 self.dependencies[key] = build_call_model( 1abcdefghijklnopqrsmt

56 original, 

57 dependency_provider=self, 

58 ) 

59 

60 override_model = build_call_model( 1abcdefghijklnopqrsmt

61 override, 

62 dependency_provider=self, 

63 serializer_cls=serializer_cls, 

64 ) 

65 

66 self.overrides[key] = override_model 1abcdefghijklnopqrsmt

67 

68 def __setitem__( 1abcdefghijklnopqrsmt

69 self, 

70 key: Callable[..., Any], 

71 value: Callable[..., Any], 

72 ) -> None: 

73 """Alias for `provider[key] = value` syntax""" 

74 self.override(key, value) 1abcdefghijklnopqrsmt

75 

76 @contextmanager 1abcdefghijklnopqrsmt

77 def scope( 1abcdefghijklnopqrsmt

78 self, 

79 original: Callable[..., Any], 

80 override: Callable[..., Any], 

81 ) -> Iterator[None]: 

82 self.override(original, override) 1abcdefghijklnopqrsmt

83 try: 1abcdefghijklnopqrsmt

84 yield 1abcdefghijklnopqrsmt

85 finally: 

86 self.overrides.pop(self.__get_original_key(original), None) 1abcdefghijklnopqrsmt

87 

88 def __get_original_key(self, original: Callable[..., Any]) -> Key: 1abcdefghijklnopqrsmt

89 return original 1abcdefghijklnopqrsmt