Skip to main content
A Python coroutine method is a built-in function bound to a native coroutine object (defined using async def) that controls its execution state. These methods allow the caller to resume execution, inject data, raise exceptions, or terminate the coroutine by interacting with the iterator returned by the underlying awaitable’s __await__() method. Native coroutines implement the collections.abc.Coroutine protocol and expose specific methods to manage their lifecycle across suspension points (await expressions).

Core Coroutine Methods

coroutine.send(value) Starts or resumes the execution of the coroutine.
  • When a coroutine is first started, it must be primed by calling send(None).
  • If the coroutine is suspended at an await expression, the await keyword delegates to the underlying awaitable’s __await__ iterator. The value passed to send(value) is injected into this underlying iterator. The await expression itself evaluates to the iterator’s final return value (extracted from StopIteration.value), not the value passed to send().
  • The method returns the next value yielded by the coroutine’s internal iterator, or raises StopIteration if the coroutine returns. The StopIteration.value attribute contains the coroutine’s final return value.
coroutine.throw(exc) Raises the specified exception instance at the exact point where the coroutine is currently suspended.
  • If the coroutine catches the exception and yields a new value, that value is returned to the caller.
  • If the coroutine does not catch the exception, or if it raises a different exception, the exception propagates back to the caller.
  • If the coroutine exits cleanly after catching the exception, it raises StopIteration.
coroutine.close() Forces the coroutine to terminate.
  • It raises a GeneratorExit exception at the current suspension point.
  • If the coroutine catches GeneratorExit and attempts to yield a new value, a RuntimeError is raised.
  • If the coroutine handles the exception and exits, or if it was already closed, the method returns silently.
coroutine.__await__() Returns an iterator that implements the coroutine protocol. This magic method is invoked internally when the coroutine is used in an await expression, allowing the caller to interface with the coroutine’s send(), throw(), and close() methods.

Syntax and Internal Mechanics

While these methods are typically abstracted away by an event loop, they can be invoked directly to manually step through a coroutine’s state machine. To demonstrate manual stepping without an active event loop, a custom dummy awaitable is required.

State Transitions

Coroutine methods directly manipulate the internal state of the coroutine object, transitioning it through four primary phases:
  1. CORO_CREATED: The coroutine object is instantiated but send(None) has not yet been called.
  2. CORO_RUNNING: The coroutine is actively executing on the thread (cannot be stepped concurrently).
  3. CORO_SUSPENDED: The coroutine has yielded control back to the caller via an await expression and is waiting for send() or throw().
  4. CORO_CLOSED: The coroutine has returned a value, raised an unhandled exception, or close() has been called.
Tired of Poor Python Skills? Fix That With Deep Grasping!Learn More