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

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

Правило задаёт рекомендации по настройке Pyright и basedpyright для Python-проектов. Пригодится, если хотите сделать проверку типов строже и последовательнее.

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

Что делает pyright

Правило охватывает настройки проекта, строгую диагностику и аннотации типов. Оно советует хранить конфигурацию в pyrightconfig.json или pyproject.toml, начинать с базовых проверок и ужесточать их постепенно. Для аргументов функций предлагаются абстрактные типы, а для возвращаемых значений — конкретные.

Отдельные рекомендации касаются Any, комментариев подавления ошибок, псевдонимов типов и синтаксиса подсказок типов. Для библиотек без встроенных типов предусмотрена папка stubs/; правило также советует использовать виртуальные окружения и настроить Pyright на их поиск. Строгие проверки требуют исправить существующие ошибки или явно задать исключения.

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

  • настроить проверки типов на уровне проекта
  • сократить использование Any в аннотациях
  • указывать код ошибки при подавлении диагностики
  • объявлять псевдонимы типов через TypeAlias
  • поддерживать заглушки типов для библиотек

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

  • Настрой проверки типов в моём Python-проекте по правилу pyright.
  • Проверь аннотации в src и предложи, где заменить Any на object.
  • Подскажи, как настроить pyrightconfig.json для строгой проверки типов.

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

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

.cursor/rules/pyright.mdc

Во frontmatter: description, globs, alwaysApply

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

Вопросы о pyright

Как установить правило pyright в Cursor?

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

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

Оно задаёт практики настройки Pyright и basedpyright, включая строгую диагностику, аннотации функций и управление заглушками типов.

Как правило предлагает работать с Any?

Используйте object, когда конкретный тип объекта не важен, а Any оставляйте для случаев, когда выразить намерение точнее нельзя.

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

pyright.mdc · CC0-1.0
---
description: This guide provides definitive, actionable best practices for configuring and using pyright (and basedpyright) to ensure robust, type-safe Python codebases in 2025.
globs: **/*.py
---
# pyright Best Practices

`pyright` is the definitive static type-checker for modern Python, essential for "type-first" development. We standardize on `basedpyright` for its stricter defaults and enhanced diagnostics, ensuring our codebase remains consistently type-clean.

## 1. Project-Wide Configuration

Always define a `pyrightconfig.json` (or `[tool.pyright]` in `pyproject.toml`) at your project root. Commit this file to version control to guarantee consistent type-checking across all developer environments and CI pipelines. Start with a baseline, fix errors, then progressively tighten rules.

❌ **BAD**: No config file, relying on default `pyright` behavior.
✅ **GOOD**: Explicitly define your type-checking rules.

```json
// pyrightconfig.json
{
  "include": ["src"],
  "exclude": ["**/node_modules", "**/__pycache__"],
  "reportMissingTypeStubs": "error",
  "reportAny": "error", // basedpyright specific, essential
  "reportExplicitAny": "error", // basedpyright specific, essential
  "reportImplicitRelativeImport": "error", // basedpyright specific
  "reportInvalidCast": "error", // basedpyright specific
  "reportUnsafeMultipleInheritance": "error", // basedpyright specific
  "strict": [ // Apply strict mode to specific directories
    "src/core",
    "src/models"
  ],
  "stubPath": "stubs" // Where custom type stubs live
}
```

## 2. Strict Diagnostics & `Any` Usage

Embrace strict diagnostics to eliminate implicit `Any` types and enforce explicit type declarations. `basedpyright`'s `reportAny` and `reportExplicitAny` are non-negotiable for maintaining a truly type-safe codebase.

### Prefer `object` over `Any`

Use `object` when a function truly accepts *any* Python object, but its type isn't relevant to its operation (e.g., for `str()`, `repr()`, or passing to a callback that ignores its argument). Reserve `Any` only when the type system *cannot* express the intent.

❌ **BAD**: Overusing `Any`, disabling type checks.

```python
from typing import Any

def process_data(data: Any) -> Any: # Type checking effectively disabled
    print(str(data))
    return data
```

✅ **GOOD**: Using `object` for truly generic inputs, `Any` only when necessary.

```python
from typing import Any, Callable

def process_data(data: object) -> object: # Accepts any object, but type is known
    print(str(data))
    return data

def call_callback(cb: Callable[[int], object]) -> None: # Callback return value is ignored
    cb(42)

