python-docs-readme-async-snippet
Problem: READMEs often show async code with await at module top level (valid only in the Python REPL, where await works at the top level). Copy-pasting such a snippet into file.py and running python file.py raises SyntaxError: 'await' outside function, because top-level await is not allowed in script/module code.
Broken README snippet (REPL-only, fails as a script):
import asyncio
async def fetch_data(name: str) -> str:
await asyncio.sleep(0.1)
return f"data for {name}"
result = await fetch_data("example")
print(result)
$ python3 /tmp/x.py
File "/tmp/x.py", line 7
result = await fetch_data("example")
^^^^^^^^^^^^^^^^^^^^^^^^^^^
SyntaxError: 'await' outside function
Fix: move the async logic into an async def main(), call it via asyncio.run(main()), and guard it with if __name__ == "__main__": so the file works both as a script and as an importable module.
Fixed README snippet (runs with python file.py):
import asyncio
async def fetch_data(name: str) -> str:
await asyncio.sleep(0.1)
return f"data for {name}"
async def main():
result = await fetch_data("example")
print(result)
if __name__ == "__main__":
asyncio.run(main())
Key points:
- async def main() is the coroutine that awaits the other coroutines.
- asyncio.run(main()) creates the event loop, runs main() to completion, and closes the loop — it also handles the loop-creation detail that loop.run_until_complete requires.
- The __name__ == "__main__" guard prevents main() from auto-running when the module is imported (e.g., from a test or another script), and makes the snippet safe to reuse.
This pattern generalizes when the snippet needs CLI arguments or to await multiple coroutines:
import asyncio
import sys
async def worker(n):
await asyncio.sleep(0.01)
return n * 2
async def main():
n = int(sys.argv[1]) if len(sys.argv) > 1 else 3
print(await worker(n))
if __name__ == "__main__":
asyncio.run(main())
The same rule applies to any async README snippet regardless of library (httpx, aiohttp, websockets, etc.): never await at module top level in a file meant to be run with python file.py.
The README at `~/README.md` contains the corrected code block. I extracted it **verbatim** (not typed by hand) using awk to grab everything between the ` ```python ` fences, wrote it to `/tmp/x.py`, and ran it.
1. **Broken snippet reproduced:** original top-level-await block extracted verbatim → `python3 /tmp/x.py` → `SyntaxError: 'await' outside function`, exit code **1**. (Confirms the bug.)
2. **Fixed snippet extracted verbatim from README → `/tmp/x.py` → `python3 /tmp/x.py` → prints `data for example`, exit code **0**. (Confirms the AC: extraction verbatim + exit 0.)
3. **Compile check:** `python3 -m py_compile /tmp/x.py` → `COMPILE_OK` (no syntax errors).
4. **Import safety (edge case):** importing `/tmp/x.py` as a module via `importlib` produced no output — `main()` is not auto-executed thanks to the `__name__` guard. Exit 0.
5. **Generalization (edge case):** `main(args)` variant with `sys.argv` ran with `python3 /tmp/argv_demo.py 21` → printed `42`, exit 0.
6. **REPL parity (edge case):** the same coroutine invoked with `asyncio.run()` (equivalent to interactive top-level `await`) → `data for example`, exit 0. The fix does not break REPL-style usage.
7. **Verbatim extraction proof:** extraction was done with `awk '/^```python$/{f=1;next} /^```$/{f=0} f' README.md > /tmp/x.py`, so the executed code is exactly the README block — no transcription drift.
**Test environment:** Python 3.14.4 (`/usr/bin/python3`), Linux.
---{"model": "deepseek-v4-flash", "problem_class": "python-docs-readme-async-snippet", "result": "passed", "tests": 6}