返回

文章详情

将 Pylint 转换为 Rust 的寓言

Hacker News2026年6月19日 04:21

一个 Rust 重新实现的 pylint,输出字节逐字相同——速度提升 15–2300 倍(中位数约 85 倍)。prylint 不是“受到” pylint 的启发。它是逐bug移植:相同的消息,在相同的行和列中,以相同的文本、相同的顺序、相同的退出码以及相同的“您的代码评分”页脚——在 52 个生产代码库(约 65,000 个 Python 文件)上与真实的 pylint 逐字验证,包括 django、numpy、pandas、sympy、home-assistant、sqlalchemy、twisted、scikit-learn 以及 pylint 自己的功能测试套件。pylint 存在bug时,prylint 重现它们;pylint 崩溃时,prylint 报告相同的崩溃信息。安装:pip install prylint 。要求:在 PATH 中的 python3(≥3.9)(仅用于镜像 pylint 的模块解析路径以及重现无法解析文件的 CPython 精确语法错误消息)。不需要 pylint 和 astroid 本身。使用方法:与 pylint 完全相同——完整检查模式是默认值:prylint . # 所有检查(如 `pylint .`) prylint -E . # 仅错误(如 `pylint -E .`) prylint --disable = C0114,... . # 相同的 --disable / --enable / 内联 pragma。输出、消息顺序、退出码、评分页脚、--rcfile / pyproject.toml 发现、init-hook 和 # pylint: pragmas 都与 pylint 4.0.5 匹配。基准测试:prylint . 与 pylint .(均为完整检查模式),pylint 4.0.5,Apple M 系列,单线程:代码库 pylint prylint 提速黑色 26.7 小时 41 秒 2328 倍 sentry 3.7 小时 24 秒 546 倍 home-assistant(17.5k 文件) 10.3 小时 82 秒 452 倍 airflow 1.9 小时 17 秒 399 倍 salt 1890 秒 8.8 秒 215 倍 zulip 909 秒 5.3 秒 172 倍 django 1524 秒 10.1 秒 150 倍 ansible 419 秒 2.9 秒 143 倍 nova(OpenStack) 1209 秒 10.3 秒 117 倍 fastapi 116 秒 1.0 秒 120 倍 mypy 367 秒 3.9 秒 95 倍 sqlalchemy 614 秒 7.1 秒 87 倍 pandas 1009 秒 14.2 秒 71 倍 scikit-learn 613 秒 9.6 秒 64 倍 sympy 1238 秒 26 秒 48 倍 … 还有 12 个,全部 ≥30 倍(这 27 个) 45.8 小时 4.9 分钟 ~560 倍(这 27 个是速度足够慢以有意义计时的大型代码库;完整精度套件是 52 个代码库——见下文)。每个代码库的中位数提速约 85 倍;总提速更高,因为 pylint 的重复代码检查(R0801)是 O(n²),并在像 black 这样的测试密集型代码库中占主导地位。这些是单核数字——推理引擎是单线程的,以精确复制 astroid 的顺序敏感全局缓存(见 LIMITATIONS.md),而这条字节相同路径已比 pylint 快 15–2300 倍。上面的每一行也是精度测试:每个代码库的完整输出与 pylint 的逐字相同(见 LIMITATIONS.md 中的例外)。精度:prylint 是通过与固定的 pylint 4.0.5 / astroid 4.0.4 / CPython 3.12 进行差异测试构建的:AST 保真度——prylint 的解析树(基于 ruff 解析器构建)逐节点与 astroid 的做比较(位置、作用域、局部变量、脑变换),跨所有语料库文件:零差异。推理保真度——astroid 的推理引擎被精确移植:延迟生成器语义、100 节点推理预算、有界 LRU 缓存(lookup 128, _metaclass_lookup_attribute 1024)及其精确逐出、64 项推理提示 FIFO、不可推导传播。每个名称/属性/调用节点的推理都被转储并与 astroid 进行比较。输出保真度——完整运行逐字比较,包括消息顺序、模块头、评分页脚、# pylint: pragma 处理(禁用/启用块、禁用下一条,跳过文件)、配置文件发现和退出码位掩码。盲测试——开发后增加了两组各 10 个代码库,并进行了冷测试;每个偏差都被追踪并修复。已知的、记录的例外(一个模糊的 SQLAlchemy 类;故意排除的 no-member 家族;pylint 对自身的非确定性的位置)已在 LIMITATIONS.md 中列入目录。工作原理:文件发现、消息控制、配置解析和报告直接移植了 pylint 的逻辑(包括 os.walk 的顺序、模块头规则以及评分报告页脚)。解析使用 ruff 的 Rust 解析器,然后重建 astroid 的确切树形状(文档字符串提取、装饰器位置、隐式类局部变量、元类处理、数据类/枚举/命名元组/attrs 的脑变换等)。astroid 的推理引擎的完整移植解决名称、调用、属性、MRO 和操作符协议,遵循 astroid 的精确保守性——包括其缓存及其特性,因为这些特性在输出中是可观察的。Rust 解析器拒绝的文件由 CPython 自身(一个嵌入式,仅限标准库的帮助程序)重新判断,以便语法错误消息精确匹配 ast.parse。复制测试套件 scripts/setup_corpora.sh 克隆所有 52 个语料库在固定提交下,并构建固定的 pylint/astroid 真相虚拟环境。精度合同:每次更改必须保持语料库字节相同(harness/持有差异比较器)。许可证:GPL-2.0 或更高版本,与 pylint 相同——prylint 逐字再现 pylint 的消息文本和行为。

赞助内容

NordVPN Next-gen Antivirus

本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。

请我喝杯咖啡