# Use Any only when absolutely no specific type can be expressed
def dynamic_factory(name: str) -> Any: # Return type is truly unknown at static analysis time
    if name == "int": return 1
    if name == "str": return "hello"
    return None
```

### Explicit Error Codes for Ignores

Always specify the exact `pyright` error code when suppressing diagnostics. This prevents accidentally ignoring other, unrelated errors on the same line and improves maintainability. `basedpyright`'s `reportIgnoreCommentWithoutRule` enforces this.

❌ **BAD**: Generic type ignores.

```python
import os

# type: ignore # What error is this ignoring?
path = os.getenv("MY_PATH")
```

✅ **GOOD**: Specific `pyright` ignore comments.

```python
import os
from typing import cast

# pyright: ignore[reportGeneralTypeIssues] # path might be None, but we know it's not
path = cast(str, os.getenv("MY_PATH"))
```

## 3. Type Aliases

Declare type aliases using `TypeAlias` for clarity and consistency. This makes the intent explicit and helps `pyright` understand your type definitions.

❌ **BAD**: Implicit type aliases.

```python
MyDict = dict[str, int] # Looks like an alias, but isn't explicitly declared
```

✅ **GOOD**: Explicit `TypeAlias` declaration.

```python
from typing import TypeAlias

MyDict: TypeAlias = dict[str, int]
```

## 4. Arguments and Return Types

### Function Arguments: Prefer Protocols and Abstract Types

For function arguments, use abstract base classes (ABCs) or protocols (`Iterable`, `Sequence`, `Mapping`) to maximize flexibility and reusability. This allows your functions to accept a wider range of compatible types.

❌ **BAD**: Overly specific argument types.

```python
def process_items(items: list[str]) -> None: # Only accepts lists
    for item in items:
        print(item)
```

✅ **GOOD**: Using abstract types for arguments.

```python
from collections.abc import Iterable

def process_items(items: Iterable[str]) -> None: # Accepts any iterable
    for item in items:
        print(item)
```

### Function Return Types: Prefer Concrete Types

For return values, prefer concrete types (`list`, `dict`) unless you are returning an instance of a protocol or an abstract base class where the specific implementation is not relevant to the caller. Avoid union return types that force `isinstance()` checks.

❌ **BAD**: Abstract return types for concrete implementations, or complex unions.

```python
from collections.abc import MutableMapping
from typing import Union

def create_mapping() -> MutableMapping[str, int]: # Returns a dict, but declared as MutableMapping
    return {"a": 1, "b": 2}

def get_value(key: str) -> Union[str, int, None]: # Forces caller to check types
    if key == "name": return "Alice"
    if key == "age": return 30
    return None
```

✅ **GOOD**: Concrete return types, simpler unions when necessary.

```python
def create_mapping() -> dict[str, int]: # Clearly returns a dict
    return {"a": 1, "b": 2}

def get_value(key: str) -> str | int | None: # Shorthand union, still explicit
    if key == "name": return "Alice"
    if key == "age": return 30
    return None
```

## 5. Modern Type Hint Syntax

Always use the modern shorthand syntax for unions (`X | Y`) and built-in generics (`list[int]`). Place `None` as the last element in a union.

❌ **BAD**: Legacy `typing` module syntax.

```python
from typing import Union, Optional, List, Dict, Type

def foo(x: Union[str, int]) -> None: ...
def bar(x: Optional[str]) -> Optional[int]: ...
def baz(items: List[str]) -> Dict[str, Type[object]]: ...
```

✅ **GOOD**: Modern, concise type hint syntax.

```python
def foo(x: str | int) -> None: ...
def bar(x: str | None) -> int | None: ...
def baz(items: list[str]) -> dict[str, type[object]]: ...
```

## 6. Type Stubs Management

Maintain a `stubs/` directory for custom type stubs for libraries that lack them. Configure `pyright` to use this path and enable `reportMissingTypeStubs`. Keep third-party libraries updated to leverage inline types.

```json
// pyrightconfig.json
{
  // ... other settings ...
  "stubPath": "stubs",
  "reportMissingTypeStubs": "error"
}
```

## 7. Virtual Environments

Always use virtual environments. Configure `pyright` to correctly locate your environment to ensure it uses the installed package types.

```json
// pyrightconfig.json
{
  // ... other settings ...
  "venvPath": ".venv", // Path to directory containing virtual environments
  "venv": "my_project_env" // Name of the virtual environment
}
```

## 8. Packaging for Type Safety

For libraries, include a `py.typed` marker file in your package to signal that it provides type information. This allows downstream users to benefit from your type annotations.

```
# my_library/py.typed
# This file can be empty. Its presence indicates the package is type-annotated.
```

## 9. Testing Approaches & CI Integration

Integrate `pyright` into your CI pipeline and pre-commit hooks. This ensures that type errors are caught early, preventing them from reaching the main branch.

```yaml
# .pre-commit-config.yaml
- repo: https://github.com/DetachHead/basedpyright
  rev: v1.1.407 # Pin to a specific basedpyright version
  hooks:
    - id: basedpyright
      args: ["--ignoreexternal"] # Only check our code, not third-party libs
