mcpField
P
pyright

pyright

github.com/bobmatnyc测试与质量78184 次安装15 周前更新
代码仓库

关于 pyright

Pyright 是 Microsoft 开发的 Python 静态类型检查器,适用于需要在项目中检查类型的开发者。它提供可配置的检查严格度、增量监视和 VS Code(Pylance)集成。

主要功能

  1. 01可配置类型检查严格度
  2. 02类型推断与类型收窄
  3. 03VS Code(Pylance)集成
  4. 04监视模式与增量检查
  5. 05生成第三方类型存根

适用场景

  1. 01在提交前检查 Python 类型问题
  2. 02逐步提高旧项目的类型检查严格度
  3. 03在 VS Code 中查看类型诊断
  4. 04为缺少存根的依赖生成类型存根

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/bobmatnyc/claude-mpm-skills --skill pyright

安装后在 Claude Code 中输入/pyright确认已加载。

附带文件metadata.json

详细介绍

Pyright - 快速 Python 类型检查器


progressive_disclosure: entry_point: summary: "Microsoft 推出的快速 Python 类型检查器,集成 VS Code 并支持严格模式" when_to_use: - "需要比 mypy 更快的类型检查时" - "使用 VS Code(Pylance)时" - "需要更严格的类型检查时" - "从 mypy 迁移时" quick_start: - "npm install -g pyright" - "创建 pyrightconfig.json" - "pyright ." token_estimate: entry: 65-80 full: 3500-4500

安装

Node.js(推荐)
# Global installation
npm install -g pyright

# Per-project installation
npm install --save-dev pyright

# Verify installation
pyright --version
VS Code(Pylance)

Pyright 为 Pylance 扩展提供支持:

# Install Pylance extension (includes pyright)
code --install-extension ms-python.vscode-pylance
pip 安装
# Community wrapper
pip install pyright

# Note: Still requires Node.js runtime

配置

pyrightconfig.json
{
  "include": [
    "src"
  ],
  "exclude": [
    "**/node_modules",
    "**/__pycache__",
    ".venv"
  ],
  "typeCheckingMode": "basic",
  "pythonVersion": "3.11",
  "pythonPlatform": "Linux",
  "reportMissingImports": true,
  "reportMissingTypeStubs": false,
  "strictListInference": true,
  "strictDictionaryInference": true,
  "strictSetInference": true
}
类型检查模式

基础模式(默认):

{
  "typeCheckingMode": "basic",
  "reportUnusedImport": "warning",
  "reportUnusedVariable": "warning"
}

标准模式:

{
  "typeCheckingMode": "standard",
  "reportUnknownParameterType": "error",
  "reportUnknownArgumentType": "error",
  "reportUnknownVariableType": "error"
}

严格模式(最高类型安全性):

{
  "typeCheckingMode": "strict",
  "reportPrivateUsage": "error",
  "reportConstantRedefinition": "error",
  "reportIncompatibleMethodOverride": "error",
  "reportIncompatibleVariableOverride": "error",
  "reportUnnecessaryIsInstance": "warning",
  "reportUnnecessaryCast": "warning"
}
单文件配置
# pyright: strict
"""Strict type checking for this file."""

# pyright: basic
"""Basic type checking."""

# pyright: reportGeneralTypeIssues=false
"""Disable specific diagnostics."""

VS Code 集成

settings.json
{
  "python.languageServer": "Pylance",
  "python.analysis.typeCheckingMode": "basic",
  "python.analysis.diagnosticMode": "workspace",
  "python.analysis.autoImportCompletions": true,
  "python.analysis.inlayHints.functionReturnTypes": true,
  "python.analysis.inlayHints.variableTypes": true,
  "python.analysis.completeFunctionParens": true
}
工作区配置
{
  "python.analysis.extraPaths": [
    "./src",
    "./lib"
  ],
  "python.analysis.stubPath": "./typings",
  "python.analysis.diagnosticSeverityOverrides": {
    "reportUnusedImport": "warning",
    "reportUnusedVariable": "warning",
    "reportGeneralTypeIssues": "error"
  }
}

类型检查功能

类型收窄
from typing import Union

def process(value: Union[str, int]) -> str:
    # Pyright narrows type based on isinstance
    if isinstance(value, str):
        return value.upper()  # value is str here
    else:
        return str(value)  # value is int here

# Type guards
from typing import TypeGuard

