facebook/pyrefly
GitHub: facebook/pyrefly
一款由 Meta 采用 Rust 开发的 Python 类型检查器和语言服务器,专注于高性能类型检查与 IDE 集成体验。
Stars: 5425 | Forks: 279
# Pyrefly:一个快速的 Python 类型检查器和语言服务器,具备强大的 IDE 功能
[](https://github.com/facebook/pyrefly)
[](https://pypi.python.org/pypi/pyrefly)
[](https://marketplace.visualstudio.com/items?itemName=meta.pyrefly)
[](https://open-vsx.org/extension/meta/pyrefly)
[](https://discord.gg/Cf7mFQtW7W)
[](https://opensource.org/licenses/MIT)
Pyrefly 是一个 Python 类型检查器和语言服务器,提供极速的类型检查以及 IDE 功能,例如代码导航、语义高亮和代码补全。它可以作为[命令行工具](https://pyrefly.org/en/docs/installation/)使用,也可以作为扩展用于流行的 IDE 和编辑器,例如 [VSCode](https://marketplace.visualstudio.com/items?itemName=meta.pyrefly)、[Neovim](https://pyrefly.org/en/docs/IDE/#neovim)、[Zed](https://zed.dev/extensions/pyrefly) 以及[更多](https://pyrefly.org/en/docs/IDE/)。
请访问 [Pyrefly 网站](https://pyrefly.org) 获取完整的文档以及如何将 Pyrefly 添加到您选择的编辑器中。
目前正处于活跃开发中,存在一些已知问题。如果您发现错误,请提交 issue。
### 快速入门
- 在浏览器中试用 pyrefly:[沙盒](https://pyrefly.org/sandbox/)
- 获取命令行工具:`pip install pyrefly`
- 获取 IDE 扩展:[IDE 安装页面](https://pyrefly.org/en/docs/IDE/)
### 关键特性:
- 类型推导:Pyrefly 可以在大多数位置推导类型,除了函数参数。它可以推导变量的类型和返回类型。
- 流类型:Pyrefly 能够理解程序的控制流以细化静态类型。
- 增量检查:Pyrefly 旨在实现模块级别的大规模增量性,具有优化的检查和并行性。
## 参与其中
如果您有疑问或想报告错误,请[创建一个 issue](https://github.com/facebook/pyrefly/issues)。
请参阅我们的[贡献指南](https://github.com/facebook/pyrefly/blob/main/CONTRIBUTING.md)了解如何为 Pyrefly 做贡献。
加入我们的 [Discord](https://discord.com/invite/Cf7mFQtW7W) 聊聊 Pyrefly 和类型。这也是我们举办双周办公时间的地方。
## 设计选择
在编写 Python 类型检查器时有许多选择。我们从 [Pyre1](https://pyre-check.org/)、[Pyright](https://github.com/microsoft/pyright) 和 [MyPy](https://mypy.readthedocs.io/en/stable/) 中汲取灵感。一些值得注意的选择:
- 我们在大多数位置推导类型,除了函数的参数。我们确实会推导变量的类型和返回类型。举个例子,`def foo(x): return True` 的结果将等同于您编写 `def foo(x: Any) -> bool: ...`。
- 我们尝试将 `[]` 的类型推导为其首次使用的方式,然后将其固定。例如 `xs = []; xs.append(1); xs.append("")` 将推导出 `xs: List[int]`,然后在最后一条语句上报错。
- 我们使用流类型来细化静态类型,例如 `x: int = 4` 不仅知道 `x` 的类型是 `int`,而且知道紧接着对 `x` 的下一次使用将意识到类型是 `Literal[4]`。
- 我们的目标是实现大规模的增量性(在模块级别)和通过并行性进行优化的检查,旨在利用 Rust 的优势使代码更简洁一些。
- 我们预期存在大型的强连通分量模块,并且不尝试利用源代码中的 DAG(有向无环图)形状。
## 代码布局
Pyrefly 被拆分为多个 crate(主要位于 `crates/` 下):
- `pyrefly_util` 是通用工具,与 Python 或类型检查无关。示例包括 IO 包装器、锁定、命令行助手等。
- `pyrefly_derive` 是用于派生诸如 `TypeEq` 和 `Visit` 等 trait 的过程宏。
- `pyrefly_python` 是不涉及类型检查方面的 Python 工具,例如建模模块或 `sys.info`。
- `pyrefly_graph` 提供用于索引值和缓存可能相互依赖的计算的工具。
- `pyrefly_bundled` 是第三方的 [typeshed stubs](https://github.com/python/typeshed)。
- `pyrefly_config` 定义了 Pyrefly 配置,并支持读取 Mypy/Pyright 配置。
- `pyrefly_types` 定义了 Pyrefly 类型及其上的操作。
- `pyrefly_wasm` 定义了编译为 WASM 的沙盒代码。
- `pyrefly` 本身是类型检查器及其他所有内容。
## 设计
设计的许多细节会定期变化。但构建检查器的基本底板涉及三个步骤:
1. 弄清楚每个模块导出什么。这需要传递地解析所有 `import *` 语句。
2. 对于每个独立的模块,将其转换为绑定(bindings),处理所有语句和作用域信息(包括静态和流)。
3. 求解这些绑定,这可能需要求解其他模块中的绑定。
如果我们遇到不可知的信息(例如递归),我们使用 `Type::Var` 插入占位符,稍后再填充。
对于每个模块,我们按顺序且完整地求解步骤。特别是,我们不尝试先求解特定的标识符(像 [Roslyn](https://github.com/dotnet/roslyn) 或 [TypeScript](https://www.typescriptlang.org/) 那样),也不使用细粒度的增量性(像 [Rust Analyzer](https://github.com/rust-lang/rust-analyzer) 使用 [Salsa](https://github.com/salsa-rs/salsa) 那样)。相反,我们的目标是原始性能和更简单的以模块为中心的设计——如果求解模块中的所有绑定足够快,就没有必要单独求解单个绑定。
### 绑定示例
给定程序:
```
1: x: int = 4
2: print(x)
```
我们可能会生成以下绑定:
- `define int@0` = `from builtins import int`
- `define x@1` = `4: int@0`
- `use x@2` = `x@1`
- `anon @2` = `print(x@2)`
- `export x` = `x@2`
值得注意的是:
- 键是诸如 `define`(某事物的定义)、`use`(某事物的使用)和 `anon`(我们需要进行类型检查但不关心结果的语句)之类的东西。
- 在许多情况下,键的值引用了其他键。
- 一些键是通过 `export` 键和 `import` 值从其他模块导入的。
- 为了消除标识符的歧义,我们使用它们出现的文本位置(在示例中我们使用了 `@line`,但实际上它是文件中的字节偏移量)。
### `Var` 示例
给定程序:
```
1: x = 1
2: while test():
3: x = x
4: print(x)
```
我们最终得到以下绑定:
- `x@1` = `1`
- `x@3` = `phi(x@1, x@3)`
- `x@4` = `phi(x@1, x@3)`
表达式 `phi` 是两个值的连接点,例如 `phi(int, str)` 将是 `int | str`。我们跳过了 `define` 和 `use` 之间的区别,因为这对于本示例来说不是必需的。
当求解 `x@3` 时,我们遇到了递归。操作上:
- 我们开始求解 `x@3`。
- 这需要我们先求解 `x@1`。
- 我们求解 `x@1` 为 `Literal[1]`
- 我们开始求解 `x@3`。但我们当前正在求解 `x@3`,所以我们发明一个新的 `Var`(让我们称之为 `?1`)并返回它。
- 我们得出结论 `x@3` 必须是 `Literal[1] | ?1`。
- 由于 `?1` 是由 `x@3` 引入的,我们记录 `?1 = Literal[1] | ?1`。我们可以取其上可达边界并得出结论 `?1 = Literal[1]`。
- 我们将 `x@3` 简化为 `Literal[1]`。
标签:IDE插件, Language Server Protocol, LSP, Meta, MIT许可, Neovim, Pyrefly, Python, Rust, SOC Prime, VS Code扩展, 云安全监控, 代码导航, 代码补全, 可视化界面, 开发工具, 无后门, 类型推断, 网络流量审计, 语言服务器, 逆向工具, 通知系统, 通知系统, 通知系统, 静态分析, 静态类型检查