Coverage for tests/test_dependency_wrapped.py: 100%
223 statements
« prev ^ index » next coverage.py v7.6.1, created at 2025-12-04 08:29 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2025-12-04 08:29 +0000
1import inspect 1abcdefg
2import sys 1abcdefg
3from functools import wraps 1abcdefg
4from typing import AsyncGenerator, Generator 1abcdefg
6import pytest 1abcdefg
7from fastapi import Depends, FastAPI 1abcdefg
8from fastapi.concurrency import iterate_in_threadpool, run_in_threadpool 1abcdefg
9from fastapi.testclient import TestClient 1abcdefg
11if sys.version_info >= (3, 13): # pragma: no cover 1abcdefg
12 from inspect import iscoroutinefunction 1fg
13else: # pragma: no cover
14 from asyncio import iscoroutinefunction 1abcde
17def noop_wrap(func): 1abcdefg
18 @wraps(func) 1abcdefg
19 def wrapper(*args, **kwargs): 1abcdefg
20 return func(*args, **kwargs) 1hijklmn
22 return wrapper 1abcdefg
25def noop_wrap_async(func): 1abcdefg
26 if inspect.isgeneratorfunction(func): 1abcdefg
28 @wraps(func) 1abcdefg
29 async def gen_wrapper(*args, **kwargs): 1abcdefg
30 async for item in iterate_in_threadpool(func(*args, **kwargs)): 1hijklmn
31 yield item 1hijklmn
33 return gen_wrapper 1abcdefg
35 elif inspect.isasyncgenfunction(func): 1abcdefg
37 @wraps(func) 1abcdefg
38 async def async_gen_wrapper(*args, **kwargs): 1abcdefg
39 async for item in func(*args, **kwargs): 1hijklmn
40 yield item 1hijklmn
42 return async_gen_wrapper 1abcdefg
44 @wraps(func) 1abcdefg
45 async def wrapper(*args, **kwargs): 1abcdefg
46 if inspect.isroutine(func) and iscoroutinefunction(func): 1hijklmn
47 return await func(*args, **kwargs) 1hijklmn
48 if inspect.isclass(func): 1hijklmn
49 return await run_in_threadpool(func, *args, **kwargs) 1hijklmn
50 dunder_call = getattr(func, "__call__", None) # noqa: B004 1hijklmn
51 if iscoroutinefunction(dunder_call): 1hijklmn
52 return await dunder_call(*args, **kwargs) 1hijklmn
53 return await run_in_threadpool(func, *args, **kwargs) 1hijklmn
55 return wrapper 1abcdefg
58class ClassInstanceDep: 1abcdefg
59 def __call__(self): 1abcdefg
60 return True 1hijklmn
63class_instance_dep = ClassInstanceDep() 1abcdefg
64wrapped_class_instance_dep = noop_wrap(class_instance_dep) 1abcdefg
65wrapped_class_instance_dep_async_wrapper = noop_wrap_async(class_instance_dep) 1abcdefg
68class ClassInstanceGenDep: 1abcdefg
69 def __call__(self): 1abcdefg
70 yield True 1hijklmn
73class_instance_gen_dep = ClassInstanceGenDep() 1abcdefg
74wrapped_class_instance_gen_dep = noop_wrap(class_instance_gen_dep) 1abcdefg
77class ClassInstanceWrappedDep: 1abcdefg
78 @noop_wrap 1abcdefg
79 def __call__(self): 1abcdefg
80 return True 1hijklmn
83class_instance_wrapped_dep = ClassInstanceWrappedDep() 1abcdefg
86class ClassInstanceWrappedAsyncDep: 1abcdefg
87 @noop_wrap_async 1abcdefg
88 def __call__(self): 1abcdefg
89 return True 1hijklmn
92class_instance_wrapped_async_dep = ClassInstanceWrappedAsyncDep() 1abcdefg
95class ClassInstanceWrappedGenDep: 1abcdefg
96 @noop_wrap 1abcdefg
97 def __call__(self): 1abcdefg
98 yield True 1hijklmn
101class_instance_wrapped_gen_dep = ClassInstanceWrappedGenDep() 1abcdefg
104class ClassInstanceWrappedAsyncGenDep: 1abcdefg
105 @noop_wrap_async 1abcdefg
106 def __call__(self): 1abcdefg
107 yield True 1hijklmn
110class_instance_wrapped_async_gen_dep = ClassInstanceWrappedAsyncGenDep() 1abcdefg
113class ClassDep: 1abcdefg
114 def __init__(self): 1abcdefg
115 self.value = True 1hijklmn
118wrapped_class_dep = noop_wrap(ClassDep) 1abcdefg
119wrapped_class_dep_async_wrapper = noop_wrap_async(ClassDep) 1abcdefg
122class ClassInstanceAsyncDep: 1abcdefg
123 async def __call__(self): 1abcdefg
124 return True 1hijklmn
127class_instance_async_dep = ClassInstanceAsyncDep() 1abcdefg
128wrapped_class_instance_async_dep = noop_wrap(class_instance_async_dep) 1abcdefg
129wrapped_class_instance_async_dep_async_wrapper = noop_wrap_async( 1abcdefg
130 class_instance_async_dep
131)
134class ClassInstanceAsyncGenDep: 1abcdefg
135 async def __call__(self): 1abcdefg
136 yield True 1hijklmn
139class_instance_async_gen_dep = ClassInstanceAsyncGenDep() 1abcdefg
140wrapped_class_instance_async_gen_dep = noop_wrap(class_instance_async_gen_dep) 1abcdefg
143class ClassInstanceAsyncWrappedDep: 1abcdefg
144 @noop_wrap 1abcdefg
145 async def __call__(self): 1abcdefg
146 return True 1hijklmn
149class_instance_async_wrapped_dep = ClassInstanceAsyncWrappedDep() 1abcdefg
152class ClassInstanceAsyncWrappedAsyncDep: 1abcdefg
153 @noop_wrap_async 1abcdefg
154 async def __call__(self): 1abcdefg
155 return True 1hijklmn
158class_instance_async_wrapped_async_dep = ClassInstanceAsyncWrappedAsyncDep() 1abcdefg
161class ClassInstanceAsyncWrappedGenDep: 1abcdefg
162 @noop_wrap 1abcdefg
163 async def __call__(self): 1abcdefg
164 yield True 1hijklmn
167class_instance_async_wrapped_gen_dep = ClassInstanceAsyncWrappedGenDep() 1abcdefg
170class ClassInstanceAsyncWrappedGenAsyncDep: 1abcdefg
171 @noop_wrap_async 1abcdefg
172 async def __call__(self): 1abcdefg
173 yield True 1hijklmn
176class_instance_async_wrapped_gen_async_dep = ClassInstanceAsyncWrappedGenAsyncDep() 1abcdefg
178app = FastAPI() 1abcdefg
180# Sync wrapper
183@noop_wrap 1abcdefg
184def wrapped_dependency() -> bool: 1abcdefg
185 return True 1hijklmn
188@noop_wrap 1abcdefg
189def wrapped_gen_dependency() -> Generator[bool, None, None]: 1abcdefg
190 yield True 1hijklmn
193@noop_wrap 1abcdefg
194async def async_wrapped_dependency() -> bool: 1abcdefg
195 return True 1hijklmn
198@noop_wrap 1abcdefg
199async def async_wrapped_gen_dependency() -> AsyncGenerator[bool, None]: 1abcdefg
200 yield True 1hijklmn
203@app.get("/wrapped-dependency/") 1abcdefg
204async def get_wrapped_dependency(value: bool = Depends(wrapped_dependency)): 1abcdefg
205 return value 1hijklmn
208@app.get("/wrapped-gen-dependency/") 1abcdefg
209async def get_wrapped_gen_dependency(value: bool = Depends(wrapped_gen_dependency)): 1abcdefg
210 return value 1hijklmn
213@app.get("/async-wrapped-dependency/") 1abcdefg
214async def get_async_wrapped_dependency(value: bool = Depends(async_wrapped_dependency)): 1abcdefg
215 return value 1hijklmn
218@app.get("/async-wrapped-gen-dependency/") 1abcdefg
219async def get_async_wrapped_gen_dependency( 1abcdefg
220 value: bool = Depends(async_wrapped_gen_dependency),
221):
222 return value 1hijklmn
225@app.get("/wrapped-class-instance-dependency/") 1abcdefg
226async def get_wrapped_class_instance_dependency( 1abcdefg
227 value: bool = Depends(wrapped_class_instance_dep),
228):
229 return value 1hijklmn
232@app.get("/wrapped-class-instance-async-dependency/") 1abcdefg
233async def get_wrapped_class_instance_async_dependency( 1abcdefg
234 value: bool = Depends(wrapped_class_instance_async_dep),
235):
236 return value 1hijklmn
239@app.get("/wrapped-class-instance-gen-dependency/") 1abcdefg
240async def get_wrapped_class_instance_gen_dependency( 1abcdefg
241 value: bool = Depends(wrapped_class_instance_gen_dep),
242):
243 return value 1hijklmn
246@app.get("/wrapped-class-instance-async-gen-dependency/") 1abcdefg
247async def get_wrapped_class_instance_async_gen_dependency( 1abcdefg
248 value: bool = Depends(wrapped_class_instance_async_gen_dep),
249):
250 return value 1hijklmn
253@app.get("/class-instance-wrapped-dependency/") 1abcdefg
254async def get_class_instance_wrapped_dependency( 1abcdefg
255 value: bool = Depends(class_instance_wrapped_dep),
256):
257 return value 1hijklmn
260@app.get("/class-instance-wrapped-async-dependency/") 1abcdefg
261async def get_class_instance_wrapped_async_dependency( 1abcdefg
262 value: bool = Depends(class_instance_wrapped_async_dep),
263):
264 return value 1hijklmn
267@app.get("/class-instance-async-wrapped-dependency/") 1abcdefg
268async def get_class_instance_async_wrapped_dependency( 1abcdefg
269 value: bool = Depends(class_instance_async_wrapped_dep),
270):
271 return value 1hijklmn
274@app.get("/class-instance-async-wrapped-async-dependency/") 1abcdefg
275async def get_class_instance_async_wrapped_async_dependency( 1abcdefg
276 value: bool = Depends(class_instance_async_wrapped_async_dep),
277):
278 return value 1hijklmn
281@app.get("/class-instance-wrapped-gen-dependency/") 1abcdefg
282async def get_class_instance_wrapped_gen_dependency( 1abcdefg
283 value: bool = Depends(class_instance_wrapped_gen_dep),
284):
285 return value 1hijklmn
288@app.get("/class-instance-wrapped-async-gen-dependency/") 1abcdefg
289async def get_class_instance_wrapped_async_gen_dependency( 1abcdefg
290 value: bool = Depends(class_instance_wrapped_async_gen_dep),
291):
292 return value 1hijklmn
295@app.get("/class-instance-async-wrapped-gen-dependency/") 1abcdefg
296async def get_class_instance_async_wrapped_gen_dependency( 1abcdefg
297 value: bool = Depends(class_instance_async_wrapped_gen_dep),
298):
299 return value 1hijklmn
302@app.get("/class-instance-async-wrapped-gen-async-dependency/") 1abcdefg
303async def get_class_instance_async_wrapped_gen_async_dependency( 1abcdefg
304 value: bool = Depends(class_instance_async_wrapped_gen_async_dep),
305):
306 return value 1hijklmn
309@app.get("/wrapped-class-dependency/") 1abcdefg
310async def get_wrapped_class_dependency(value: ClassDep = Depends(wrapped_class_dep)): 1abcdefg
311 return value.value 1hijklmn
314@app.get("/wrapped-endpoint/") 1abcdefg
315@noop_wrap 1abcdefg
316def get_wrapped_endpoint(): 1abcdefg
317 return True 1hijklmn
320@app.get("/async-wrapped-endpoint/") 1abcdefg
321@noop_wrap 1abcdefg
322async def get_async_wrapped_endpoint(): 1abcdefg
323 return True 1hijklmn
326# Async wrapper
329@noop_wrap_async 1abcdefg
330def wrapped_dependency_async_wrapper() -> bool: 1abcdefg
331 return True 1hijklmn
334@noop_wrap_async 1abcdefg
335def wrapped_gen_dependency_async_wrapper() -> Generator[bool, None, None]: 1abcdefg
336 yield True 1hijklmn
339@noop_wrap_async 1abcdefg
340async def async_wrapped_dependency_async_wrapper() -> bool: 1abcdefg
341 return True 1hijklmn
344@noop_wrap_async 1abcdefg
345async def async_wrapped_gen_dependency_async_wrapper() -> AsyncGenerator[bool, None]: 1abcdefg
346 yield True 1hijklmn
349@app.get("/wrapped-dependency-async-wrapper/") 1abcdefg
350async def get_wrapped_dependency_async_wrapper( 1abcdefg
351 value: bool = Depends(wrapped_dependency_async_wrapper),
352):
353 return value 1hijklmn
356@app.get("/wrapped-gen-dependency-async-wrapper/") 1abcdefg
357async def get_wrapped_gen_dependency_async_wrapper( 1abcdefg
358 value: bool = Depends(wrapped_gen_dependency_async_wrapper),
359):
360 return value 1hijklmn
363@app.get("/async-wrapped-dependency-async-wrapper/") 1abcdefg
364async def get_async_wrapped_dependency_async_wrapper( 1abcdefg
365 value: bool = Depends(async_wrapped_dependency_async_wrapper),
366):
367 return value 1hijklmn
370@app.get("/async-wrapped-gen-dependency-async-wrapper/") 1abcdefg
371async def get_async_wrapped_gen_dependency_async_wrapper( 1abcdefg
372 value: bool = Depends(async_wrapped_gen_dependency_async_wrapper),
373):
374 return value 1hijklmn
377@app.get("/wrapped-class-instance-dependency-async-wrapper/") 1abcdefg
378async def get_wrapped_class_instance_dependency_async_wrapper( 1abcdefg
379 value: bool = Depends(wrapped_class_instance_dep_async_wrapper),
380):
381 return value 1hijklmn
384@app.get("/wrapped-class-instance-async-dependency-async-wrapper/") 1abcdefg
385async def get_wrapped_class_instance_async_dependency_async_wrapper( 1abcdefg
386 value: bool = Depends(wrapped_class_instance_async_dep_async_wrapper),
387):
388 return value 1hijklmn
391@app.get("/wrapped-class-dependency-async-wrapper/") 1abcdefg
392async def get_wrapped_class_dependency_async_wrapper( 1abcdefg
393 value: ClassDep = Depends(wrapped_class_dep_async_wrapper),
394):
395 return value.value 1hijklmn
398@app.get("/wrapped-endpoint-async-wrapper/") 1abcdefg
399@noop_wrap_async 1abcdefg
400def get_wrapped_endpoint_async_wrapper(): 1abcdefg
401 return True 1hijklmn
404@app.get("/async-wrapped-endpoint-async-wrapper/") 1abcdefg
405@noop_wrap_async 1abcdefg
406async def get_async_wrapped_endpoint_async_wrapper(): 1abcdefg
407 return True 1hijklmn
410client = TestClient(app) 1abcdefg
413@pytest.mark.parametrize( 1abcdefg
414 "route",
415 [
416 "/wrapped-dependency/",
417 "/wrapped-gen-dependency/",
418 "/async-wrapped-dependency/",
419 "/async-wrapped-gen-dependency/",
420 "/wrapped-class-instance-dependency/",
421 "/wrapped-class-instance-async-dependency/",
422 "/wrapped-class-instance-gen-dependency/",
423 "/wrapped-class-instance-async-gen-dependency/",
424 "/class-instance-wrapped-dependency/",
425 "/class-instance-wrapped-async-dependency/",
426 "/class-instance-async-wrapped-dependency/",
427 "/class-instance-async-wrapped-async-dependency/",
428 "/class-instance-wrapped-gen-dependency/",
429 "/class-instance-wrapped-async-gen-dependency/",
430 "/class-instance-async-wrapped-gen-dependency/",
431 "/class-instance-async-wrapped-gen-async-dependency/",
432 "/wrapped-class-dependency/",
433 "/wrapped-endpoint/",
434 "/async-wrapped-endpoint/",
435 "/wrapped-dependency-async-wrapper/",
436 "/wrapped-gen-dependency-async-wrapper/",
437 "/async-wrapped-dependency-async-wrapper/",
438 "/async-wrapped-gen-dependency-async-wrapper/",
439 "/wrapped-class-instance-dependency-async-wrapper/",
440 "/wrapped-class-instance-async-dependency-async-wrapper/",
441 "/wrapped-class-dependency-async-wrapper/",
442 "/wrapped-endpoint-async-wrapper/",
443 "/async-wrapped-endpoint-async-wrapper/",
444 ],
445)
446def test_class_dependency(route): 1abcdefg
447 response = client.get(route) 1hijklmn
448 assert response.status_code == 200, response.text 1hijklmn
449 assert response.json() is True 1hijklmn