首页
/ Ruff 0.11.x 版本演进全解析:Python 版本推断新机制、PGH004 稳定化与 Compile-time Syntax Errors 体系

Ruff 0.11.x 版本演进全解析:Python 版本推断新机制、PGH004 稳定化与 Compile-time Syntax Errors 体系

2026-09-05 20:15:53作者:羿妍玫Ivan

本文围绕 Ruff 官方变更记录 changelogs/0.11.x.md 展开,完整覆盖 0.11.0 至 0.11.13 共 14 个版本的核心变更。读完本文,你将掌握 0.11.0 中 requires-python 推断这一破坏性变更的确切语义与源码实现、PGH004 稳定化后的检测范围,以及贯穿整个 0.11.x 系列的 compile-time syntax errors(编译期语法错误)检测体系是如何逐版本铺开的,并了解 --exit-non-zero-on-format 等 CLI 新选项的实际行为。

0.11.0 的由来:一次发布流程修正

0.11.0 并不是一个常规的迭代版本,而是对 0.10.0 的补发(follow-up release)。变更记录开篇明确说明:由于发布流程中的一个失误,requires-python 推断相关的变更没有包含进 0.10.0,因此 Ruff 0.11.0 补上了这一变更,同时完成了 PGH004 preview 行为的稳定化。也就是说,升级 0.11.0 时实际引入的“新行为”有两块:Python 版本推断机制的变更(破坏性变更)与 blanket-noqa 检测范围的扩大。

破坏性变更:target-version 缺失时的版本推断

在此之前,指定 Python 版本只有两条途径:

  • ruff.toml(或 pyproject.toml[tool.ruff] 段)中显式配置 target-version
  • 在带有 [tool.ruff] 段的 pyproject.toml 中依赖 project.requires-python 字段。

问题出在 Ruff 的配置发现机制上:一个不含 [tool.ruff] 段的 pyproject.toml 会被整个忽略,其中的 requires-python 也随之被忽略,Ruff 会回退到默认 Python 版本(记录写作时为 3.9)——当你明明声明了目标版本时,这个行为出人意料。

0.11.0 更新后的配置发现规则如下(变更记录原文列出三条,当前 docs/configuration.md 中“Inferring the Python version”一节的完整表述为四条):

  1. 如果直接传入了配置文件,Ruff 不会尝试推断缺失的 target-version
  2. 如果在文件系统层级中发现配置文件(如 ruff.toml 没有 target-version),Ruff 会检查同一目录下的 pyproject.toml,并尊重其 requires-python 字段——即使该文件不含 [tool.ruff] 段;
  3. 如果使用用户级配置(user-level configuration),则取父目录中最近的 pyproject.tomlrequires-python 字段优先;
  4. 如果被检查文件所在目录没有任何配置文件(ruff.toml 或带 [tool.ruff] 段的 pyproject.toml),Ruff 会向上查找最近的 pyproject.toml 并使用其 requires-python

源码实现:apply_fallbacks 与回退版本推导

从源码结构看,这套逻辑的落点在 ruff_workspace crate:

  • configuration.rs 中的 apply_fallbacks 方法:当配置来源为 ConfigurationOrigin::Ancestor(即从父目录层级发现)且 target_version 为空时,调用 pyproject::find_fallback_target_version(dir) 推导回退版本;
  • pyproject.rs 中的 find_fallback_target_version 沿路径祖先目录逐级查找,找到第一个含 requires-pythonpyproject.toml 即返回;
  • 关键的版本提取逻辑在 pyproject.rsget_minimum_supported_version:它从 VersionSpecifiers只筛选 =====~=>=> 等下界类操作符,取各操作数版本截断到 major.minor 后的最小值,再映射到 PythonVersion 枚举。例如 requires-python = ">=3.13" 会推导出 py313

需要注意的细节:load_optionspyproject.rs)在解析 pyproject.toml 时,如果其中已显式给出 target_version,则显式配置优先,不会再去读 requires-python。也就是说,target-version 依旧是“细粒度控制”的第一选择,推断只作为兜底。

PGH004(blanket-noqa)稳定化

blanket-noqa 规则(PGH004)在 0.11.0 稳定化,行为变化是:同时检测文件级的 blanket noqa 注释,而不仅仅是行级注释。即 # noqa 整行/整文件地关闭所有规则的行为现在也会被告警。配合 0.11.5 中 RUF100 对“带具体规则码的未使用文件级 noqa 指令”的检测修复,0.11.x 系列对 noqa 卫生管理的整体覆盖明显增强。

贯穿系列的 Preview 主线:compile-time syntax errors

0.11.x 系列最具系统性的一条线索是 [syntax-errors] 类别的 preview 功能——把 CPython 在编译期才会报错的语法问题,前移到 lint 阶段检测。按版本梳理其演进:

  • 0.11.1:一批针对“低版本 Python 使用高版本语法”的检测先行落地,包括 PEP 701 f-string 在 Python 3.12 之前、括号化上下文管理器(PEP 634/614 相关)在 3.9 之前、星号注解(PEP 646)在 3.11 之前、for 语句迭代子句中的元组解包在 3.9 之前等;同时改进了 pre-PEP-614 装饰器语法错误的消息与范围(range);
  • 0.11.2:修复 3.11 之前可变参数(variadic)注解上的误报;
  • 0.11.3:正式宣布 Start detecting compile-time syntax errors(开始检测编译期语法错误),并补充 match 模式相关问题(映射模式重复键、类模式重复属性、case 模式中多重赋值等)、__debug__ 赋值/删除检测;
  • 0.11.4:补充注解(annotations)中的非法语法检测、match 模式中的重复键/属性;同期还实现了 RUF102(invalid-rule-code);
  • 0.11.5:将注解检查扩展到 await 表达式与带注解赋值,新增同步推导式中出现异步推导式的检测;
  • 0.11.8:新增模块级 nonlocal 声明、单星号赋值 x = *y 检测,并将“未加括号的 except 元组”语法错误限定为 3.14 之前的行为;
  • 0.11.9:两项关键调整——版本相关的语法错误默认按最新受支持 Python 版本判定,以及为 Python 3.14 实现 deferred annotations;
  • 0.11.13(其他变更):parser 与 formatter 双双支持 Python 3.14 的 t-strings(模板字符串)。

