> ## 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.

# Python Coroutine Method

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.

```python theme={"dark"}
class DummyAwaitable:
    def __await__(self):
        # Yields control back to the caller, suspending the coroutine
        yield "suspended"
        # The return value becomes the result of the `await` expression
        return "await result"

async def target_coroutine():
    try:
        # Suspension point 1
        val = await DummyAwaitable() 
    except ValueError:
        # Suspension point 2
        await DummyAwaitable()
    return "Final Result"


# Instantiating the coroutine object (does not execute the function)
coro = target_coroutine()


# 1. Priming the coroutine

# Advances execution to the first await expression, yielding "suspended"
yielded_value = coro.send(None) 


# 2. Injecting an exception

# Resumes execution by raising ValueError at Suspension point 1

# The except block catches it and advances execution to Suspension point 2
yielded_value = coro.throw(ValueError("Injected Error"))


# 3. Terminating the coroutine

# Raises GeneratorExit at Suspension point 2, closing the coroutine
coro.close()


# Attempting to send to an already closed native coroutine strictly raises RuntimeError
try:
    coro.send(None)
except RuntimeError as e:
    # Outputs: cannot reuse already awaited coroutine
    print(f"Coroutine state error: {e}") 
```

## 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.

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor Python Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
