> ## 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 Async For Loop

An asynchronous `for` loop (`async for`) is a control flow statement designed to iterate over asynchronous iterables. It allows the Python event loop to suspend the execution of the current coroutine while waiting for the next item to be yielded, thereby preventing blocking operations during iteration.

## Syntax

```python theme={"dark"}
async for target in async_iterable:
    # Execute loop body
```

## The Asynchronous Iterator Protocol

The `async for` statement operates strictly on objects that implement the Asynchronous Iterator Protocol (introduced in PEP 492). This protocol requires two specific dunder (double underscore) methods:

1. `__aiter__(self)`: Must return an asynchronous iterator object.
2. `__anext__(self)`: Must return an *awaitable* (typically a coroutine) that resolves to the next value in the sequence. When the iteration is exhausted, this awaitable must raise a `StopAsyncIteration` exception.

## Execution Mechanics

When the Python interpreter encounters an `async for` loop, it performs the following sequence of operations under the hood:

1. It calls `type(async_iterable).__aiter__(async_iterable)` to obtain the asynchronous iterator.
2. It calls `type(async_iterator).__anext__(async_iterator)` to get an awaitable.
3. It implicitly `await`s the awaitable returned by `__anext__()`. This is the point where context switching can occur, yielding control back to the event loop.
4. Upon resolution of the awaitable, it assigns the resulting value to the `target` variable.
5. It executes the loop body.
6. It repeats steps 2-5 until the `__anext__()` awaitable raises `StopAsyncIteration`, which the loop catches silently to terminate execution.

## Implementation Example: Custom Async Iterable

To visualize the mechanics without relying on external libraries, here is a custom class implementing the protocol:

```python theme={"dark"}
import asyncio

class AsyncCounter:
    def __init__(self, limit):
        self.limit = limit
        self.current = 0

    def __aiter__(self):
        # Returns the asynchronous iterator (self)
        return self

    async def __anext__(self):
        # Returns an awaitable that yields the next value or raises StopAsyncIteration
        if self.current >= self.limit:
            raise StopAsyncIteration
        
        await asyncio.sleep(0.1)  # Non-blocking suspension point
        self.current += 1
        return self.current

async def main():
    # The async for loop consumes the AsyncCounter
    async for number in AsyncCounter(3):
        print(number)

asyncio.run(main())
```

## Asynchronous Generators

Writing classes with `__aiter__` and `__anext__` is verbose. Python provides Asynchronous Generators as a syntactic shortcut. If an `async def` function contains a `yield` statement, it is classified as an asynchronous generator *function*. Calling this function returns an asynchronous generator object (the iterator), which natively implements the asynchronous iterator protocol and can be consumed directly by `async for`.

```python theme={"dark"}
import asyncio

async def async_generator(limit):
    for i in range(limit):
        await asyncio.sleep(0.1)
        yield i + 1

async def main():
    async for number in async_generator(3):
        print(number)

asyncio.run(main())
```

## Technical Constraints

* **Scope:** `async for` can only be used inside an `async def` function (a coroutine) or within an asynchronous comprehension. Using it in a synchronous function will raise a `SyntaxError`.
* **Type Restriction:** You cannot use `async for` on standard synchronous iterables (like `list`, `tuple`, or standard generators). The target object *must* implement `__aiter__`. Attempting to use `async for` on a standard list will raise a `TypeError: 'async for' requires an object with __aiter__ method`.

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