mirror of https://github.com/astral-sh/ruff
2.3 KiB
2.3 KiB
async / await
Basic
async def retrieve() -> int:
return 42
async def main():
result = await retrieve()
reveal_type(result) # revealed: int
Generic async functions
from typing import TypeVar
T = TypeVar("T")
async def persist(x: T) -> T:
return x
async def f(x: int):
result = await persist(x)
reveal_type(result) # revealed: int
Use cases
Future
import asyncio
import concurrent.futures
def blocking_function() -> int:
return 42
async def main():
loop = asyncio.get_event_loop()
with concurrent.futures.ThreadPoolExecutor() as pool:
result = await loop.run_in_executor(pool, blocking_function)
# TODO: should be `int`
reveal_type(result) # revealed: Unknown
asyncio.Task
import asyncio
async def f() -> int:
return 1
async def main():
task = asyncio.create_task(f())
result = await task
# TODO: this should be `int`
reveal_type(result) # revealed: Unknown
asyncio.gather
import asyncio
async def task(name: str) -> int:
return len(name)
async def main():
(a, b) = await asyncio.gather(
task("A"),
task("B"),
)
# TODO: these should be `int`
reveal_type(a) # revealed: Unknown
reveal_type(b) # revealed: Unknown
Under the hood
[environment]
python-version = "3.12" # Use 3.12 to be able to use PEP 695 generics
Let's look at the example from the beginning again:
async def retrieve() -> int:
return 42
When we look at the signature of this function, we see that it actually returns a CoroutineType:
reveal_type(retrieve) # revealed: def retrieve() -> CoroutineType[Any, Any, int]
The expression await retrieve() desugars into a call to the __await__ dunder method on the
CoroutineType object, followed by a yield from. Let's first see the return type of __await__:
reveal_type(retrieve().__await__()) # revealed: Generator[Any, None, int]
We can see that this returns a Generator that yields Any, and eventually returns int. For the
final type of the await expression, we retrieve that third argument of the Generator type:
from typing import Generator
def _():
result = yield from retrieve().__await__()
reveal_type(result) # revealed: int