pyrefly-type-coverage

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Pyrefly Type Coverage Skill

Pyrefly 类型覆盖技能

This skill guides you through improving type coverage in Python files using Pyrefly, Meta's type checker. Follow this systematic process to add proper type annotations to files.
本技能将指导你使用Meta的类型检查工具Pyrefly来提升Python文件的类型覆盖度。按照这个系统化的流程为文件添加正确的类型注解。

Prerequisites

前置条件

  • The file you're working on should be in a project with a
    pyrefly.toml
    configuration
  • 你处理的文件所在项目需包含
    pyrefly.toml
    配置文件

Step-by-Step Process

分步流程

Step 1: Remove Ignore Errors Directive

步骤1:移除忽略错误指令

First, locate and remove any
pyre-ignore-all-errors
comments at the top of the file:
python
undefined
首先,找到并移除文件顶部所有
pyre-ignore-all-errors
类的注释:
python
undefined

REMOVE lines like these:

REMOVE lines like these:

pyre-ignore-all-errors

pyre-ignore-all-errors

pyre-ignore-all-errors[16,21,53,56]

pyre-ignore-all-errors[16,21,53,56]

@lint-ignore-every PYRELINT

@lint-ignore-every PYRELINT


These directives suppress type checking for the entire file and must be removed to enable proper type coverage.

这些指令会屏蔽整个文件的类型检查,必须移除才能启用正常的类型覆盖检查。

Step 2: Add Entry to pyrefly.toml

步骤2:在pyrefly.toml中添加配置项

Add a sub-config entry for stricter type checking. Open
pyrefly.toml
and add an entry following this pattern:
toml
[[sub-config]]
matches = "path/to/your/file.py"
[sub-config.errors]
implicit-import = false
implicit-any = true
For directory-level coverage:
toml
[[sub-config]]
matches = "path/to/directory/**"
[sub-config.errors]
implicit-import = false
implicit-any = true
You can also enable stricter options as needed:
toml
[[sub-config]]
matches = "path/to/your/file.py"
[sub-config.errors]
implicit-import = false
implicit-any = true
添加子配置项以启用更严格的类型检查。打开
pyrefly.toml
并按照以下格式添加配置:
toml
[[sub-config]]
matches = "path/to/your/file.py"
[sub-config.errors]
implicit-import = false
implicit-any = true
针对目录级别的覆盖配置:
toml
[[sub-config]]
matches = "path/to/directory/**"
[sub-config.errors]
implicit-import = false
implicit-any = true
你也可以根据需要启用更严格的检查选项:
toml
[[sub-config]]
matches = "path/to/your/file.py"
[sub-config.errors]
implicit-import = false
implicit-any = true

Uncomment these for stricter checking:

Uncomment these for stricter checking:

unannotated-attribute = true

unannotated-attribute = true

unannotated-parameter = true

unannotated-parameter = true

unannotated-return = true

unannotated-return = true

undefined
undefined

Step 3: Run Pyrefly to Identify Missing Coverage

步骤3:运行Pyrefly识别缺失的类型覆盖

Execute the type checker to see all type errors:
bash
pyrefly check <FILENAME>
Example:
bash
pyrefly check torch/_dynamo/utils.py
This will output a list of type errors with line numbers and descriptions. Common error types include:
  • Missing return type annotations
  • Missing parameter type annotations
  • Incompatible types
  • Missing attribute definitions
  • Implicit
    Any
    usage
CRITICAL: Your goal is to resolve all errors. If you cannot resolve an error, you can use
# pyrefly: ignore[...]
to suppress but you should try to resolve the error first
执行类型检查工具以查看所有类型错误:
bash
pyrefly check <FILENAME>
示例:
bash
pyrefly check torch/_dynamo/utils.py
这会输出包含行号和描述的类型错误列表。常见的错误类型包括:
  • 缺失返回类型注解
  • 缺失参数类型注解
  • 类型不兼容
  • 缺失属性定义
  • 隐式
    Any
    类型的使用
重要提示:你的目标是解决所有错误。如果无法解决某个错误,可以使用
# pyrefly: ignore[...]
来屏蔽,但应优先尝试解决错误。

Step 4: Add Type Annotations

步骤4:添加类型注解

Work through each error systematically:
  1. Read the function/code carefully - Understand what the function does
  2. Examine usage patterns - Look at how the function is called to understand expected types
  3. Add appropriate annotations - Add type hints based on your analysis
逐个系统地处理每个错误:
  1. 仔细阅读函数/代码 - 理解函数的功能
  2. 检查使用模式 - 查看函数的调用方式以理解预期的类型
  3. 添加合适的注解 - 根据你的分析添加类型提示

Common Annotation Patterns

常见注解模式

Function signatures:
python
undefined
函数签名
python
undefined

Before

Before

def process_data(items, callback): ...
def process_data(items, callback): ...

After

After

from collections.abc import Callable def process_data(items: list[str], callback: Callable[[str], bool]) -> None: ...

**Class attributes:**
```python
from collections.abc import Callable def process_data(items: list[str], callback: Callable[[str], bool]) -> None: ...

**类属性**:
```python

Before

Before

class MyClass: def init(self): self.value = None self.items = []
class MyClass: def init(self): self.value = None self.items = []

After

After

class MyClass: value: int | None items: list[str]
def __init__(self) -> None:
    self.value = None
    self.items = []

