Coverage for fastapi/concurrency.py: 100%
18 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
1from contextlib import asynccontextmanager as asynccontextmanager 1abcdefg
2from typing import AsyncGenerator, ContextManager, TypeVar 1abcdefg
4import anyio.to_thread 1abcdefg
5from anyio import CapacityLimiter 1abcdefg
6from starlette.concurrency import iterate_in_threadpool as iterate_in_threadpool # noqa 1abcdefg
7from starlette.concurrency import run_in_threadpool as run_in_threadpool # noqa 1abcdefg
8from starlette.concurrency import ( # noqa 1abcdefg
9 run_until_first_complete as run_until_first_complete,
10)
12_T = TypeVar("_T") 1abcdefg
15@asynccontextmanager 1abcdefg
16async def contextmanager_in_threadpool( 1abcdefg
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) 2@b[b]b(bv w x y ^b_b`b{bz |bA B C }bD E F ~bacbcccdcecfcgchcicjckclcmcncG ocH )bZbpcI 0bqcJ K L rch i sctcuc1bM N O P vcwcxcycQ zcR S T AcU V W BcCcDcEcFcGcHcIcJcKcLcMcNcOcPcX QcY 2b3bRcZ 4bSc0 1 2 Tcj k UcVcWc*b3 4 5 6 XcYcZc0c7 1c8 9 ! 2c# $ % 3c4c5c6c7c8c9c!c#c$c%c'c(c)c*c' +c( +b5b,c) 6b-c* + , .cl m /c:c;c,b- . / : =c?c@c[c; ]c= ? @ ^c[ ] ^ _c`c{c|c}c~cadbdcdddedfdgdhdid_ jd` -b7bkd{ 8bld| } ~ mdn o ndodpd.babbbcbdbqdrdsdtdebudfbgbhbvdibjbkbwdxdydzdAdBdCdDdEdFdGdHdIdJdKdlbLdmb/b9bMdnb!bNdobpbqbOdp q PdQdRd:brbsbtbubSdTdUdVdvbWdwbxbybXdzbAbBbYdZd0d1d2d3d4d5d6d7d8d9d!d#d$dCb%dDb;b#b'dEb$b(dFbGbHb)dr s *d+d,d=bIbJbKbLb-d.d/d:dMb;dNbObPb=dQbRbSb?d@d[d]d^d_d`d{d|d}d~daebecedeTbeeUb?b%bfeVb'bgeWbXbYbhet u
26 try: 2@b[b]b(bv w x y ^b_b`b{bz |bA B C }bD E F ~bacbcccdcecfcgchcicjckclcmcncG ocH )bZbpcI 0bqcJ K L rch i sctcuc1bM N O P vcwcxcycQ zcR S T AcU V W BcCcDcEcFcGcHcIcJcKcLcMcNcOcPcX QcY 2b3bRcZ 4bSc0 1 2 Tcj k UcVcWc*b3 4 5 6 XcYcZc0c7 1c8 9 ! 2c# $ % 3c4c5c6c7c8c9c!c#c$c%c'c(c)c*c' +c( +b5b,c) 6b-c* + , .cl m /c:c;c,b- . / : =c?c@c[c; ]c= ? @ ^c[ ] ^ _c`c{c|c}c~cadbdcdddedfdgdhdid_ jd` -b7bkd{ 8bld| } ~ mdn o ndodpd.babbbcbdbqdrdsdtdebudfbgbhbvdibjbkbwdxdydzdAdBdCdDdEdFdGdHdIdJdKdlbLdmb/b9bMdnb!bNdobpbqbOdp q PdQdRd:brbsbtbubSdTdUdVdvbWdwbxbybXdzbAbBbYdZd0d1d2d3d4d5d6d7d8d9d!d#d$dCb%dDb;b#b'dEb$b(dFbGbHb)dr s *d+d,d=bIbJbKbLb-d.d/d:dMb;dNbObPb=dQbRbSb?d@d[d]d^d_d`d{d|d}d~daebecedeTbeeUb?b%bfeVb'bgeWbXbYbhet u
27 yield await run_in_threadpool(cm.__enter__) 2@b[b]b(bv w x y ^b_b`b{bz |bA B C }bD E F ~bacbcccdcecfcgchcicjckclcmcncG ocH )bZbpcI 0bqcJ K L rch i sctcuc1bM N O P vcwcxcycQ zcR S T AcU V W BcCcDcEcFcGcHcIcJcKcLcMcNcOcPcX QcY 2b3bRcZ 4bSc0 1 2 Tcj k UcVcWc*b3 4 5 6 XcYcZc0c7 1c8 9 ! 2c# $ % 3c4c5c6c7c8c9c!c#c$c%c'c(c)c*c' +c( +b5b,c) 6b-c* + , .cl m /c:c;c,b- . / : =c?c@c[c; ]c= ? @ ^c[ ] ^ _c`c{c|c}c~cadbdcdddedfdgdhdid_ jd` -b7bkd{ 8bld| } ~ mdn o ndodpd.babbbcbdbqdrdsdtdebudfbgbhbvdibjbkbwdxdydzdAdBdCdDdEdFdGdHdIdJdKdlbLdmb/b9bMdnb!bNdobpbqbOdp q PdQdRd:brbsbtbubSdTdUdVdvbWdwbxbybXdzbAbBbYdZd0d1d2d3d4d5d6d7d8d9d!d#d$dCb%dDb;b#b'dEb$b(dFbGbHb)dr s *d+d,d=bIbJbKbLb-d.d/d:dMb;dNbObPb=dQbRbSb?d@d[d]d^d_d`d{d|d}d~daebecedeTbeeUb?b%bfeVb'bgeWbXbYbhet u
28 except Exception as e: 2(bv w x y z A B C D E F G H )bZbI 0bJ K L h i 1bM N O P Q R S T U V W X Y 2b3bZ 4b0 1 2 j k *b3 4 5 6 7 8 9 ! # $ % ' ( +b5b) 6b* + , l m ,b- . / : ; = ? @ [ ] ^ _ ` -b7b{ 8b| } ~ n o .babbbcbdbebfbgbhbibjbkblbmb/b9bnb!bobpbqbp q :brbsbtbubvbwbxbybzbAbBbCbDb;b#bEb$bFbGbHbr s =bIbJbKbLbMbNbObPbQbRbSbTbUb?b%bVb'bWbXbYbt u
29 ok = bool( 2(bv w x y z A B C D E F G H )bZbI 0bJ K L h i 1bM N O P Q R S T U V W X Y 2b3bZ 4b0 1 2 j k *b3 4 5 6 7 8 9 ! # $ % ' ( +b5b) 6b* + , l m ,b- . / : ; = ? @ [ ] ^ _ ` -b7b{ 8b| } ~ n o .babbbcbdbebfbgbhbibjbkblbmb/b9bnb!bobpbqbp q :brbsbtbubvbwbxbybzbAbBbCbDb;b#bEb$bFbGbHbr s =bIbJbKbLbMbNbObPbQbRbSbTbUb?b%bVb'bWbXbYbt u
30 await anyio.to_thread.run_sync(
31 cm.__exit__, type(e), e, e.__traceback__, limiter=exit_limiter
32 )
33 )
34 if not ok: 2v w x y z A B C D E F G H ZbI 0bJ K L h i M N O P Q R S T U V W X Y 3bZ 4b0 1 2 j k 3 4 5 6 7 8 9 ! # $ % ' ( 5b) 6b* + , l m - . / : ; = ? @ [ ] ^ _ ` 7b{ 8b| } ~ n o abbbcbdbebfbgbhbibjbkblbmb9bnb!bobpbqbp q rbsbtbubvbwbxbybzbAbBbCbDb#bEb$bFbGbHbr s IbJbKbLbMbNbObPbQbRbSbTbUb%bVb'bWbXbYbt u
35 raise e 2v w x y z A B C D E F G H I J K L h i 1bM N O P Q R S T U V W X Y 2bZ 0 1 2 j k 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , l m - . / : ; = ? @ [ ] ^ _ ` { | } ~ n o abbbcbdbebfbgbhbibjbkblbmbnbobpbqbp q rbsbtbubvbwbxbybzbAbBbCbDbEbFbGbHbr s IbJbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbt u
36 else:
37 await anyio.to_thread.run_sync( 2@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrch i sctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcj k UcVcWcXcYcZc0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(c)c*c+c,c-c.cl m /c:c;c=c?c@c[c]c^c_c`c{c|c}c~cadbdcdddedfdgdhdidjdkdldmdn o ndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdp q PdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8d9d!d#d$d%d'd(d)dr s *d+d,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegehet u
38 cm.__exit__, None, None, None, limiter=exit_limiter
39 )