11from __future__ import annotations
22
3- import sys
43import asyncio
54import functools
6- import contextvars
7- from typing import Any , TypeVar , Callable , Awaitable
5+ from typing import TypeVar , Callable , Awaitable
86from typing_extensions import ParamSpec
97
108import anyio
1513T_ParamSpec = ParamSpec ("T_ParamSpec" )
1614
1715
18- if sys .version_info >= (3 , 9 ):
19- _asyncio_to_thread = asyncio .to_thread
20- else :
21- # backport of https://docs.python.org/3/library/asyncio-task.html#asyncio.to_thread
22- # for Python 3.8 support
23- async def _asyncio_to_thread (
24- func : Callable [T_ParamSpec , T_Retval ], / , * args : T_ParamSpec .args , ** kwargs : T_ParamSpec .kwargs
25- ) -> Any :
26- """Asynchronously run function *func* in a separate thread.
27-
28- Any *args and **kwargs supplied for this function are directly passed
29- to *func*. Also, the current :class:`contextvars.Context` is propagated,
30- allowing context variables from the main thread to be accessed in the
31- separate thread.
32-
33- Returns a coroutine that can be awaited to get the eventual result of *func*.
34- """
35- loop = asyncio .events .get_running_loop ()
36- ctx = contextvars .copy_context ()
37- func_call = functools .partial (ctx .run , func , * args , ** kwargs )
38- return await loop .run_in_executor (None , func_call )
39-
40-
4116async def to_thread (
4217 func : Callable [T_ParamSpec , T_Retval ], / , * args : T_ParamSpec .args , ** kwargs : T_ParamSpec .kwargs
4318) -> T_Retval :
4419 if sniffio .current_async_library () == "asyncio" :
45- return await _asyncio_to_thread (func , * args , ** kwargs )
20+ return await asyncio . to_thread (func , * args , ** kwargs )
4621
4722 return await anyio .to_thread .run_sync (
4823 functools .partial (func , * args , ** kwargs ),
@@ -53,10 +28,7 @@ async def to_thread(
5328def asyncify (function : Callable [T_ParamSpec , T_Retval ]) -> Callable [T_ParamSpec , Awaitable [T_Retval ]]:
5429 """
5530 Take a blocking function and create an async one that receives the same
56- positional and keyword arguments. For python version 3.9 and above, it uses
57- asyncio.to_thread to run the function in a separate thread. For python version
58- 3.8, it uses locally defined copy of the asyncio.to_thread function which was
59- introduced in python 3.9.
31+ positional and keyword arguments.
6032
6133 Usage:
6234
0 commit comments