def is_str_list(val: list[object]) -> TypeGuard[list[str]]:
    return all(isinstance(x, str) for x in val)

def process_list(items: list[object]) -> None:
    if is_str_list(items):
        # items is list[str] here
        print(", ".join(items))
协议支持
from typing import Protocol

class Drawable(Protocol):
    def draw(self) -> None: ...

class Circle:
    def draw(self) -> None:
        print("Drawing circle")

def render(obj: Drawable) -> None:
    obj.draw()

# Works with structural typing
render(Circle())  # ✓ No explicit inheritance needed
TypedDict
from typing import TypedDict, NotRequired

class User(TypedDict):
    name: str
    age: int
    email: NotRequired[str]  # Optional in Python 3.11+

def create_user(data: User) -> None:
    print(data["name"])  # ✓ Type-safe
    # print(data["missing"])  # ✗ Error

user: User = {
    "name": "Alice",
    "age": 30
}  # ✓ email is optional
字面量类型
from typing import Literal

Mode = Literal["read", "write", "append"]

def open_file(mode: Mode) -> None:
    ...

open_file("read")    # ✓
open_file("delete")  # ✗ Error

高级功能

变型与泛型
from typing import TypeVar, Generic, Sequence

T_co = TypeVar("T_co", covariant=True)
T_contra = TypeVar("T_contra", contravariant=True)

class Reader(Generic[T_co]):
    def read(self) -> T_co: ...

class Writer(Generic[T_contra]):
    def write(self, item: T_contra) -> None: ...

# Covariance: Reader[Dog] is subtype of Reader[Animal]
# Contravariance: Writer[Animal] is subtype of Writer[Dog]
ParamSpec
from typing import ParamSpec, TypeVar, Callable

P = ParamSpec("P")
R = TypeVar("R")

def add_logging(f: Callable[P, R]) -> Callable[P, R]:
    def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
        print(f"Calling {f.__name__}")
        return f(*args, **kwargs)
    return wrapper

@add_logging
def greet(name: str, age: int) -> str:
    return f"Hello {name}, {age}"

# Type-safe: greet("Alice", 30)
类型别名
from typing import TypeAlias

# Simple alias
UserId: TypeAlias = int
Username: TypeAlias = str

# Generic alias
from collections.abc import Sequence
Vector: TypeAlias = Sequence[float]

# Complex alias
JSON: TypeAlias = dict[str, "JSON"] | list["JSON"] | str | int | float | bool | None

CI/CD 集成

GitHub Actions
name: Type Check

on: [push, pull_request]

jobs:
  typecheck:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install pyright
        run: npm install -g pyright

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: Run pyright
        run: pyright
Pre-commit 钩子
# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: pyright
        name: pyright
        entry: pyright
        language: node
        types: [python]
        pass_filenames: false
        additional_dependencies: ['[email protected]']
Makefile
.PHONY: typecheck typecheck-strict

typecheck:
	pyright

typecheck-strict:
	pyright --level strict

typecheck-watch:
	pyright --watch

typecheck-stats:
	pyright --stats

从 mypy 迁移

配置映射
{
  "// mypy: disallow_untyped_defs": "reportUntypedFunctionDecorator",
  "// mypy: disallow_any_generics": "reportMissingTypeArgument",
  "// mypy: warn_return_any": "reportUnknownArgumentType",
  "// mypy: strict_equality": "reportUnnecessaryComparison",
  "// mypy: warn_unused_ignores": "reportUnnecessaryTypeIgnoreComment"
}
注释语法
# mypy: ignore-errors
# ↓ pyright equivalent
# pyright: reportGeneralTypeIssues=false

# type: ignore
# ↓ pyright equivalent
# pyright: ignore

# type: ignore[error-code]
# ↓ pyright equivalent
# pyright: ignore[reportGeneralTypeIssues]
渐进式迁移
{
  "typeCheckingMode": "basic",
  "include": ["src/new_module"],
  "exclude": ["src/legacy"],
  "reportMissingImports": true,
  "reportMissingTypeStubs": false
}

性能优化

基准性能
# Create performance baseline
pyright --stats --createstub

# Compare after changes
pyright --stats
监视模式
# Fast incremental checking
pyright --watch

# With specific path
pyright --watch src/
并行检查
{
  "executionEnvironments": [
    {
      "root": "src",
      "pythonVersion": "3.11"
    },
    {
      "root": "tests",
      "pythonVersion": "3.11",
      "extraPaths": ["src"]
    }
  ]
}

