77from typing import Any , TypeVar , Callable , Awaitable
88from typing_extensions import ParamSpec
99
10+ import anyio
11+ import sniffio
12+ import anyio .to_thread
13+
1014T_Retval = TypeVar ("T_Retval" )
1115T_ParamSpec = ParamSpec ("T_ParamSpec" )
1216
1317
1418if sys .version_info >= (3 , 9 ):
15- to_thread = asyncio .to_thread
19+ _asyncio_to_thread = asyncio .to_thread
1620else :
1721 # backport of https://docs.python.org/3/library/asyncio-task.html#asyncio.to_thread
1822 # for Python 3.8 support
19- async def to_thread (
23+ async def _asyncio_to_thread (
2024 func : Callable [T_ParamSpec , T_Retval ], / , * args : T_ParamSpec .args , ** kwargs : T_ParamSpec .kwargs
2125 ) -> Any :
2226 """Asynchronously run function *func* in a separate thread.
@@ -34,6 +38,17 @@ async def to_thread(
3438 return await loop .run_in_executor (None , func_call )
3539
3640
41+ async def to_thread (
42+ func : Callable [T_ParamSpec , T_Retval ], / , * args : T_ParamSpec .args , ** kwargs : T_ParamSpec .kwargs
43+ ) -> T_Retval :
44+ if sniffio .current_async_library () == "asyncio" :
45+ return await _asyncio_to_thread (func , * args , ** kwargs )
46+
47+ return await anyio .to_thread .run_sync (
48+ functools .partial (func , * args , ** kwargs ),
49+ )
50+
51+
3752# inspired by `asyncer`, https://github.com/tiangolo/asyncer
3853def asyncify (function : Callable [T_ParamSpec , T_Retval ]) -> Callable [T_ParamSpec , Awaitable [T_Retval ]]:
3954 """
0 commit comments