pyright-type-checker
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePyright - Fast Python Type Checker
Pyright - 快速Python类型检查工具
progressive_disclosure: entry_point: summary: "Fast Python type checker from Microsoft with VS Code integration and strict modes" when_to_use: - "When needing faster type checking than mypy" - "When using VS Code (Pylance)" - "When requiring stricter type checking" - "When migrating from mypy" quick_start: - "npm install -g pyright" - "Create pyrightconfig.json" - "pyright ." token_estimate: entry: 65-80 full: 3500-4500
progressive_disclosure: entry_point: summary: "微软推出的快速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
Installation
安装
Node.js (Recommended)
Node.js(推荐方式)
bash
undefinedbash
undefinedGlobal installation
Global installation
npm install -g pyright
npm install -g pyright
Per-project installation
Per-project installation
npm install --save-dev pyright
npm install --save-dev pyright
Verify installation
Verify installation
pyright --version
undefinedpyright --version
undefinedVS Code (Pylance)
VS Code(搭配Pylance)
Pyright powers Pylance extension:
bash
undefinedPyright 是 Pylance 扩展的核心支持工具:
bash
undefinedInstall Pylance extension (includes pyright)
Install Pylance extension (includes pyright)
code --install-extension ms-python.vscode-pylance
undefinedcode --install-extension ms-python.vscode-pylance
undefinedpip Installation
pip安装方式
bash
undefinedbash
undefinedCommunity wrapper
Community wrapper
pip install pyright
pip install pyright
Note: Still requires Node.js runtime
Note: Still requires Node.js runtime
undefinedundefinedConfiguration
配置
pyrightconfig.json
pyrightconfig.json
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
}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
}Type Checking Modes
类型检查模式
Basic Mode (Default):
json
{
"typeCheckingMode": "basic",
"reportUnusedImport": "warning",
"reportUnusedVariable": "warning"
}Standard Mode:
json
{
"typeCheckingMode": "standard",
"reportUnknownParameterType": "error",
"reportUnknownArgumentType": "error",
"reportUnknownVariableType": "error"
}Strict Mode (Maximum type safety):
json
{
"typeCheckingMode": "strict",
"reportPrivateUsage": "error",
"reportConstantRedefinition": "error",
"reportIncompatibleMethodOverride": "error",
"reportIncompatibleVariableOverride": "error",
"reportUnnecessaryIsInstance": "warning",
"reportUnnecessaryCast": "warning"
}基础模式(默认):
json
{
"typeCheckingMode": "basic",
"reportUnusedImport": "warning",
"reportUnusedVariable": "warning"
}标准模式:
json
{
"typeCheckingMode": "standard",
"reportUnknownParameterType": "error",
"reportUnknownArgumentType": "error",
"reportUnknownVariableType": "error"
}严格模式(最高类型安全性):
json
{
"typeCheckingMode": "strict",
"reportPrivateUsage": "error",
"reportConstantRedefinition": "error",
"reportIncompatibleMethodOverride": "error",
"reportIncompatibleVariableOverride": "error",
"reportUnnecessaryIsInstance": "warning",
"reportUnnecessaryCast": "warning"
}Per-File Configuration
单文件配置
python
undefinedpython
undefinedpyright: strict
pyright: strict
"""Strict type checking for this file."""
"""Strict type checking for this file."""
pyright: basic
pyright: basic
"""Basic type checking."""
"""Basic type checking."""
pyright: reportGeneralTypeIssues=false
pyright: reportGeneralTypeIssues=false
"""Disable specific diagnostics."""
undefined"""Disable specific diagnostics."""
undefinedVS Code Integration
VS Code集成
settings.json
settings.json
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
}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
}Workspace Configuration
工作区配置
json
{
"python.analysis.extraPaths": [
"./src",
"./lib"
],
"python.analysis.stubPath": "./typings",
"python.analysis.diagnosticSeverityOverrides": {
"reportUnusedImport": "warning",
"reportUnusedVariable": "warning",
"reportGeneralTypeIssues": "error"
}
}json
{
"python.analysis.extraPaths": [
"./src",
"./lib"
],
"python.analysis.stubPath": "./typings",
"python.analysis.diagnosticSeverityOverrides": {
"reportUnusedImport": "warning",
"reportUnusedVariable": "warning",
"reportGeneralTypeIssues": "error"
}
}Type Checking Features
类型检查特性
Type Narrowing
类型窄化
python
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 herepython
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 hereType guards
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))
undefinedfrom 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))
undefinedProtocol Support
协议支持
python
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()python
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
Works with structural typing
render(Circle()) # ✓ No explicit inheritance needed
undefinedrender(Circle()) # ✓ No explicit inheritance needed
undefinedTypedDict
TypedDict
python
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 optionalpython
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 optionalLiteral Types
字面量类型
python
from typing import Literal
Mode = Literal["read", "write", "append"]
def open_file(mode: Mode) -> None:
...
open_file("read") # ✓
open_file("delete") # ✗ Errorpython
from typing import Literal
Mode = Literal["read", "write", "append"]
def open_file(mode: Mode) -> None:
...
open_file("read") # ✓
open_file("delete") # ✗ ErrorAdvanced Features
高级特性
Variance and Generics
方差与泛型
python
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: ...python
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]
Covariance: Reader[Dog] is subtype of Reader[Animal]
Contravariance: Writer[Animal] is subtype of Writer[Dog]
Contravariance: Writer[Animal] is subtype of Writer[Dog]
undefinedundefinedParamSpec
ParamSpec
python
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}"python
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)
Type-safe: greet("Alice", 30)
undefinedundefinedType Aliases
类型别名
python
from typing import TypeAliaspython
from typing import TypeAliasSimple alias
Simple alias
UserId: TypeAlias = int
Username: TypeAlias = str
UserId: TypeAlias = int
Username: TypeAlias = str
Generic alias
Generic alias
from collections.abc import Sequence
Vector: TypeAlias = Sequence[float]
from collections.abc import Sequence
Vector: TypeAlias = Sequence[float]
Complex alias
Complex alias
JSON: TypeAlias = dict[str, "JSON"] | list["JSON"] | str | int | float | bool | None
undefinedJSON: TypeAlias = dict[str, "JSON"] | list["JSON"] | str | int | float | bool | None
undefinedCI/CD Integration
CI/CD集成
GitHub Actions
GitHub Actions
yaml
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: pyrightyaml
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: pyrightPre-commit Hook
预提交钩子
yaml
undefinedyaml
undefined.pre-commit-config.yaml
.pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: pyright name: pyright entry: pyright language: node types: [python] pass_filenames: false additional_dependencies: ['pyright@1.1.350']
undefinedrepos:
- repo: local
hooks:
- id: pyright name: pyright entry: pyright language: node types: [python] pass_filenames: false additional_dependencies: ['pyright@1.1.350']
undefinedMakefile
Makefile
makefile
.PHONY: typecheck typecheck-strict
typecheck:
pyright
typecheck-strict:
pyright --level strict
typecheck-watch:
pyright --watch
typecheck-stats:
pyright --statsmakefile
.PHONY: typecheck typecheck-strict
typecheck:
pyright
typecheck-strict:
pyright --level strict
typecheck-watch:
pyright --watch
typecheck-stats:
pyright --statsMigration from mypy
从mypy迁移
Configuration Mapping
配置映射
json
{
"// mypy: disallow_untyped_defs": "reportUntypedFunctionDecorator",
"// mypy: disallow_any_generics": "reportMissingTypeArgument",
"// mypy: warn_return_any": "reportUnknownArgumentType",
"// mypy: strict_equality": "reportUnnecessaryComparison",
"// mypy: warn_unused_ignores": "reportUnnecessaryTypeIgnoreComment"
}json
{
"// mypy: disallow_untyped_defs": "reportUntypedFunctionDecorator",
"// mypy: disallow_any_generics": "reportMissingTypeArgument",
"// mypy: warn_return_any": "reportUnknownArgumentType",
"// mypy: strict_equality": "reportUnnecessaryComparison",
"// mypy: warn_unused_ignores": "reportUnnecessaryTypeIgnoreComment"
}Comment Syntax
注释语法
python
undefinedpython
undefinedmypy: ignore-errors
mypy: ignore-errors
↓ pyright equivalent
↓ pyright equivalent
pyright: reportGeneralTypeIssues=false
pyright: reportGeneralTypeIssues=false
type: ignore
type: ignore
↓ pyright equivalent
↓ pyright equivalent
pyright: ignore
pyright: ignore
type: ignore[error-code]
type: ignore[error-code]
↓ pyright equivalent
↓ pyright equivalent
pyright: ignore[reportGeneralTypeIssues]
pyright: ignore[reportGeneralTypeIssues]
undefinedundefinedGradual Migration
渐进式迁移
json
{
"typeCheckingMode": "basic",
"include": ["src/new_module"],
"exclude": ["src/legacy"],
"reportMissingImports": true,
"reportMissingTypeStubs": false
}json
{
"typeCheckingMode": "basic",
"include": ["src/new_module"],
"exclude": ["src/legacy"],
"reportMissingImports": true,
"reportMissingTypeStubs": false
}Performance Optimization
性能优化
Baseline Performance
基准性能
bash
undefinedbash
undefinedCreate performance baseline
Create performance baseline
pyright --stats --createstub
pyright --stats --createstub
Compare after changes
Compare after changes
pyright --stats
undefinedpyright --stats
undefinedWatch Mode
监听模式
bash
undefinedbash
undefinedFast incremental checking
Fast incremental checking
pyright --watch
pyright --watch
With specific path
With specific path
pyright --watch src/
undefinedpyright --watch src/
undefinedParallel Checking
并行检查
json
{
"executionEnvironments": [
{
"root": "src",
"pythonVersion": "3.11"
},
{
"root": "tests",
"pythonVersion": "3.11",
"extraPaths": ["src"]
}
]
}json
{
"executionEnvironments": [
{
"root": "src",
"pythonVersion": "3.11"
},
{
"root": "tests",
"pythonVersion": "3.11",
"extraPaths": ["src"]
}
]
}Common Patterns
常见模式
Optional Handling
可选值处理
python
from typing import Optional
def get_user(user_id: int) -> Optional[str]:
return "Alice" if user_id == 1 else Nonepython
from typing import Optional
def get_user(user_id: int) -> Optional[str]:
return "Alice" if user_id == 1 else NoneBefore pyright 1.1.200
Before pyright 1.1.200
user = get_user(1)
if user is not None:
print(user.upper())
user = get_user(1)
if user is not None:
print(user.upper())
With pyright type narrowing
With pyright type narrowing
user = get_user(1)
if user: # Narrows to str
print(user.upper())
undefineduser = get_user(1)
if user: # Narrows to str
print(user.upper())
undefinedUnion Narrowing
联合类型窄化
python
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 strpython
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 strOverload
重载
python
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"python
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
Type-safe usage
text: str = open_file("file.txt", "r")
data: bytes = open_file("file.bin", "rb")
undefinedtext: str = open_file("file.txt", "r")
data: bytes = open_file("file.bin", "rb")
undefinedAssertion Functions
断言函数
python
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 checkpython
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 checkPyright vs mypy
Pyright vs mypy
Performance Comparison
性能对比
bash
undefinedbash
undefinedTypical project (10K lines)
Typical project (10K lines)
mypy: ~5-10 seconds
mypy: ~5-10 seconds
pyright: ~1-2 seconds
pyright: ~1-2 seconds
Large project (100K lines)
Large project (100K lines)
mypy: ~60-120 seconds
mypy: ~60-120 seconds
pyright: ~10-20 seconds
pyright: ~10-20 seconds
undefinedundefinedFeature Differences
特性差异
Pyright Advantages:
- 5-10x faster type checking
- Better type inference
- VS Code integration (Pylance)
- Active development by Microsoft
- Better Protocol support
- Superior type narrowing
mypy Advantages:
- More mature ecosystem
- Plugin system
- Finer-grained control
- Better documentation
- More configuration options
Pyright 优势:
- 类型检查速度比mypy快5-10倍
- 更出色的类型推断
- 深度集成VS Code(Pylance)
- 由微软积极开发维护
- 更完善的Protocol支持
- 更强大的类型窄化能力
mypy 优势:
- 生态系统更成熟
- 支持插件系统
- 更精细的配置控制
- 文档更完善
- 配置选项更丰富
When to Use Pyright
何时选择Pyright
- ✅ VS Code users
- ✅ Need fast feedback
- ✅ Want strict type checking
- ✅ Modern Python (3.10+)
- ✅ Starting new projects
- ✅ VS Code用户
- ✅ 需要快速反馈
- ✅ 想要严格的类型检查
- ✅ 使用现代Python(3.10+)
- ✅ 启动新项目
When to Use mypy
何时选择mypy
- ✅ Existing mypy setup
- ✅ Need mypy plugins
- ✅ Non-VS Code editors
- ✅ Legacy Python (<3.8)
- ✅ Team prefers mypy
- ✅ 已有mypy配置环境
- ✅ 需要mypy插件
- ✅ 使用非VS Code编辑器
- ✅ 维护遗留Python项目(<3.8)
- ✅ 团队偏好mypy
Best Practices
最佳实践
Start with Basic Mode
从基础模式开始
json
{
"typeCheckingMode": "basic",
"reportMissingImports": true,
"reportUndefinedVariable": true
}json
{
"typeCheckingMode": "basic",
"reportMissingImports": true,
"reportUndefinedVariable": true
}Gradually Increase Strictness
逐步提升严格性
json
{
"typeCheckingMode": "standard",
"reportUnknownParameterType": "warning",
"reportUnknownArgumentType": "warning"
}json
{
"typeCheckingMode": "standard",
"reportUnknownParameterType": "warning",
"reportUnknownArgumentType": "warning"
}Use Type Stubs
使用类型存根
bash
undefinedbash
undefinedGenerate stubs for third-party packages
Generate stubs for third-party packages
pyright --createstub package_name
pyright --createstub package_name
Custom stubs directory
Custom stubs directory
mkdir -p typings
undefinedmkdir -p typings
undefinedLeverage Inlay Hints
利用内嵌提示
json
{
"python.analysis.inlayHints.variableTypes": true,
"python.analysis.inlayHints.functionReturnTypes": true,
"python.analysis.inlayHints.callArgumentNames": true
}json
{
"python.analysis.inlayHints.variableTypes": true,
"python.analysis.inlayHints.functionReturnTypes": true,
"python.analysis.inlayHints.callArgumentNames": true
}Type Coverage
类型覆盖率
bash
undefinedbash
undefinedCheck type completeness
Check type completeness
pyright --stats
pyright --stats
Output:
Output:
Files analyzed: 42
Files analyzed: 42
Lines of code: 3,421
Lines of code: 3,421
Type completeness: 87.3%
Type completeness: 87.3%
undefinedundefinedIgnore Strategically
策略性忽略
python
undefinedpython
undefinedAvoid broad ignores
Avoid broad ignores
pyright: ignore # ✗ Too broad
pyright: ignore # ✗ Too broad
Prefer specific ignores
Prefer specific ignores
pyright: ignore[reportGeneralTypeIssues] # ✓ Specific
pyright: ignore[reportGeneralTypeIssues] # ✓ Specific
Or fix the issue
Or fix the issue
value: str = cast(str, unknown_value) # ✓ Best
undefinedvalue: str = cast(str, unknown_value) # ✓ Best
undefinedTroubleshooting
故障排除
Import Resolution
导入解析问题
json
{
"extraPaths": ["src", "lib"],
"stubPath": "typings",
"venvPath": ".",
"venv": ".venv"
}json
{
"extraPaths": ["src", "lib"],
"stubPath": "typings",
"venvPath": ".",
"venv": ".venv"
}Stub Generation
存根生成
bash
undefinedbash
undefinedGenerate stubs for package
Generate stubs for package
pyright --createstub requests
pyright --createstub requests
Custom stub location
Custom stub location
pyright --createstub requests --outputdir typings
undefinedpyright --createstub requests --outputdir typings
undefinedPerformance Issues
性能问题
json
{
"exclude": [
"**/node_modules",
"**/__pycache__",
".venv",
"build",
"dist"
]
}json
{
"exclude": [
"**/node_modules",
"**/__pycache__",
".venv",
"build",
"dist"
]
}VS Code Not Using Pyright
VS Code未使用Pyright
json
{
"python.languageServer": "Pylance",
"python.analysis.typeCheckingMode": "basic",
"python.analysis.diagnosticMode": "workspace"
}json
{
"python.languageServer": "Pylance",
"python.analysis.typeCheckingMode": "basic",
"python.analysis.diagnosticMode": "workspace"
}Resources
资源
Official:
Community:
- awesome-pyright
- Python Type Hints
- PEP 484 - Type Hints
Related Skills: mypy, FastAPI, Django, pytest
Token Count: ~3,850 tokens
官方资源:
社区资源:
- awesome-pyright
- Python 类型提示
- PEP 484 - 类型提示
相关技能:mypy, FastAPI, Django, pytest
Token 数量:约3,850个