常见模式

Optional 处理
from typing import Optional

def get_user(user_id: int) -> Optional[str]:
    return "Alice" if user_id == 1 else None

# Before pyright 1.1.200
user = get_user(1)
if user is not None:
    print(user.upper())

# With pyright type narrowing
user = get_user(1)
if user:  # Narrows to str
    print(user.upper())
联合类型收窄
from typing import Union

def process(value: Union[str, list[str]]) -> str:
    if isinstance(value, list):
        return ", ".join(value)  # value is list[str]
    return value  # value is str
重载
from typing import overload, Literal

@overload
def open_file(path: str, mode: Literal["r"]) -> str: ...

@overload
def open_file(path: str, mode: Literal["rb"]) -> bytes: ...

def open_file(path: str, mode: str) -> str | bytes:
    if mode == "rb":
        return b"binary data"
    return "text data"

# Type-safe usage
text: str = open_file("file.txt", "r")
data: bytes = open_file("file.bin", "rb")
断言函数
from typing import Never

def assert_never(value: Never) -> Never:
    raise AssertionError(f"Unexpected value: {value}")

def handle_status(status: Literal["success", "error"]) -> None:
    if status == "success":
        print("OK")
    elif status == "error":
        print("Failed")
    else:
        assert_never(status)  # Exhaustiveness check

Pyright 与 mypy 对比

性能比较
# Typical project (10K lines)
# mypy: ~5-10 seconds
# pyright: ~1-2 seconds

# Large project (100K lines)
# mypy: ~60-120 seconds
# pyright: ~10-20 seconds
功能差异

Pyright 的优势:

  • 类型检查速度快 5–10 倍
  • 类型推断更出色
  • 集成 VS Code(Pylance)
  • 由 Microsoft 积极开发
  • 协议支持更出色
  • 类型收窄能力更强

mypy 的优势:

  • 生态更成熟
  • 插件系统
  • 控制更精细
  • 文档更完善
  • 配置选项更多
适用 Pyright 的场景
  • ✅ VS Code 用户
  • ✅ 需要快速反馈
  • ✅ 希望进行严格的类型检查
  • ✅ 使用现代 Python(3.10+)
  • ✅ 开始新项目
适用 mypy 的场景
  • ✅ 已有 mypy 配置
  • ✅ 需要 mypy 插件
  • ✅ 使用非 VS Code 编辑器
  • ✅ 使用旧版 Python(<3.8)
  • ✅ 团队更偏好 mypy

最佳实践

从基础模式开始
{
  "typeCheckingMode": "basic",
  "reportMissingImports": true,
  "reportUndefinedVariable": true
}
逐步提高严格程度
{
  "typeCheckingMode": "standard",
  "reportUnknownParameterType": "warning",
  "reportUnknownArgumentType": "warning"
}
使用类型存根
# Generate stubs for third-party packages
pyright --createstub package_name

# Custom stubs directory
mkdir -p typings
善用内嵌提示
{
  "python.analysis.inlayHints.variableTypes": true,
  "python.analysis.inlayHints.functionReturnTypes": true,
  "python.analysis.inlayHints.callArgumentNames": true
}
类型覆盖率
# Check type completeness
pyright --stats

# Output:
# Files analyzed: 42
# Lines of code: 3,421
# Type completeness: 87.3%
有针对性地忽略
# Avoid broad ignores
# pyright: ignore  # ✗ Too broad

# Prefer specific ignores
# pyright: ignore[reportGeneralTypeIssues]  # ✓ Specific

# Or fix the issue
value: str = cast(str, unknown_value)  # ✓ Best

故障排除

导入解析
{
  "extraPaths": ["src", "lib"],
  "stubPath": "typings",
  "venvPath": ".",
  "venv": ".venv"
}
存根生成
# Generate stubs for package
pyright --createstub requests

# Custom stub location
pyright --createstub requests --outputdir typings
性能问题
{
  "exclude": [
    "**/node_modules",
    "**/__pycache__",
    ".venv",
    "build",
    "dist"
  ]
}
VS Code 未使用 Pyright
{
  "python.languageServer": "Pylance",
  "python.analysis.typeCheckingMode": "basic",
  "python.analysis.diagnosticMode": "workspace"
}

资源

官方资源:

社区资源:


相关技能:mypy、FastAPI、Django、pytest Token 数量:约 3,850 个 token

评论

支持 Markdown