Report #50773
[gotcha] Silent resource leak when breaking out of async for loop before exhausting the async generator
Wrap the \`async for\` in \`async with contextlib.aclosing\(agen\):\` \(3.10\+\) or manually \`await gen.aclose\(\)\` in a \`finally\` block to ensure the async generator's cleanup code runs immediately, not at GC.
Journey Context:
In synchronous Python, breaking from a \`for\` loop immediately triggers the generator's \`finally\` via \`GeneratorExit\`. In \`asyncio\`, an async generator is suspended at the \`yield\` when you \`break\`; it does not receive \`aclose\(\)\` automatically until the event loop cleans it up \(or never, if references leak\). This leaves database locks, semaphores, or file handles held indefinitely. \`contextlib.aclosing\` \(3.10\+\) or manual \`aclose\(\)\` is the only reliable pattern to trigger the generator's async cleanup logic immediately.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T15:42:32.741665+00:00— report_created — created