К основному содержанию
правило

trio — правило для Cursor: советы по Python и установка

Правило задаёт рекомендации по асинхронному Python-коду с Trio: управление задачами, отмена, ввод-вывод, типы и тесты. Подключите его, если проект использует Trio.

Установить в Cursor · Вручную: положить файлы Все способы и платформы ↓
.cursor/rules/trio.mdc
Открыть на GitHub

Что делает trio

Правило применяется к файлам **/*.py. Оно направляет агента использовать trio.open_nursery() для связанных задач, явно управлять отменой и не блокировать цикл событий синхронными вызовами. Для блокирующей функции в примерах предлагается trio.to_thread.run_sync.

Также описаны аннотации типов, проверки через mypy --strict и flake8-async или Ruff с правилами ASYNC, а для тестов — trio.testing. Если библиотека должна работать с разными асинхронными средами, правило советует использовать примитивы AnyIO. Синхронный ввод-вывод внутри async def остановит выполнение других задач до завершения вызова.

Какие задачи решает

  • управлять жизненным циклом параллельных задач через nursery
  • обрабатывать отмену и очищать ресурсы
  • выносить блокирующие вызовы из цикла событий
  • добавлять типы к асинхронным функциям
  • проверять Trio-код с помощью trio.testing

Примеры запросов агенту

  • Перепиши эту функцию так, чтобы задачи запускались внутри trio.open_nursery().
  • Добавь корректную обработку отмены и очистку ресурсов в этой операции Trio.
  • Проверь асинхронный код на блокирующие вызовы и добавь подходящие типы.

Как установить trio

Вручную: положить файлы

.cursor/rules/trio.mdc

Во frontmatter: description, globs, alwaysApply

По шагам, с командами для каждой платформы: Cursor rules: файлы .mdc, четыре режима и замена .cursorrules

Вопросы о trio

Как установить trio в Cursor?

Добавьте файл правила в проект по пути .cursor/rules/trio.mdc.

Что делает правило trio?

Оно задаёт рекомендации для асинхронного Python-кода с Trio: структурированное управление задачами, отмену, неблокирующий ввод-вывод, типизацию и тестирование.

Как правило предлагает работать с блокирующими вызовами?

Для синхронной функции оно показывает trio.to_thread.run_sync, который запускает её в отдельном потоке. Для сетевого ввода-вывода перечислены trio.socket, trio-http-client и httpx с бэкендом Trio.

Исходный текст

trio.mdc · CC0-1.0
---
description: This guide enforces best practices for using Trio, Python's structured concurrency library, ensuring robust, type-safe, and performant asynchronous applications.
globs: **/*.py
---
# trio Best Practices

Trio is the definitive choice for new async-first Python projects in 2025, prioritizing usability and correctness through structured concurrency. Adhere to these guidelines for maintainable, high-performance code.

## 1. Structured Concurrency with Nurseries

Always manage concurrent tasks within a `trio.open_nursery()`. This guarantees that all spawned tasks complete or are cancelled together, preventing hidden task leaks and simplifying error handling.

❌ **BAD: Fire-and-forget tasks**
```python
import trio

async def background_task():
    await trio.sleep(100) # This task will run indefinitely, unmanaged

async def main():
    # No nursery, no explicit management
    trio.lowlevel.spawn_system_task(background_task)
    print("Main task exiting, background task is orphaned.")

trio.run(main)
```

✅ **GOOD: Tasks within a nursery**
```python
import trio

async def managed_task(task_id: int):
    print(f"Task {task_id} started.")
    await trio.sleep(1)
    print(f"Task {task_id} finished.")

async def main():
    async with trio.open_nursery() as nursery:
        nursery.start_soon(managed_task, 1)
        nursery.start_soon(managed_task, 2)
    print("All tasks in nursery completed.")

trio.run(main)
```

## 2. Explicit Cancellation and Timeouts

Trio's cancellation model is robust. Use `cancel_scope` for explicit control over task lifetimes and `trio.Cancelled` for graceful cleanup.

