首页
/ Ruff 0.1.x 版本演进深度解析:unsafe fixes 默认关闭、`ruff format` Beta 落地与 Preview 规则机制

Ruff 0.1.x 版本演进深度解析:unsafe fixes 默认关闭、`ruff format` Beta 落地与 Preview 规则机制

2026-09-05 19:01:48作者:田桥桑Industrious

本文以 Ruff 官方变更日志 changelogs/0.1.x.md 为主体,完整梳理 0.1.0 到 0.1.15 共 16 个版本的关键变更脉络,并结合仓库源码印证 0.1.x 周期最重要的三项机制:修复(fix)的三档适用性模型(Safe/Unsafe/Display)、ruff format 格式化器的 Beta 发布与逐步完善、以及 Preview 模式下的新规则孵化流程。读完后,你可以准确理解从 0.0.x 升级到 0.1.x 需要处理哪些破坏性变更、如何在项目中安全地启用 unsafe fixes、以及如何利用 extend-safe-fixes / extend-unsafe-fixes 按规则调整修复的激进程度。

0.1.x 版本链总览

changelogs/0.1.x.md 记录了 0.1.0 至 0.1.15 的完整变更历史,每个版本按固定维度组织:Breaking changes(破坏性变更)、Rule changes(规则行为调整)、Preview features(预览功能与新规则)、Configuration(配置项)、CLI(命令行)、Formatter(格式化器)、Bug fixes(缺陷修复)、Documentation(文档)与 Internals(内部实现)。几个标志性节点:

版本 标志性事件
0.1.0 首个使用 CHANGELOG 文件的版本;unsafe fixes 改为显式 opt-in;移除废弃的 format 设置
0.1.1 引入 lint.preview[format|lint].exclude 配置项
0.1.2 Ruff 格式化器 Beta 版随版本发布,ruff format 命令可用
0.1.3 格式化器批量消除与 Black 的已知偏差
0.1.4 引入按 Ruff 版本隔离的缓存目录、注释/字符串解析性能优化
0.1.5 RUFF_NO_CACHE 环境变量、隐藏 --extension 参数
0.1.6 flake8-banditpylintrefurb 等插件批量新增规则
0.1.7 ruff checkruff format 默认操作当前目录
0.1.8 通过 docstring-code-format 设置支持格式化 docstring 内代码片段
0.1.9 破坏性变更:默认排除 site-packages
0.1.10–0.1.15 持续补充 preview 规则(RUF021RUF022 等)与修复能力

0.1.x 周期的核心叙事是:Ruff 从一个“极快的 Python linter”扩展为“linter + 格式化器”双引擎产品,同时通过 Preview 机制为 0.2.x 稳定规则集蓄水。0.2.x 及以后版本见 changelogs/0.2.x.md

0.1.0:首个正式使用 CHANGELOG 的版本及其破坏性变更

变更日志开篇明确:0.1.0 是第一个使用仓库内 CHANGELOG 文件的发布,更早的变更条目位于 GitHub Releases;Ruff 同时启用了新的版本策略(仓库内对应 docs/versioning.md)。

移除废弃的 format 设置

0.1.0 删除了此前已废弃的 format 设置,并给出三条明确替代路径:

  • 配置层面:format 设置不能再用于配置输出格式,改用 output-format
  • 环境变量层面:RUFF_FORMAT 被忽略,改用 RUFF_OUTPUT_FORMAT
  • 命令行层面:ruff check--format 选项被移除,改用 --output-format

从源码结构看,这一替换在 CLI 层留下了完整的迁移痕迹:crates/ruff/src/args.rs 中仍保留了针对旧 --format 的弃用警告修复(0.1.0 条目 “Fix use of deprecated --format option in warning”),说明官方在移除过程中保证了过渡期用户能看到清晰的提示而非静默失败。

默认规则集收缩