```

## 10. Common Pitfalls & `basedpyright` Gotchas

`basedpyright` introduces critical rules to prevent common typing mistakes:

### `reportImplicitRelativeImport`

Bans ambiguous relative imports that work as scripts but fail as modules.

❌ **BAD**: Implicit relative import.

```python
# my_package/module_a.py
def func_a(): pass

# my_package/module_b.py
import module_a # Fails when my_package is imported
```

✅ **GOOD**: Explicit relative import.

```python
# my_package/module_b.py
from . import module_a # Correct relative import
```

### `reportInvalidCast`

Prevents casting to types that have no overlap with the original, indicating a logical error.

❌ **BAD**: Invalid cast.

```python
from typing import cast

value: int = 10
str_value = cast(str, value) # int can never be str
```

✅ **GOOD**: Valid cast (e.g., narrowing a union).

```python
from typing import cast

value: int | None = None
if value is not None:
    int_value = cast(int, value) # Valid: narrowing from int | None to int
```

### `reportUnsafeMultipleInheritance`

Discourages multiple inheritance when base classes have `__init__` or `__new__` methods, as it's often unsafe and unpredictable.

❌ **BAD**: Unsafe multiple inheritance.

```python
class BaseA:
    def __init__(self): super().__init__()
class BaseB:
    def __init__(self): pass

class MyClass(BaseA, BaseB): # Unsafe: __init__ chain is ambiguous
    pass
```

✅ **GOOD**: Avoid unsafe multiple inheritance or use mixins carefully.

```python
class BaseA:
    def __init__(self): pass

class MyMixin:
    def do_something(self): pass

class MyClass(BaseA, MyMixin): # Safe if mixin doesn't have __init__
    def __init__(self):
        super().__init__()
```

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

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

Каталог правил IDE →
pyright-lsp официальный Anthropic Подключает языковой сервер Pyright к Claude Code для статической проверки типов. Помогает находить ошибки в файлах Python с расширениями .py и .pyi. ★ 44 967звёзд репо 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

Весь набор →
pytorch Задаёт стандарты чистого кода для PyTorch в Python-проектах. Направляет Cursor разделять архитектуру на модули, выносить тензоры на устройства и отключать градиенты при инференсе. ★ 3 580звёзд репо python Правило задаёт стиль и практики для Python-файлов в Cursor. Оно пригодится, когда нужно поддерживать единый формат, типизацию, структуру проекта и тесты. ★ 3 580звёзд репо pytest Правило задаёт команде единый стиль тестов на pytest: структуру проекта, фикстуры, параметризацию и моки. Пригодится, когда тесты пишут несколько человек. ★ 3 580звёзд репо pyside Задаёт стандарты разработки интерфейсов на PySide6 в Cursor. Помогает разделять логику и графику через Qt Designer или связку QML с бэкендом. ★ 3 580звёзд репо pyramid Правило для Cursor с набором практик по Python-фреймворку Pyramid: структура проекта, конфигурация, транзакции и предикаты представлений. ★ 3 580звёзд репо pyqt Правило для Cursor задаёт стандарты разработки PyQt-приложений на Python: запрещает менять сгенерированный интерфейс вручную и требует выносить тяжёлые вычисления из потока интерфейса. ★ 3 580звёзд репо pylint Правило задаёт рекомендации по настройке Pylint и проверке Python-кода: от docstring и имён до обработки исключений и сложности функций. ★ 3 580звёзд репо pygame Правило для Cursor задаёт каркас Pygame-проекта: один UIManager, фиксированный шаг времени, вёрстка на якорях и темы в JSON. ★ 3 580звёзд репо

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

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