Python › Async Generators & Async Context Managers

How does an async generator interact with try/finally for guaranteed cleanup, similar to regular generators?

Intermediate

Answer

Just like a regular generator, wrapping the yield in a try/finally inside an async generator guarantees the finally block runs when the generator is exhausted, explicitly closed via aclose(), or garbage collected — ensuring resources like an open connection are properly released even if the consumer stops iterating early.
async def read_stream(conn):
    try:
        while True:
            chunk = await conn.read_chunk()
            if not chunk:
                break
            yield chunk
    finally:
        await conn.close()  # runs even if consumer breaks out of 'async for' early
Real-world example Ensuring a network connection or file handle used inside an async generator is properly closed even if the consumer stops early.

Common follow-ups: What method would you call to explicitly close an async generator without fully iterating it?