docs: 添加异步生成器安全规则到 AGENTS.md 和 project_rules.md
Deploy to Production / deploy (push) Failing after 6s Details

This commit is contained in:
chiguyong 2026-06-18 16:35:09 +08:00
parent b4ba65b9ca
commit a2c6af54b8
2 changed files with 40 additions and 0 deletions

View File

@ -0,0 +1,39 @@
# 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:**
```python
async def subscribe(self):
if self._closed:
return # BUG: makes this a coroutine when _closed=True
...
yield event
```
**Correct — use `return; yield` pattern:**
```python
async def subscribe(self):
if self._closed:
return
yield # Makes this always an async generator
...
yield event
```
**Correct — restructure to avoid early return:**
```python
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 -q` before committing
- Known failing test (unrelated): `test_rewoo_agent_yaml_loads` — skip if needed

View File

@ -10,6 +10,7 @@
- Expert names validated with `_EXPERT_NAME_RE = re.compile(r"^[a-zA-Z0-9_-]{1,64}$")` - Expert names validated with `_EXPERT_NAME_RE = re.compile(r"^[a-zA-Z0-9_-]{1,64}$")`
- HandoffTransport queues bounded (`maxsize=1024`), close uses sentinel pattern - HandoffTransport queues bounded (`maxsize=1024`), close uses sentinel pattern
- Frontend: Vue 3 + TypeScript + Ant Design Vue, Pinia stores, no `require()` calls - Frontend: Vue 3 + TypeScript + Ant Design Vue, Pinia stores, no `require()` calls
- **Async generator safety**: Never use early `return` before the first `yield` in `async def` — use `return; yield` pattern instead (see `.trae/rules/project_rules.md`)
## Tech Stack ## Tech Stack