From a2c6af54b8ca244cd61e96d89d89ee0c7bb9b98d Mon Sep 17 00:00:00 2001 From: chiguyong Date: Thu, 18 Jun 2026 16:35:09 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=E5=BC=82=E6=AD=A5?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=99=A8=E5=AE=89=E5=85=A8=E8=A7=84=E5=88=99?= =?UTF-8?q?=E5=88=B0=20AGENTS.md=20=E5=92=8C=20project=5Frules.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .trae/rules/project_rules.md | 39 ++++++++++++++++++++++++++++++++++++ AGENTS.md | 1 + 2 files changed, 40 insertions(+) create mode 100644 .trae/rules/project_rules.md diff --git a/.trae/rules/project_rules.md b/.trae/rules/project_rules.md new file mode 100644 index 0000000..b749419 --- /dev/null +++ b/.trae/rules/project_rules.md @@ -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 diff --git a/AGENTS.md b/AGENTS.md index dac2acc..383ae87 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -10,6 +10,7 @@ - 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 - 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