1.1 KiB
1.1 KiB
Project Rules
Python Async Generator Safety
When writing async generator functions (async def with yield), NEVER use early return before the first yield. This causes Python to treat the function as a coroutine instead of an async generator, resulting in 'async for' requires an object with __aiter__ method, got coroutine errors at runtime.
Wrong:
async def subscribe(self):
if self._closed:
return # BUG: makes this a coroutine when _closed=True
...
yield event
Correct — use return; yield pattern:
async def subscribe(self):
if self._closed:
return
yield # Makes this always an async generator
...
yield event
Correct — restructure to avoid early return:
async def subscribe(self):
if not self._closed:
...
yield event
This applies to ALL async generator functions in the codebase. When adding an early exit path to any async def that contains yield, always ensure the yield is reachable or add a return; yield guard.
Testing
- Run
python3 -m pytest tests/unit/ -x -qbefore committing