Coverage for tests/test_overrides.py: 100%
195 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 AsyncGenerator, Generator 1abcdefghijklmnopqrst
2from typing import Annotated 1abcdefghijklmnopqrst
3from unittest.mock import Mock 1abcdefghijklmnopqrst
5import pytest 1abcdefghijklmnopqrst
7from fast_depends import Depends, Provider, inject 1abcdefghijklmnopqrst
10def test_not_override(provider: Provider) -> None: 1abcdefghijklmnopqrst
11 mock = Mock() 1abcdefghijklmnopqrst
13 def base_dep(): 1abcdefghijklmnopqrst
14 mock.original() 1abcdefghijklmnopqrst
15 return 1 1abcdefghijklmnopqrst
17 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst
18 def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst
19 assert d == 1 1abcdefghijklmnopqrst
21 func() 1abcdefghijklmnopqrst
23 mock.original.assert_called_once() 1abcdefghijklmnopqrst
26def test_sync_override(provider: Provider) -> None: 1abcdefghijklmnopqrst
27 mock = Mock() 1abcdefghijklmnopqrst
29 def base_dep(): 1abcdefghijklmnopqrst
30 raise NotImplementedError
32 def override_dep(): 1abcdefghijklmnopqrst
33 mock.override() 1abcdefghijklmnopqrst
34 return 2 1abcdefghijklmnopqrst
36 provider.override(base_dep, override_dep) 1abcdefghijklmnopqrst
38 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst
39 def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst
40 assert d == 2 1abcdefghijklmnopqrst
42 func() 1abcdefghijklmnopqrst
44 provider.clear() 1abcdefghijklmnopqrst
47def test_override_by_key(provider: Provider) -> None: 1abcdefghijklmnopqrst
48 mock = Mock() 1abcdefghijklmnopqrst
50 def base_dep(): 1abcdefghijklmnopqrst
51 raise NotImplementedError
53 def override_dep(): 1abcdefghijklmnopqrst
54 mock.override() 1abcdefghijklmnopqrst
55 return 2 1abcdefghijklmnopqrst
57 provider[base_dep] = override_dep 1abcdefghijklmnopqrst
59 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst
60 def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst
61 assert d == 2 1abcdefghijklmnopqrst
63 func() 1abcdefghijklmnopqrst
65 provider.clear() 1abcdefghijklmnopqrst
68def test_override_context(provider: Provider) -> None: 1abcdefghijklmnopqrst
69 def base_dep(): 1abcdefghijklmnopqrst
70 return 1 1abcdefghijklmnopqrst
72 def override_dep(): 1abcdefghijklmnopqrst
73 return 2 1abcdefghijklmnopqrst
75 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst
76 def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst
77 return d 1abcdefghijklmnopqrst
79 with provider.scope(base_dep, override_dep): 1abcdefghijklmnopqrst
80 assert func() == 2 1abcdefghijklmnopqrst
82 assert func() == 1 1abcdefghijklmnopqrst
85def test_override_context_exception(provider: Provider) -> None: 1abcdefghijklmnopqrst
86 def base_dep(): 1abcdefghijklmnopqrst
87 return 1 1abcdefghijklmnopqrst
89 def override_dep(): 1abcdefghijklmnopqrst
90 return 2 1abcdefghijklmnopqrst
92 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst
93 def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst
94 return d 1abcdefghijklmnopqrst
96 with pytest.raises(ValueError): 1abcdefghijklmnopqrst
97 with provider.scope(base_dep, override_dep): 1abcdefghijklmnopqrst
98 assert func() == 2 1abcdefghijklmnopqrst
99 raise ValueError 1abcdefghijklmnopqrst
101 assert func() == 1 1abcdefghijklmnopqrst
104def test_sync_by_async_override(provider: Provider) -> None: 1abcdefghijklmnopqrst
105 def base_dep(): 1abcdefghijklmnopqrst
106 raise NotImplementedError
108 async def override_dep(): # pragma: no cover 1abcdefghijklmnopqrst
109 return 2
111 provider.override(base_dep, override_dep) 1abcdefghijklmnopqrst
113 with pytest.raises(AssertionError): 1abcdefghijklmnopqrst
115 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst
116 def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst
117 pass
120def test_sync_by_async_override_in_extra(provider: Provider) -> None: 1abcdefghijklmnopqrst
121 def base_dep(): 1abcdefghijklmnopqrst
122 raise NotImplementedError
124 async def override_dep(): # pragma: no cover 1abcdefghijklmnopqrst
125 return 2
127 provider.override(base_dep, override_dep) 1abcdefghijklmnopqrst
129 with pytest.raises(AssertionError): 1abcdefghijklmnopqrst
131 @inject( 1abcdefghijklmnopqrst
132 dependency_provider=provider,
133 extra_dependencies=(Depends(base_dep),),
134 )
135 def func(): 1abcdefghijklmnopqrst
136 pass
139@pytest.mark.anyio 1abcdefghijklmnopqrst
140async def test_async_override(provider: Provider) -> None: 1abcdefghijklmnopqrst
141 mock = Mock() 1abcdefghijklmnopqrst
143 async def base_dep(): 1abcdefghijklmnopqrst
144 raise NotImplementedError
146 async def override_dep(): 1abcdefghijklmnopqrst
147 mock.override() 1abcdefghijklmnopqrst
148 return 2 1abcdefghijklmnopqrst
150 provider.override(base_dep, override_dep) 1abcdefghijklmnopqrst
152 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst
153 async def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst
154 assert d == 2 1abcdefghijklmnopqrst
156 await func() 1abcdefghijklmnopqrst
157 mock.override.assert_called_once() 1abcdefghijklmnopqrst
160@pytest.mark.anyio 1abcdefghijklmnopqrst
161async def test_async_by_sync_override(provider: Provider) -> None: 1abcdefghijklmnopqrst
162 mock = Mock() 1abcdefghijklmnopqrst
164 async def base_dep(): 1abcdefghijklmnopqrst
165 raise NotImplementedError
167 def override_dep(): 1abcdefghijklmnopqrst
168 mock.override() 1abcdefghijklmnopqrst
169 return 2 1abcdefghijklmnopqrst
171 provider.override(base_dep, override_dep) 1abcdefghijklmnopqrst
173 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst
174 async def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst
175 assert d == 2 1abcdefghijklmnopqrst
177 await func() 1abcdefghijklmnopqrst
178 mock.override.assert_called_once() 1abcdefghijklmnopqrst
181def test_deep_overrides(provider: Provider) -> None: 1abcdefghijklmnopqrst
182 mock = Mock() 1abcdefghijklmnopqrst
184 def dep1(c=Depends(mock.dep2)): 1abcdefghijklmnopqrst
185 mock.dep1() 1abcdefghijklmnopqrst
187 def dep3(c=Depends(mock.dep4)): 1abcdefghijklmnopqrst
188 mock.dep3() 1abcdefghijklmnopqrst
190 @inject( 1abcdefghijklmnopqrst
191 dependency_provider=provider,
192 extra_dependencies=(Depends(dep1),),
193 )
194 def func() -> None: 1abcdefghijklmnopqrst
195 return 1abcdefghijklmnopqrst
197 func() 1abcdefghijklmnopqrst
198 mock.dep1.assert_called_once() 1abcdefghijklmnopqrst
199 mock.dep2.assert_called_once() 1abcdefghijklmnopqrst
200 assert not mock.dep3.called 1abcdefghijklmnopqrst
201 assert not mock.dep4.called 1abcdefghijklmnopqrst
202 mock.reset_mock() 1abcdefghijklmnopqrst
204 with provider.scope(dep1, dep3): 1abcdefghijklmnopqrst
205 func() 1abcdefghijklmnopqrst
206 assert not mock.dep1.called 1abcdefghijklmnopqrst
207 assert not mock.dep2.called 1abcdefghijklmnopqrst
208 mock.dep3.assert_called_once() 1abcdefghijklmnopqrst
209 mock.dep4.assert_called_once() 1abcdefghijklmnopqrst
212def test_deep_overrides_with_different_signatures(provider: Provider) -> None: 1abcdefghijklmnopqrst
213 mock = Mock() 1abcdefghijklmnopqrst
215 def dep1(c=Depends(mock.dep2)): 1abcdefghijklmnopqrst
216 mock.dep1() 1abcdefghijklmnopqrst
218 def dep3(): 1abcdefghijklmnopqrst
219 mock.dep3() 1abcdefghijklmnopqrst
221 @inject( 1abcdefghijklmnopqrst
222 dependency_provider=provider,
223 extra_dependencies=(Depends(dep1),),
224 )
225 def func(): 1abcdefghijklmnopqrst
226 return 1abcdefghijklmnopqrst
228 func() 1abcdefghijklmnopqrst
229 mock.dep1.assert_called_once() 1abcdefghijklmnopqrst
230 mock.dep2.assert_called_once() 1abcdefghijklmnopqrst
231 assert not mock.dep3.called 1abcdefghijklmnopqrst
232 mock.reset_mock() 1abcdefghijklmnopqrst
234 with provider.scope(dep1, dep3): 1abcdefghijklmnopqrst
235 func() 1abcdefghijklmnopqrst
236 assert not mock.dep1.called 1abcdefghijklmnopqrst
237 assert not mock.dep2.called 1abcdefghijklmnopqrst
238 mock.dep3.assert_called_once() 1abcdefghijklmnopqrst
241def test_override_context_with_generator(provider: Provider) -> None: 1abcdefghijklmnopqrst
242 def base_dep() -> Generator[int, None, None]: 1abcdefghijklmnopqrst
243 raise NotImplementedError
245 def override_dep() -> Generator[int, None, None]: 1abcdefghijklmnopqrst
246 yield 2 1abcdefghijklmnopqrst
248 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst
249 def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst
250 return d 1abcdefghijklmnopqrst
252 with provider.scope(base_dep, override_dep): 1abcdefghijklmnopqrst
253 assert func() == 2 1abcdefghijklmnopqrst
256def test_override_context_with_undefined_generator(provider: Provider) -> None: 1abcdefghijklmnopqrst
257 def base_dep() -> Generator[int, None, None]: 1abcdefghijklmnopqrst
258 raise NotImplementedError
260 def override_dep() -> Generator[int, None, None]: 1abcdefghijklmnopqrst
261 yield 2 1abcdefghijklmnopqrst
263 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst
264 def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst
265 return d 1abcdefghijklmnopqrst
267 with provider.scope(base_dep, override_dep): 1abcdefghijklmnopqrst
268 assert func() == 2 1abcdefghijklmnopqrst
271@pytest.mark.anyio 1abcdefghijklmnopqrst
272async def test_async_override_context_with_generator(provider: Provider) -> None: 1abcdefghijklmnopqrst
273 async def base_dep() -> AsyncGenerator[int, None]: 1abcdefghijklmnopqrst
274 raise NotImplementedError
276 async def override_dep() -> AsyncGenerator[int, None]: 1abcdefghijklmnopqrst
277 yield 2 1abcdefghijklmnopqrst
279 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst
280 async def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst
281 return d 1abcdefghijklmnopqrst
283 with provider.scope(base_dep, override_dep): 1abcdefghijklmnopqrst
284 assert await func() == 2 1abcdefghijklmnopqrst
287@pytest.mark.anyio 1abcdefghijklmnopqrst
288async def test_async_override_context_with_undefined_generator( 1abcdefghijklmnopqrst
289 provider: Provider,
290) -> None:
291 async def base_dep() -> AsyncGenerator[int, None]: 1abcdefghijklmnopqrst
292 raise NotImplementedError
294 async def override_dep() -> AsyncGenerator[int, None]: 1abcdefghijklmnopqrst
295 yield 2 1abcdefghijklmnopqrst
297 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst
298 async def func(d=Depends(base_dep)): 1abcdefghijklmnopqrst
299 return d 1abcdefghijklmnopqrst
301 with provider.scope(base_dep, override_dep): 1abcdefghijklmnopqrst
302 assert await func() == 2 1abcdefghijklmnopqrst
305def test_clear_overrides(provider: Provider) -> None: 1abcdefghijklmnopqrst
306 def base_dep() -> int: 1abcdefghijklmnopqrst
307 return 1 1abcdefghijklmnopqrst
309 def override_dep() -> int: 1abcdefghijklmnopqrst
310 return 2 1abcdefghijklmnopqrst
312 @inject(dependency_provider=provider) 1abcdefghijklmnopqrst
313 def func(d: Annotated[int, Depends(base_dep)]) -> int: 1abcdefghijklmnopqrst
314 return d 1abcdefghijklmnopqrst
316 provider.override(base_dep, override_dep) 1abcdefghijklmnopqrst
318 assert len(provider.overrides) == 1 1abcdefghijklmnopqrst
319 assert len(provider.dependencies) == 1 1abcdefghijklmnopqrst
320 assert func() == 2 # override dependency called 1abcdefghijklmnopqrst
322 provider.clear() 1abcdefghijklmnopqrst
324 assert len(provider.overrides) == 0 1abcdefghijklmnopqrst
325 assert len(provider.dependencies) == 1 1abcdefghijklmnopqrst
326 assert func() == 1 # original dep called 1abcdefghijklmnopqrst