❌ **BAD: Ignoring cancellation or using raw `try...except`**
```python
import trio

async def long_running_operation():
    try:
        await trio.sleep(10)
        print("Operation completed.")
    except Exception: # Too broad, doesn't specifically handle cancellation
        print("Operation failed somehow.")

async def main():
    with trio.move_on_after(0.1) as cancel_scope:
        await long_running_operation()
    if cancel_scope.cancelled_caught:
        print("Operation was cancelled.")

trio.run(main)
```

✅ **GOOD: Handling `trio.Cancelled` for cleanup**
```python
import trio

async def long_running_operation():
    try:
        print("Starting long operation...")
        await trio.sleep(10)
        print("Operation completed.")
    except trio.Cancelled:
        print("Operation was cancelled, performing cleanup.")
        # Perform necessary cleanup here
        raise # Re-raise to propagate cancellation

async def main():
    async with trio.open_nursery() as nursery:
        nursery.start_soon(long_running_operation)
        await trio.sleep(0.1)
        nursery.cancel_scope.cancel() # Explicitly cancel the nursery

trio.run(main)
```

## 3. I/O Hygiene: Never Block the Event Loop

Blocking calls (e.g., `time.sleep()`, synchronous file I/O, `requests.get()`) will starve the event loop and halt all other concurrent tasks. Use Trio-aware alternatives or offload to a thread.

❌ **BAD: Blocking call in an `async def` function**
```python
import time
import trio

async def fetch_data_blocking():
    print("Fetching data (blocking)...")
    time.sleep(2) # Blocks the entire event loop!
    print("Data fetched.")
    return {"data": "example"}

async def main():
    async with trio.open_nursery() as nursery:
        nursery.start_soon(fetch_data_blocking)
        nursery.start_soon(fetch_data_blocking) # These will run sequentially

trio.run(main)
```

✅ **GOOD: Offloading blocking calls with `trio.to_thread.run_sync`**
```python
import time
import trio

def _blocking_fetch_data(): # This is a regular sync function
    print("Fetching data (blocking in thread)...")
    time.sleep(2)
    print("Data fetched in thread.")
    return {"data": "example"}

async def fetch_data_non_blocking():
    return await trio.to_thread.run_sync(_blocking_fetch_data)

async def main():
    async with trio.open_nursery() as nursery:
        nursery.start_soon(fetch_data_non_blocking)
        nursery.start_soon(fetch_data_non_blocking) # These will run concurrently

trio.run(main)
```
For network I/O, use `trio.socket`, `trio-http-client`, or `httpx` (with `trio` backend).

## 4. Type Safety and Linting

Mandate type hints for all `async def` functions, variables, and return types. Use `mypy --strict` and `flake8-async` (or Ruff with `ASYNC` rules) to catch common async-related errors early.

❌ **BAD: Missing type hints, potential runtime errors**
```python
import trio

async def process_item(item): # 'item' has no type hint
    await trio.sleep(0.1)
    return item * 2

async def main():
    result = await process_item("text") # Will fail at runtime if 'item' is str
    print(result)

trio.run(main)
```

✅ **GOOD: Comprehensive type hints**
```python
import trio

async def process_item(item: int) -> int:
    await trio.sleep(0.1)
    return item * 2

async def main():
    result = await process_item(5) # Type checker will catch incorrect usage
    print(result)

trio.run(main)
```
Configure `ruff` to enable `ASYNC` rules (e.g., `select = ["E", "F", "ASYNC"]` in `pyproject.toml`).

## 5. Interoperability with AnyIO

When building libraries or applications that need to be framework-agnostic (e.g., compatible with FastAPI, which uses AnyIO), write your async code using AnyIO primitives. This keeps your codebase portable across Trio, asyncio, and Curio.

```python
# Using AnyIO for portable async code
import anyio

async def do_something_concurrently():
    async with anyio.create_task_group() as tg:
        tg.start_soon(anyio.sleep, 1)
        tg.start_soon(anyio.sleep, 2)
    print("AnyIO tasks completed.")

async def main():
    await do_something_concurrently()

# Run with Trio backend
anyio.run(main, backend="trio")
```

