Async
async def, await, and the Task[T] / Future[T] types parse and type-check.
Basic shape
async def number() -> i32:
return 42
async def combine() -> i32:
a = await number()
b = await number()
return a + b- Calling an
async defdoes not return its declared type — it returns aTask[T]whereTis the declared return type. awaitunwraps aTask[T]back toT.awaitmay only appear inside anasync def; using it in a plain function is a compile error.- An
async defmay itself be awaited, or run from anasync main.
async def main(argv: list[str]) -> i32:
print(await combine())
return 0The result type propagates through await, so the usual typing rules apply:
async def fetch_name() -> str:
return "sere"
async def greet() -> str:
name: str = await fetch_name() # typed str, not Any
return "hello " + nameArgument typing
Arguments are checked against the declared parameter types, not the task:
async def scale(value: i32, factor: i32 = 2) -> i32:
return value * factor
async def use() -> i32:
return await scale(3, factor=4) # 12An async def main is the entry point for an async program. Error handling is
unchanged — try / except / finally work across await, and defer bodies
still run while an exception unwinds.
Not implemented
Some constructs parse but are rejected rather than silently miscompiled:
| Construct | Status |
|---|---|
yield / generator functions | not implemented — use a nested def or a list |
keyword-only parameters after *args | not implemented |
global / nonlocal | not implemented (nested def closures work) |
| lambda capture of enclosing locals | not implemented — use a nested def |
Incomplete lowering reports NotImplementedError with the source location
instead of generating wrong code.
See also
- functions.md —
def, defaults, callable types. - exceptions.md — error handling.
- ../language.md — reference summary.