Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A Python coroutine function is a specialized function defined using the async def syntax that enables asynchronous, non-blocking execution. Unlike standard synchronous functions, invoking a coroutine function does not immediately execute its internal block of code. Instead, it returns a coroutine object. This object is typically driven to completion by an asynchronous event loop, though at the language level, it is technically driven by calling its .send() method (e.g., .send(None)).

Syntax and Instantiation

A coroutine function is declared using the async modifier before the def keyword. Inside the function body, the await keyword is used to declare suspension points.
import asyncio


# This is a coroutine function
async def process_data():
    # The 'await' keyword yields control back to the event loop
    await asyncio.sleep(1)
    return "Success"


# Calling the function returns a coroutine object; it does NOT execute the body
coro_object = process_data()
print(type(coro_object))  # <class 'coroutine'>


# Cleanly discard the unawaited coroutine to prevent a RuntimeWarning

# when the object is garbage collected by the Python interpreter.
coro_object.close()

Execution Mechanics

To execute the code within a coroutine function, the resulting coroutine object is usually awaited or scheduled as a Task within an event loop.
  1. The await Expression: When the Python interpreter encounters an await expression inside a coroutine function, it suspends the execution of that specific coroutine. Under the hood, await delegates to the .send() method of the awaited object.
  2. Yielding Control: The suspension yields control of the thread back to the caller (typically the event loop), allowing the loop to execute other pending coroutines or tasks.
  3. Resumption: Once the awaited operation resolves, the suspended coroutine function is resumed from the exact point it was paused, preserving its local state and variables.
import asyncio

async def compute_value():
    await asyncio.sleep(1) # Suspension point 1
    return 42

async def main():
    # Awaiting the coroutine object drives it to completion
    # and extracts the underlying return value.
    result = await compute_value() # Suspension point 2
    print(result)


# asyncio.run() initializes the event loop and executes the top-level coroutine
asyncio.run(main())

Technical Rules and Constraints

  • Awaitables: The await keyword can only be applied to awaitable objects. In Python, the primary awaitables are coroutine objects, asyncio.Task objects, and asyncio.Future objects.
  • Scope Restriction: The await, async for, and async with keywords are syntactically restricted and can only be used within the body of an async def coroutine function. Using them in a standard def function raises a SyntaxError.
  • Return Behavior: While a standard function returns the value specified in its return statement, a coroutine function always returns a coroutine object. The value specified in the return statement becomes the result of the await expression when the coroutine object is eventually evaluated.
  • Generators vs. Coroutines: Under the hood, Python coroutines are built upon the generator infrastructure. However, async def strictly separates coroutines from standard generators (yield). A coroutine function cannot contain a yield statement unless it is specifically designed as an asynchronous generator.
Master Python with Deep Grasping Methodology!Learn More