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
« 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
5from fast_depends.core import build_call_model 1abcdefghijklnopqrsmt
7if TYPE_CHECKING: 1abcdefghijklnopqrsmt
8 from fast_depends.core import CallModel
11Key: TypeAlias = Hashable 1abcdefghijklnopqrsmt
14class Provider: 1abcdefghijklnopqrsmt
15 dependencies: dict[Key, "CallModel"] 1abcdefghijklm
16 overrides: dict[Key, "CallModel"] 1abcdefghijklm
18 def __init__(self) -> None: 1abcdefghijklnopqrsmt
19 self.dependencies = {} 1abcdefghijklnopqrsmt
20 self.overrides = {} 1abcdefghijklnopqrsmt
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
28 def clear(self) -> None: 1abcdefghijklnopqrsmt
29 self.overrides = {} 1abcdefghijklnopqrsmt
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
39 def get_dependant(self, key: Key) -> "CallModel": 1abcdefghijklnopqrsmt
40 return self.overrides.get(key) or self.dependencies[key] 1abcdefghijklnopqrsmt
42 def override( 1abcdefghijklnopqrsmt
43 self,
44 original: Callable[..., Any],
45 override: Callable[..., Any],
46 ) -> None:
47 key = self.__get_original_key(original) 1abcdefghijklnopqrsmt
49 serializer_cls = None 1abcdefghijklnopqrsmt
51 if original_dependant := self.dependencies.get(key): 1abcdefghijklnopqrsmt
52 serializer_cls = original_dependant.serializer_cls 1abcdefghijklnopqrsmt
54 else:
55 self.dependencies[key] = build_call_model( 1abcdefghijklnopqrsmt
56 original,
57 dependency_provider=self,
58 )
60 override_model = build_call_model( 1abcdefghijklnopqrsmt
61 override,
62 dependency_provider=self,
63 serializer_cls=serializer_cls,
64 )
66 self.overrides[key] = override_model 1abcdefghijklnopqrsmt
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
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
88 def __get_original_key(self, original: Callable[..., Any]) -> Key: 1abcdefghijklnopqrsmt
89 return original 1abcdefghijklnopqrsmt