“Drop formatting specific rules from the default set”(#7900)将纯格式化取向的规则从默认 lint 集合中移除。这与 0.1.2 引入 ruff format 的动作一脉相承:格式化职责交给专门的格式化器,linter 默认集合聚焦于静态检查,两者边界由此划清。

unsafe fixes 改为显式 opt-in

这是 0.1.x 周期影响面最大的行为变更:“Unsafe fixes are no longer displayed or applied without opt-in”(#7769)。其动机可在 docs/linter.md 中找到官方解释:某些修复即使语法正确,也可能改变运行时行为、移除用户注释,或改变异常类型从而破坏上游错误处理,因此这类修复必须被用户显式“认领”后才能显示和应用。

修复适用性模型:从 CLI 参数到源码实现

0.1.0 引入的 opt-in 机制并非孤立的 CLI 开关,而是一套贯穿配置、CLI、输出渲染的三档模型。

三档 Applicability

crates/ruff_diagnostics/src/fix.rs 中,Applicability 枚举定义了修复的三个级别,注释直接说明了各自语义:

  • DisplayOnly:修复不安全,仅用于展示供用户手动应用,可能产生错误意图或无效语法(对应 0.1.0 CLI 条目中重命名后的 Display 级别);
  • Unsafe:修复结果语法有效,但可能改变运行时行为或删除用户注释,需要用户 opt-in 才能应用;
  • Safe:修复可无条件应用,要么肯定是用户意图,要么完全保持代码语义,除非整条语句被移除否则保留注释。

docs/versioning.md 的 “Fix stabilization” 一节给出了同一模型的文档化表述:Display 永不应用、只展示;Unsafe 需显式 opt-in 才应用;Safe 自动应用。并且明确:降低某个修复的适用性(applicability)不算破坏性变更,而提升则遵循稳定化流程。

CLI 与配置入口

ruff check 侧的参数定义见 crates/ruff/src/args.rs--unsafe-fixes 使用 overrides_with 与隐藏的 --no-unsafe-fixes 互斥配对,解析后折叠为一个布尔结果。与 0.1.0 变更日志条目一一对应的是:

  • --unsafe-fixes:opt-in 显示并应用 unsafe fixes(#7769);
  • 配置项 unsafe-fixes 新增(#7769),允许在 pyproject.toml 中长期开启;
  • --fix 的默认行为随之变化:不再包含 unsafe 修复,help 文本也更新为 “Use --no-fix to disable or --unsafe-fixes to include unsafe fixes”。

输出提示与 per-rule 升降级

crates/ruff/src/printer.rs 中可以看到提示信息的渲染逻辑:当 UnsafeFixes 处于仅提示(hint)状态时,汇总消息会追加 “{n} hidden fix(es) can be enabled with the --unsafe-fixesoption” 字样,这正是变更日志中 “Update fix summary message incheck --diffto include unsafe fix hints”(#7790)的实现落点;而 “Renames applicability levels toSafe, Unsafe, and Display`”(#7843)则统一了文档与输出中的命名。

0.1.0 还配套提供了按规则调整修复安全性的配置项(#7841):extend-safe-fixes 将某条规则的修复提升为 safe,extend-unsafe-fixes 则降级为 unsafe。docs/linter.md 给出了可直接复制的示例:

[tool.ruff.lint]
extend-safe-fixes = ["F601"]
extend-unsafe-fixes = ["UP034"]

支持使用前缀选择整组规则,例如用 F 将 Pyflakes 所有规则的修复提升为 safe。0.1.5 进一步补全了该机制的边界情况:合并 extend-unsafe-fixesextend-safe-fixes 时会考虑选择器(selector)的特异性(#8444),避免同名规则在不同层级配置下升降级结果不一致。

0.1.2:ruff format Beta 版随包发布

变更日志对 0.1.2 的定性是:“This release includes the Beta version of the Ruff formatter — an extremely fast, Black-compatible Python formatter. Try it today with ruff format!”。围绕格式化器的 0.1.x 演进呈现出清晰的三阶段节奏:

Beta 发布(0.1.2)

0.1.2 的 Formatter 条目密度是整条 0.1.x 链中最高的之一,反映了 Beta 前的集中打磨:

  • line-ending 默认值改为 auto(#8057);
  • format 命令加入缓存(#8089),并进一步避免读取已命中缓存的文件(#8134);
  • 移除 --line-length 命令行选项(#8131),行宽统一由配置 line-length 驱动,同时补充了 line-length 文档中的格式化器说明(#8150);
  • 对与 linter 不兼容的旧格式化选项发出警告(#8088),并在 0.1.3 继续细化针对 isort.force-single-line 等具体场景的警告文案(#8192、#8244);
  • 移除实验性警告(#8148),完成从 “experimental” 到 “Beta” 的姿态切换;
  • 0.1.2 同时新增 ruff version 命令并支持长版本显示(#8034),以及配置项 pycodestyle.max-line-length(#8039)。

偏差消除(0.1.3)

0.1.3 的主题是 “removing several known and unintentional deviations from Black”(消除与 Black 的已知非故意偏差)。代表性修复包括:

  • None/True/False 的幂运算两侧不再添加空格(#8189);
  • 注解赋值中避免引入多余括号(#8233);
  • 类定义与前置注释之间插入必要的空行(#8224);
  • 仅当表达式以括号开头或结尾时才省略可选括号(#8238);
  • 使用源类型(source type)决定格式化解析模式(#8205),使 # fmt: skip/# fmt: off 场景下的解析更准确;
  • 为格式化器引入 preview 模式的测试与基础实现(#8044),为 0.1.4 起各版本中大量 “preview style” 条目奠定基础;
  • fmt: off 尾部子注释修复(#8234)、IPython escape command 的括号支持(#8207)。

0.1.3 还顺手修正了一个文档与实现不一致的问题:isort 的行宽判断改回使用 line-length 设置而非 pycodestyle.max-line-length(#8235)。

持续精修(0.1.4–0.1.9)

此后各版本持续收敛格式化器行为:

  • 0.1.4:fmt: off/fmt: skip 保留尾部分号(#8273、#8275)、避免将字节串误判为 docstring(#8350)、return 位置的元组优先按逗号拆分(#8280)、--line-length 选项回归 format 命令(#8363);
  • 0.1.5:多行 lambda 表达式语句的格式稳定性修复(#8466);
  • 0.1.6:await 链式调用的不稳定格式修复(#8676)、Notebook 尾部分号保留(#8590)、测试期间对比格式化前后 AST 的一致性(#8624);
  • 0.1.7:preview 风格的多行字典/列表 “hugging”(#8293)、类型别名的尾随注释内联(#8941)、单参数换行的函数插入尾逗号(#8921);
  • 0.1.9:dynamic 行宽模式下修复 doctest 超过配置行宽的问题(#9129)、can_omit_optional_parentheses 在右端含 f-string 时的修复(#9124)、target-version 进入格式化器选项(#9220)。

0.1.8:docstring-code-format 与文档代码片段格式化

0.1.8 引入了 opt-in 的 docstring-code-format 设置(#8854),允许格式化 docstring 中的 Python 代码片段。围绕该特性,同一版本还完成了配套能力:“dynamic” 行宽模式(#9098)、Markdown 代码块重排(#9030)、reStructuredText 代码片段支持(#9003),以及将 “preserve” 引号风格加入 preview(#8822)以对齐 Black 的 skip-string-normalization。这使 Ruff 成为少数能同时统一源码与文档内代码片段格式的工具。

Preview 机制:新规则的孵化器

变更日志中每个版本的 “Preview features” 小节,是观察 Ruff 规则演进的最佳样本。docs/versioning.md 的 “Rule stabilization” 一节规定了游戏规则:新规则一律先进 preview;preview 规则至少经历一个 minor 版本才有资格转正(例如 0.6.1 加入的规则,最早 0.8.0 才能稳定);preview 期内行为可能随时调整甚至移除。

从 0.1.x 的 preview 条目可以归纳出三条孵化轨迹:

  1. 既有插件的补齐pylint 插件在 0.1.1–0.1.15 间连续落地了 PLR6201PLR0916E0704W0604PLW1514(0.1.1),PLR1704W0108 修复(0.1.6),PLR1733PLe1132PLR0917PLR1736(0.1.7),PLR0914(0.1.9)直至 E0237PLE0643PLR1702(0.1.15);flake8-bandit 则在 0.1.12 一次性引入 S4XX 可疑导入系列(#8831)与 SSL 系列规则(S502/S503/S504,#9384–#9391)。
  2. Ruff 自有规则(RUF 前缀)的扩展。0.1.12 新增 RUF021parenthesize-chained-operators,强制 a or b and c 加括号,#9440)与 RUF011 的变量键支持(#9411);0.1.14 新增 RUF022__all__ 排序,#9474);0.1.15 则加入了 RUF024mutable-fromkeys-value)、RUF025(无必要的 dict 推导)、RUF026default_factory 位置守卫)与 __slots__/__match_args__ 排序规则(#9564)。
  3. 修复能力的 preview 先行。大量条目以 “Add fix for …” 形式出现,例如 0.1.6 为 E221E228E271/E272 系列补充修复(#8622、#8623),0.1.14 为 B033SIM113PGH002TRY400 补充修复,0.1.15 一次性覆盖 flake8-returnRET505RET508 全家族(#9595)。按 docs/versioning.md 的规则,preview 期新增 safe fix 只触发 patch 版本号,这也解释了 0.1.x 各 patch 版本为何条目繁密却不提升 minor。

0.1.15 还出现了一条机制性条目:当 NURSERY 选择器与 --preview 同时使用时直接报错(#9682),体现了 preview 选择器语义在 0.1.x 末尾的收紧——0.1.0 已将其调整为“仅在启用规则时对空 preview 选择器给出警告”(#7842)。

0.1.9 破坏性变更:默认排除 site-packages

0.1.x 周期中唯一的独立 “Breaking changes” 小节出现在 0.1.9:“Add site-packages to default exclusions”(#9188)。对扫描目录包含依赖环境(如虚拟环境、node_modules 式 vendored 代码)的项目,升级后这些路径默认不再进入 lint/format 流程。从变更日志的表述看,这是一次默认扫描范围的收缩,属于 docs/versioning.md 中 “Configuration changes in a backwards incompatible way” 触发 minor 升版的典型情形——但 Ruff 将其放进了 patch 版本,属于 0.x 阶段版本策略下的特例,升级时值得单独核对 exclude 配置。

缺陷修复中的高频主题

浏览 0.1.x 的 “Bug fixes” 小节,可以归纳出四个反复出现的修复主题,它们恰好对应 Ruff 的四个解析子系统:

  1. f-string 与 PEP 701 新词法器。0.1.0 修复了 match 模式字面量中误允许 f-string(#7857)、f-string 内花括号转义(#7780)、单引号 f-string 多行 format spec 的词法(#7787);0.1.4 处理了未终止 f-string(#8154)与 r/f 前缀顺序(#8464);0.1.7 修复了 ur 字符串前缀导致的语法错误(#8971)。
  2. Notebook 支持。0.1.0 为 JSON 输出新增 cell 字段(#7664);0.1.4 支持 Jupyter automagics 检测(#8398);0.1.7 让 E402 在 cell 级别工作、E703/B015/B018 豁免 cell 尾表达式(#8821、#8815、#8872);0.1.12 为所有诊断补充 cell 索引(#9387);0.1.14 起 Notebook 格式化生成确定性 ID(#9359)。
  3. 类型系统相关规则的误报治理flake8-type-checking 系列在 0.1.6–0.1.15 间连续修正:订阅式基类的 TYPE_CHECKING 判定(#7954 的后续修复)、typing_extensions 全成员视为 typing 别名(#9335)、Pydantic BaseConfig/BaseSettings 的默认拷贝语义(#8793、#9650)、InitVar 不再标记为 typing-only(#9688)。
  4. 修复(fix)自身的安全性。0.1.2 将 B006mutable-argument-defaults)与 PLR6201literal-membership)的修复降级为 unsafe(#8097、#8108);0.1.8 允许 flake8-type-checking 规则自动为运行时求值引用加引号(#6001);0.1.10 对自动加引号修复做了防嵌套引号与编辑去重处理(#9168、#9140)。这些条目共同说明:在 0.1.x 周期中,“修复的适用性标注”本身成为了一类被持续审计的对象。

内部实现与性能条目

0.1.4 的 Internals 小节是观察 Ruff 工程结构的一个窗口:按 Ruff 版本隔离缓存目录(#8333)、为 --fix--diff 启用选择性缓存(#8316)、注释解析(#8193)与字符串解析(#8227)的性能优化、为 isort 引入专用排序键(#7963)。0.1.14 则改进 --show-settings 的可读性输出(#9464),0.1.15 为动态配置项生成专用 JSON schema(#9632)。此外 0.1.5 支持通过 RUFF_NO_CACHE 环境变量禁用缓存(#8538),0.1.10 为 TOML 解析错误补充文件路径(#9358)、为格式化器解析错误补充行列号(#9321),显著提升了配置排错体验。

升级 0.1.x 的实操核对清单

结合变更日志与 docs/linter.mddocs/configuration.md 中的说明,从 0.0.x 升级到 0.1.x 时建议按以下顺序核对:

  1. 移除 format 设置:配置中的 format 改为 output-format,环境变量 RUFF_FORMAT 改为 RUFF_OUTPUT_FORMAT,命令行 --format 改为 --output-format
  2. 确认 unsafe fixes 行为:默认不再显示/应用 unsafe 修复。若工作流依赖自动修复激进规则,显式启用:
    # 仅显示 unsafe fixes
    ruff check --unsafe-fixes
    
    # 显示并应用 unsafe fixes
    ruff check --fix --unsafe-fixes
    
    或在配置中长期开启 unsafe-fixes = true;若希望连提示都关闭,设为 false 或传 --no-unsafe-fixes
  3. 按需微调修复安全性:用 lint.extend-safe-fixes / lint.extend-unsafe-fixes 按规则(或规则前缀)升降级,参考 0.1.2 中修复过的示例文档(#8139);
  4. 检查 exclude 与默认规则集:格式化取向规则已移出默认集合,依赖它们的用户需显式 --select;0.1.9 起 site-packages 默认排除,必要时用 0.1.1 引入的 [format|lint].exclude(#8000)或全局 exclude 精确控制,--force-exclude 在 0.1.4 起对二者均生效(#8393);
  5. 格式化器迁移:若此前使用 Black,可用 ruff format --check(0.1.9 起对已格式化文件给出明确消息,#9153)对比差异,再结合 0.1.1 引入的 --target-version(#8055)与 --diff(#7937)选项做灰度切换;
  6. 关注 JSON 输出消费者:诊断输出新增了 cell 字段(0.1.0,#7664)与 applicability 字段语义重命名(0.1.0,#7843),json 格式下所有修复始终展示、安全级别可从 applicability 字段读取(docs/linter.md)。

小结

0.1.x 是 Ruff 从 0.0.x 走向 1.0 的第一段正式航程:0.1.0 确立了 “CHANGELOG + 版本策略 + 修复三档适用性” 的工程基线,0.1.2 让 ruff format Beta 版进入发行包,其后九个 patch 版本则围绕“消除与 Black 的偏差”“Preview 规则孵化”“修复安全性审计”三条主线高频迭代。理解这一周期,关键在于把握两个贯穿始终的机制:修复适用性模型(源码见 crates/ruff_diagnostics/src/fix.rs)与 Preview 稳定化流程(策略见 docs/versioning.md)——前者决定 --fix 的边界,后者决定你在任何 patch 版本中会看到哪些“即将转正”的新规则。

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

项目优选

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