**Complex types:**
**CRITICAL**: use syntax for Python >3.10 and prefer collections.abc as opposed to
typing for better code standards.

**Critical**: For more advanced/generic types such as `TypeAlias`, `TypeVar`, `Generic`, `Protocol`, etc. use `typing_extensions`

```python
class MyClass: value: int | None items: list[str]
def __init__(self) -> None:
    self.value = None
    self.items = []

**复杂类型**:
**重要提示**:使用Python 3.10+的语法,并且优先使用collections.abc而非typing模块,以遵循更好的代码标准。

**重要提示**:对于更高级的泛型类型,如`TypeAlias`、`TypeVar`、`Generic`、`Protocol`等,请使用`typing_extensions`。

```python

Optional values

Optional values

def get_value(key: str) -> int | None: ...
def get_value(key: str) -> int | None: ...

Union types

Union types

def process(value: str | int) -> str: ...
def process(value: str | int) -> str: ...

Dict and List

Dict and List

def transform(data: dict[str, list[int]]) -> list[str]: ...
def transform(data: dict[str, list[int]]) -> list[str]: ...

Callable

Callable

from collections.abc import Callable def apply(func: Callable[[int, int], int], a: int, b: int) -> int: ...
from collections.abc import Callable def apply(func: Callable[[int, int], int], a: int, b: int) -> int: ...

TypeVar for generics

TypeVar for generics

from typing_extensions import TypeVar T = TypeVar('T') def first(items: list[T]) -> T: ...

**Using `# pyre-ignore` for specific lines:**

If a specific line is difficult to type correctly (e.g., dynamic metaprogramming), you can ignore just that line:

```python
from typing_extensions import TypeVar T = TypeVar('T') def first(items: list[T]) -> T: ...

**为特定行使用`# pyre-ignore`**:

如果某行代码难以正确标注类型(例如动态元编程),可以仅忽略该行:

```python

pyrefly: ignore[attr-defined]

pyrefly: ignore[attr-defined]

result = getattr(obj, dynamic_name)()

**CRITICAL**: Avoid using `# pyre-ignore` unless it is necessary.
When possible, we can implement stubs, or refactor code to make it more type-safe.
result = getattr(obj, dynamic_name)()

**重要提示**:除非必要,否则避免使用`# pyre-ignore`。如果可能,我们可以存根实现或重构代码以提高类型安全性。

Step 5: Iterate and Verify

步骤5:迭代并验证

After adding annotations:
  1. Re-run pyrefly check to verify errors are resolved:
    bash
    pyrefly check <FILENAME>
  2. Fix any new errors that may appear from the annotations you added
  3. Repeat until clean - Continue until pyrefly reports no errors
添加注解后:
  1. 重新运行pyrefly检查以验证错误是否已解决:
    bash
    pyrefly check <FILENAME>
  2. 修复任何新出现的错误,这些错误可能来自你添加的注解
  3. 重复直到无错误 - 持续操作直到pyrefly报告无错误

Step 6: Commit Changes

步骤6:提交变更

To keep type coverage PRs manageable, you should commit your change once finished with a file.
为了让类型覆盖的PR保持易于管理,完成一个文件的处理后应提交变更。

Tips for Success

成功技巧

  1. Start with function signatures - Return types and parameter types are usually the highest priority
  2. Use
    from __future__ import annotations
    - Add this at the top of the file for forward references:
    python
    from __future__ import annotations
  3. Leverage type inference - Pyrefly can infer many types; focus on function boundaries
  4. Check existing type stubs - For external libraries, check if type stubs exist
  5. Use
    typing_extensions
    for newer features
    - For compatibility:
    python
    from typing_extensions import TypeAlias, Self, ParamSpec
  6. Document complex types with TypeAlias:
    python
    from typing import Dict, List, TypeAlias
    
    ConfigType: TypeAlias = Dict[str, List[int]]
    
    def process_config(config: ConfigType) -> None: ...
  1. 从函数签名开始 - 返回类型和参数类型通常是最高优先级
  2. 使用
    from __future__ import annotations
    - 在文件顶部添加此语句以支持前向引用:
    python
    from __future__ import annotations
  3. 利用类型推断 - Pyrefly可以推断许多类型;重点关注函数边界
  4. 检查现有的类型存根 - 对于外部库,检查是否存在类型存根
  5. 使用
    typing_extensions
    获取更新的特性
    - 为了兼容性:
    python
    from typing_extensions import TypeAlias, Self, ParamSpec
  6. 使用TypeAlias记录复杂类型
    python
    from typing import Dict, List, TypeAlias
    
    ConfigType: TypeAlias = Dict[str, List[int]]
    
    def process_config(config: ConfigType) -> None: ...

Example Workflow

示例工作流

bash
undefined
bash
undefined

1. Open the file and remove pyre-ignore-all-errors

1. Open the file and remove pyre-ignore-all-errors

2. Add entry to pyrefly.toml

2. Add entry to pyrefly.toml

3. Check initial errors

3. Check initial errors

pyrefly check torch/my_module.py
pyrefly check torch/my_module.py

4. Add annotations iteratively

4. Add annotations iteratively

5. Re-check after changes

5. Re-check after changes

pyrefly check torch/my_module.py
pyrefly check torch/my_module.py

6. Repeat until clean

6. Repeat until clean

undefined
undefined