Coverage for fastapi/concurrency.py: 100%
18 statements
« prev ^ index » next coverage.py v7.6.1, created at 2025-09-29 03:37 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2025-09-29 03:37 +0000
1from contextlib import asynccontextmanager as asynccontextmanager 1abcdef
2from typing import AsyncGenerator, ContextManager, TypeVar 1abcdef
4import anyio.to_thread 1abcdef
5from anyio import CapacityLimiter 1abcdef
6from starlette.concurrency import iterate_in_threadpool as iterate_in_threadpool # noqa 1abcdef
7from starlette.concurrency import run_in_threadpool as run_in_threadpool # noqa 1abcdef
8from starlette.concurrency import ( # noqa 1abcdef
9 run_until_first_complete as run_until_first_complete,
10)
12_T = TypeVar("_T") 1abcdef
15@asynccontextmanager 1abcdef
16async def contextmanager_in_threadpool( 1abcdef
17 cm: ContextManager[_T],
18) -> AsyncGenerator[_T, None]:
19 # blocking __exit__ from running waiting on a free thread
20 # can create race conditions/deadlocks if the context manager itself
21 # has its own internal pool (e.g. a database connection pool)
22 # to avoid this we let __exit__ run without a capacity limit
23 # since we're creating a new limiter for each call, any non-zero limit
24 # works (1 is arbitrary)
25 exit_limiter = CapacityLimiter(1) 23b4b5bTbs t u v 6b7b8b9bw !bx y z #bA B C $bD %bE UbFb'bF Gb(bG H I g h )b*b+bHbJ K L M ,b-b.b/bN :bO P Q ;bR S T =bU ?bV IbJb@bW Kb[bX Y Z i j ]b^b_bVb0 1 2 3 `b{b|b}b4 ~b5 6 7 ac8 9 ! bc# cc$ WbLbdc% Mbec' ( ) k l fcgchcXb* + , - icjckclc. mc/ : ; nc= ? @ oc[ pc] YbNbqc^ Obrc_ ` { m n sctcucZb| } ~ abvcwcxcycbbzccbdbebAcfbgbhbBcibCcjb0bPbDckbQbEclbmbnbo p FcGcHc1bobpbqbrbIcJcKcLcsbMctbubvbNcwbxbybOczbPcAb2bRbQcBbSbRcCbDbEbq r
26 try: 23b4b5bTbs t u v 6b7b8b9bw !bx y z #bA B C $bD %bE UbFb'bF Gb(bG H I g h )b*b+bHbJ K L M ,b-b.b/bN :bO P Q ;bR S T =bU ?bV IbJb@bW Kb[bX Y Z i j ]b^b_bVb0 1 2 3 `b{b|b}b4 ~b5 6 7 ac8 9 ! bc# cc$ WbLbdc% Mbec' ( ) k l fcgchcXb* + , - icjckclc. mc/ : ; nc= ? @ oc[ pc] YbNbqc^ Obrc_ ` { m n sctcucZb| } ~ abvcwcxcycbbzccbdbebAcfbgbhbBcibCcjb0bPbDckbQbEclbmbnbo p FcGcHc1bobpbqbrbIcJcKcLcsbMctbubvbNcwbxbybOczbPcAb2bRbQcBbSbRcCbDbEbq r
27 yield await run_in_threadpool(cm.__enter__) 23b4b5bTbs t u v 6b7b8b9bw !bx y z #bA B C $bD %bE UbFb'bF Gb(bG H I g h )b*b+bHbJ K L M ,b-b.b/bN :bO P Q ;bR S T =bU ?bV IbJb@bW Kb[bX Y Z i j ]b^b_bVb0 1 2 3 `b{b|b}b4 ~b5 6 7 ac8 9 ! bc# cc$ WbLbdc% Mbec' ( ) k l fcgchcXb* + , - icjckclc. mc/ : ; nc= ? @ oc[ pc] YbNbqc^ Obrc_ ` { m n sctcucZb| } ~ abvcwcxcycbbzccbdbebAcfbgbhbBcibCcjb0bPbDckbQbEclbmbnbo p FcGcHc1bobpbqbrbIcJcKcLcsbMctbubvbNcwbxbybOczbPcAb2bRbQcBbSbRcCbDbEbq r
28 except Exception as e: 2Tbs t u v w x y z A B C D E UbFbF GbG H I g h HbJ K L M N O P Q R S T U V IbJbW KbX Y Z i j Vb0 1 2 3 4 5 6 7 8 9 ! # $ WbLb% Mb' ( ) k l Xb* + , - . / : ; = ? @ [ ] YbNb^ Ob_ ` { m n Zb| } ~ abbbcbdbebfbgbhbibjb0bPbkbQblbmbnbo p 1bobpbqbrbsbtbubvbwbxbybzbAb2bRbBbSbCbDbEbq r
29 ok = bool( 2Tbs t u v w x y z A B C D E UbFbF GbG H I g h HbJ K L M N O P Q R S T U V IbJbW KbX Y Z i j Vb0 1 2 3 4 5 6 7 8 9 ! # $ WbLb% Mb' ( ) k l Xb* + , - . / : ; = ? @ [ ] YbNb^ Ob_ ` { m n Zb| } ~ abbbcbdbebfbgbhbibjb0bPbkbQblbmbnbo p 1bobpbqbrbsbtbubvbwbxbybzbAb2bRbBbSbCbDbEbq r
30 await anyio.to_thread.run_sync(
31 cm.__exit__, type(e), e, e.__traceback__, limiter=exit_limiter
32 )
33 )
34 if not ok: 2s t u v w x y z A B C D E FbF GbG H I g h J K L M N O P Q R S T U V JbW KbX Y Z i j 0 1 2 3 4 5 6 7 8 9 ! # $ Lb% Mb' ( ) k l * + , - . / : ; = ? @ [ ] Nb^ Ob_ ` { m n | } ~ abbbcbdbebfbgbhbibjbPbkbQblbmbnbo p obpbqbrbsbtbubvbwbxbybzbAbRbBbSbCbDbEbq r
35 raise e 2s t u v w x y z A B C D E F G H I g h HbJ K L M N O P Q R S T U V IbW X Y Z i j 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) k l * + , - . / : ; = ? @ [ ] ^ _ ` { m n | } ~ abbbcbdbebfbgbhbibjbkblbmbnbo p obpbqbrbsbtbubvbwbxbybzbAbBbCbDbEbq r
36 else:
37 await anyio.to_thread.run_sync( 23b4b5b6b7b8b9b!b#b$b%b'b(bg h )b*b+b,b-b.b/b:b;b=b?b@b[bi j ]b^b_b`b{b|b}b~bacbcccdceck l fcgchcicjckclcmcncocpcqcrcm n sctcucvcwcxcyczcAcBcCcDcEco p FcGcHcIcJcKcLcMcNcOcPcQcRcq r
38 cm.__exit__, None, None, None, limiter=exit_limiter
39 )