这条线索的意义在于:Ruff 的 Rust 解析器在解析成功之后,还维护了一套 semantic_errors 检查层(可参见 ruff_python_parsererror.rs 的目录结构),0.11.x 系列把它逐步暴露为可启用的 preview 诊断,让“这份代码在目标 Python 版本下根本编译不过”的问题在 lint 阶段即可被捕获。由于均处于 preview 状态,启用方式是在配置或 CLI 中开启 preview 模式;正式稳定化前的行为仍可能调整。

值得逐条关注的规则与修复变更

Airflow 规则(AIR3xx)的大规模演进

flake8-airflow 插件是 0.11.x 中改动最密集的插件,核心是 Airflow 3 的模块迁移检测(AIR301/AIR302 等):从 0.11.1 起陆续补充 chainchain_linearcross_downstream 检测,0.11.3 引入 AIR312 拆分、规则编号多次迁移(AIR301AIR002AIR302AIR301AIR303AIR302 等,使用这些编码时注意版本差异),0.11.10–0.11.13 则持续补全 autofix(含针对 Airflow 3 中重命名场景的不安全修复)并扩展到单个符号级别的模块路径检查。如果你的项目依赖 Airflow 且使用这些规则,升级时应留意规则码映射变化。

CLI:--exit-non-zero-on-format(0.11.1)

这是一个 CI 场景下很实用的新选项:只要格式化实际修改了任何文件,即使全部文件都格式化成功,ruff format 也返回非零退出码。实现位于 args.rs,定义为 FormatCommand 的布尔参数,并带有历史别名 --exit-non-zero-on-fix。其典型用法是让 CI 以“检查+失败”的方式守护格式一致性,而不是静默修改工作区。

配置与 CLI 的其他新增

  • 0.11.3:stdin 传入的 pyproject.toml 现在能被正确解析检查(此前作为普通文本处理会导致误判);flake8-import-conventions 的默认别名新增 numpy.typing as npt
  • 0.11.8:新增禁用 typing_extensions 相关导入建议的选项(对应 configuration.rsLintConfigurationtyping_extensions 字段,0.11.9 还修复了该设置缺少 combine 调用的 bug);配置选项中新增 Python 3.14target-version 可用 py314);
  • 0.11.9ruff analyze graph 允许传入虚拟环境。

规则行为变更与自动修复安全性收紧

0.11.x 系列体现了一个清晰的工程取向——把更多自动修复标记为“不安全(unsafe)”以避免破坏性变更,例如:

  • 0.11.7:FURB161(refurb)修复除整数字面量与布尔量外一律不安全;PLR1730 在删除注释时不安全;
  • 0.11.10:PIE804 在字典含注释时修复标记为不安全;
  • 0.11.12/0.11.13:UP010UP004UP050 在删除注释时标记为不安全;
  • 同期也有“放宽”方向:0.11.7 中 E712(冗余布尔比较)获得自动修复,PERF401 允许用推导式替换列表函数调用。

若你的 CI 使用 --fix 而非 --unsafe-fixes,这些安全性调整直接影响修复覆盖面,升级后值得对 diff 做一次抽查。

代表性 bug 修复

变更记录中篇幅最大的部分是 bug fixes,其中几类修复模式值得关注:

  • 文件描述符(fd)参数导致的误报:0.11.8–0.11.10 集中修复了 flake8-use-pathlib 一族规则(PTH104/PTH116/PTH123/PTH208 等)在函数参数是文件描述符时仍建议 Path 方法的误报,0.11.10 进一步推广为“对所有带 dir_fd 参数的 os.* 函数抑制诊断”;
  • 自动修复产生非法代码:如 SIM905rsplit 修复会产生反转的列表字面量(0.11.10 修复)、UP018 修复丢失空格或括号(0.11.7/0.11.9 修复)、FURB129 修复生成非法语法(0.11.12 修复);
  • 稳定性:0.11.1 中 Server 端在有版本特定语法错误时允许 FixAll 操作;0.11.3 中“从已删除目录运行 Ruff 时 panic!”改为正常报错。

升级建议

  • 如果从 0.10.x 或更早版本升级到 0.11.x,首要关注的是未配置 target-version 的项目:新推断机制可能改变 Ruff 实际使用的目标版本(尤其是目录中存在 pyproject.toml 但无 [tool.ruff] 段、且声明了 requires-python 的场景),从而改变部分版本相关规则(如 UP 系列 pyupgrade 规则)的触发行为。可用 ruff check --show-settings 查看解析后的 target-version 验证;
  • 使用 Airflow 相关规则码的项目,需对照 0.11.3 起的规则码迁移记录核对配置;
  • 依赖 ruff format 退出码的 CI 脚本,可考虑改用 --exit-non-zero-on-format 获得“有文件被改动即失败”的语义;
  • preview 相关的 syntax-errors 检测在整个 0.11.x 系列中持续变动且默认不启用,建议在稳定化之前不要在非 preview 流程中依赖其输出。

本系列变更记录的完整明细(含全部 PR 编号)见 changelogs/0.11.x.md,版本推断的现行文档表述见 docs/configuration.md

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
588
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
906
1.83 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.53 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.34 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
987
506
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384