一键导入
python-async-patterns
Best practices for async Python code, avoiding common pitfalls like await precedence bugs and sync-in-async anti-patterns.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Best practices for async Python code, avoiding common pitfalls like await precedence bugs and sync-in-async anti-patterns.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Help the team document and maintain Architecture Decision Records (ADRs).
Expert guidance on document processing with Docling and audio transcription with Whisper.
Standard for creating technical documentation in this repository. Use this when writing new documentation in docs/ to ensure consistent hierarchy and formatting.
Expert guidance on creating accurate, visually polished Mermaid diagrams for architecture documentation.
Expert guidance on MongoDB implementation for RAG, including aggregation pipelines and search patterns.
Expert guidance on building agents and tools with Pydantic AI.
| name | python-async-patterns |
| description | Best practices for async Python code, avoiding common pitfalls like await precedence bugs and sync-in-async anti-patterns. |
Expert guidance on writing correct and performant async Python code. These patterns prevent common bugs discovered in code reviews.
Use this skill when:
async def functionsProblem: The comma operator has higher precedence than await.
# ❌ WRONG - Returns (coroutine, value) instead of (result, value)
async def search(query: str) -> tuple[list, str]:
return await repository.search(query), query # BUG!
# ✅ CORRECT - Assign result first, then create tuple
async def search(query: str) -> tuple[list, str]:
results = await repository.search(query)
return results, query
Rule: Never use await inside a tuple literal. Always assign the awaited result to a variable first.
Problem: Calling synchronous I/O inside async functions blocks the event loop.
# ❌ WRONG - Blocks event loop
async def save_document(doc: Document) -> str:
result = sync_client.insert(doc) # BLOCKING!
return result.id
# ✅ CORRECT - Wrap with asyncio.to_thread()
import asyncio
async def save_document(doc: Document) -> str:
result = await asyncio.to_thread(
lambda: sync_client.insert(doc)
)
return result.id
Rule: If using a sync library in async code, wrap calls with asyncio.to_thread().
Problem: Return type doesn't match what the function actually returns.
# ❌ WRONG - Says it returns List but actually returns tuple
async def search(query: str) -> List[Match]:
results = await repo.search(query)
return results, query # Actually tuple!
# ✅ CORRECT - Accurate type hint
async def search(query: str) -> tuple[List[Match], str]:
results = await repo.search(query)
return results, query
Rule: Always verify return type matches the actual return value. Use tuple[T1, T2] for tuples.
Problem: Generic exceptions lack context for debugging.
# ❌ WRONG - No context
if not result.data:
raise Exception("Failed to save")
# ✅ CORRECT - Rich context
from src.core.exceptions import DocumentSaveError
if not result.data:
raise DocumentSaveError(
cause="No data returned from insert",
document_id=doc.id
)
Rule: Create domain-specific exceptions that capture relevant context.
| Anti-Pattern | Fix |
|---|---|
return await foo(), bar | Assign first: x = await foo(); return x, bar |
sync_call() in async | Wrap: await asyncio.to_thread(sync_call) |
-> List[T] returns tuple | Fix: -> tuple[List[T], str] |
raise Exception(msg) | Use: raise DomainError(context) |