## 6. Testing Approaches

Leverage `trio.testing` for reliable and deterministic tests of your asynchronous code.

```python
import trio
import trio.testing
import pytest

async def worker(value: int) -> int:
    await trio.sleep(0.01)
    return value * 2

@pytest.mark.trio
async def test_worker_doubles_value():
    # Use trio.testing.wait_all_tasks_blocked() for deterministic execution
    async with trio.open_nursery() as nursery:
        send_channel, receive_channel = trio.open_memory_channel(0)
        nursery.start_soon(lambda: nursery.start_soon(worker, 5)) # Example task
        await trio.testing.wait_all_tasks_blocked() # Ensures tasks yield
        # Assertions about task state or results
        assert await worker(3) == 6
```

© sanjeed5 · CC0-1.0 · sanjeed5/awesome-cursor-rules-mdc

Похожие правила IDE

Каталог правил IDE →
winui3 официальный github Правило задаёт рекомендации для WinUI 3 и Windows App SDK: от XAML и потоков до окон и MVVM. Пригодится, чтобы Copilot учитывал особенности настольных приложений Windows. ★ 40 478звёзд репо vue официальный github Правило задаёт Copilot стандарты Vue 3: Composition API, <script setup>, реактивность, Pinia и Vue Router. Пригодится, когда агент пишет компоненты в вашем стиле. ★ 40 478звёзд репо vsixtoolkit официальный github Направляет GitHub Copilot при создании расширений VSIX через библиотеку Community.VisualStudio.Toolkit. Задаёт совместимость с .NET Framework 4.8 и правила потоков. ★ 40 478звёзд репо use-cliche-data-in-docs официальный github Правило помогает писать документацию и примеры с вымышленными данными вместо значений из конфигов, скриптов и запросов. Пригодится при создании и правке документации. ★ 40 478звёзд репо update-docs-on-code-change официальный github Правило для GitHub Copilot, которое напоминает обновлять README.md и документацию, когда меняется код. Пригодится, если доки у вас отстают от реальности. ★ 40 478звёзд репо update-code-from-shorthand официальный github Превращает псевдокод и краткие заметки между маркерами в готовый код. Помогает быстро развернуть черновую логику прямо внутри целевого файла. ★ 40 478звёзд репо

Из того же набора240

Весь набор →
typescript Задаёт стандарты строгой типизации TypeScript для файлов JavaScript и JSX через JSDoc, флаги компилятора и проверки во время выполнения. ★ 3 580звёзд репо typer Правило задаёт структуру CLI на Typer: модульные команды, типизацию через Annotated и настройку entry point. Пригодится, когда вы пишете или рефакторите Python-командную строку. ★ 3 580звёзд репо turbopack Правило для Cursor задаёт, как писать код под Turbopack в Next.js 16+: структура src/, TypeScript, App Router, явные директивы кэша. ★ 3 580звёзд репо trpc Задаёт стандарты построения API на tRPC в файлах TypeScript. Помогает генерировать модульные роутеры, валидацию через Zod и корректные middleware. ★ 3 580звёзд репо transformers Правило для Cursor задаёт стиль работы с библиотекой 🤗 Transformers: модульные модели, типизация, Trainer вместо ручных циклов обучения. ★ 3 580звёзд репо tqdm Файл правил для Cursor, который задаёт агенту единый стиль работы с tqdm: импорты, контекстные менеджеры, вывод в консоль и метрики в постфиксе. ★ 3 580звёзд репо tortoise-orm Правило задаёт рекомендации по работе с Tortoise ORM в Python-проектах: от управления подключениями до пакетных операций и миграций. ★ 3 580звёзд репо tornado Правило для Cursor задаёт стиль кода в Tornado: только async/await для ввода-вывода, полные аннотации типов и один обработчик ошибок на всё приложение. ★ 3 580звёзд репо

Спонсоры проекта

Компании, которые помогают держать аналитику открытой