首页
/ Ruff 0.5.x 版本演进全解:规则重映射、输出格式变更与语言服务器稳定化

Ruff 0.5.x 版本演进全解:规则重映射、输出格式变更与语言服务器稳定化

2026-09-05 11:53:28作者:虞亚竹Luna

本篇技术指南基于 Ruff 仓库中的 0.5.x 版本变更记录,系统梳理 Ruff 0.5.0 至 0.5.7 的完整演进脉络:从 0.5.0 引入的破坏性变更(XDG 配置发现、ALL 选择器行为、规则代码重映射)、29 条预览规则的稳定化、废弃配置与 CLI 选项的移除,到 0.5.3 语言服务器(native server)的稳定发布和 0.5.6 预览模式下 Notebook 默认启用。读完本文,你将掌握升级到 0.5.x 需要做的全部配置迁移,以及每个次要版本中规则行为、解析器、服务端与性能层面的具体改动,并能结合仓库源码验证关键机制的实现位置。

0.5.0:一次面向长期稳定性的重大版本

0.5.0 是 0.5.x 系列中唯一包含破坏性变更的版本。官方将其定位为一个"里程碑式"的发布:一方面清理了此前积累的废弃配置与命令,另一方面通过规则重映射(remapping)让 flake8-async 与 flake8-trio 两个插件体系合流,并对大量预览期规则进行了稳定化。

破坏性变更

0.5.0 的破坏性变更共有五项,升级时需要逐一确认:

  • macOS 用户级配置遵循 XDG 规范:与其他 Unix 平台一致,macOS 上用户级配置的发现路径改为遵循 XDG 规范。这意味着原先依赖 macOS 专属路径(如 ~/Library/Application Support)存放用户配置的使用方式不再适用。
  • ALL 选择器排除已废弃规则:此前 select = ["ALL"] 会包含所有规则,0.5.0 起该选择器不再选中处于 deprecated 状态的规则。如果你在配置中使用 ALL,升级后部分规则会"静默消失",需要显式确认。
  • 发布压缩包多了一层目录嵌套:下载的发行归档内部多了一个目录层级,解压时需要用 --strip-components=1 去除,否则二进制会落在多一层子目录中。
  • 发布产物文件名不再包含版本号:这一改动允许用户通过 GitHub 的 /latest 相对 URL 直接安装最新版,简化了安装脚本。
  • 部分 flake8-bandit 规则的诊断范围(diagnostic range)被调整:与 shell 相关的 bandit 规则高亮位置发生了变化(对应 PR #10667),依赖精确诊断范围做二次处理的工具需要回归验证。

规则废弃:syntax-error(E999)

0.5.0 起,规则 syntax-error(代码 E999)被标记为废弃。原因是语法错误从此总是会被显示——解析器报错直接成为诊断输出的一部分,不再需要通过选择 E999 来"打开"这一能力。这一改动在 0.5.1 中还得到了配套完善:token 级别的规则可以在存在语法错误的源码上继续运行(PR #11950),且当源码存在语法错误时会自动禁用 autofix(PR #12134),避免在不完整 AST 上产生错误修复。

规则重映射:TRIO 并入 ASYNC,ASYNC10x 拆分为 ASYNC2xx

这是 0.5.0 对现有用户影响最大的一组改动。flake8-trio 的规则被整体并入 flake8-async,同时原来含义混杂的 ASYNC100~ASYNC102 被拆分为更精确的 ASYNC2xx/ASYNC25x 系列。完整映射表如下:

规则 原代码 新代码
blocking-http-call-in-async-function ASYNC100 ASYNC210
open-sleep-or-subprocess-in-async-function ASYNC101 拆分为 ASYNC220ASYNC221ASYNC230ASYNC251
blocking-os-call-in-async-function ASYNC102 合并进 ASYNC220ASYNC221
trio-timeout-without-await TRIO100 ASYNC100
trio-sync-call TRIO105 ASYNC105
trio-async-function-with-timeout TRIO109 ASYNC109
trio-unneeded-sleep TRIO110 ASYNC110
trio-zero-sleep-call TRIO115 ASYNC115
repeated-isinstance-calls PLR1701 SIM101

从源码结构看,这些重定向并非仅在文档层面存在:仓库中维护了一张集中式的重定向表 rule_redirects.rs,其中明确标注了 TRIOASYNC1 的前缀级重定向(TRIO100ASYNC100TRIO105ASYNC105TRIO109ASYNC109TRIO110ASYNC110TRIO115ASYNC115)以及 PLR1701SIM101 的条目(源码注释中标记为 "Removed in v0.5")。这张表通过 get_redirect_target 在解析 select/ignore 中的旧代码时生效——只要你在配置里写的是旧代码,Ruff 会自动按新代码处理,但变更记录同时提醒:重映射可能导致原本被禁用的规则变为启用状态(例如原 ignore = ["ASYNC100"] 现在对应 ASYNC210,而新拆出的 ASYNC220/ASYNC221/ASYNC230/ASYNC251 不再被该条目覆盖)。

拆分后的新规则在源码中一一对应:blocking_http_call.rs 产出 ASYNC210blocking_process_invocation.rs 产出 ASYNC220/ASYNC221blocking_open_call.rs 产出 ASYNC230blocking_sleep.rs 产出 ASYNC251(见 crates/ruff_linter/src/rules/flake8_async/)。

规则稳定化:29 条规则脱离预览

0.5.0 将以下规则从 preview 转为稳定(稳定化后其行为不再随 preview 开关变化,可放心用于生产配置):

  • Ruff 自有规则:mutable-fromkeys-valueRUF024)、default-factory-kwargRUF026
  • flake8-bandit:django-extraS610
  • Perflint:manual-dict-comprehensionPERF403
  • Refurb:print-empty-stringFURB105)、readlines-in-forFURB129)、if-expr-min-maxFURB136)、bit-countFURB161)、redundant-log-baseFURB163)、regex-flag-aliasFURB167)、isinstance-type-noneFURB168)、type-none-comparisonFURB169)、implicit-cwdFURB177)、hashlib-digest-hexFURB181)、list-reverse-copyFURB187
  • Pylint:bad-open-modePLW1501)、empty-commentPLR2044)、global-at-module-levelPLW0604)、misplaced-bare-raisePLE0744)、non-ascii-import-namePLC2403)、non-ascii-namePLC2401)、nonlocal-and-globalPLE0115)、potential-index-errorPLE0643)、redeclared-assigned-namePLW0128)、redefined-argument-from-localPLR1704)、repeated-keyword-argumentPLE1132)、super-without-bracketsPLW0245)、unnecessary-list-index-lookupPLR1736)、useless-exception-statementPLW0133)、useless-with-lockPLW2101

同时,五条既有规则的行为调整也在 0.5.0 完成稳定化:

  • is-literalF632):现在对 list、set、dict 字面量做 is/is not 身份检查也会告警
  • needless-boolSIM103):现在能检测隐式 else 分支的 if 表达式
  • module-import-not-at-top-of-fileE402):现在允许在导入语句之间修改 os.environ
  • type-comparisonE721):现在允许 type(x) is int 这类惯用写法
  • yoda-conditionSIM300):现在覆盖更宽范围的表达式

废弃配置与命令的移除

0.5.0 按既定流程移除了所有标记为 deprecated 的配置项、CLI 选项与命令形态,替代关系如下:

已移除的废弃配置项

移除项 替代方案
output-format = "text" output-format = "concise"output-format = "full"
tab-size indent-width

已移除的废弃 CLI 选项

移除项 替代方案
--show-source --output-format=full
--no-show-source --output-format=concise

已移除的废弃 CLI 命令形态

移除项 替代方案
ruff <path> ruff check <path>
ruff --clean ruff clean
ruff --generate-shell-completion ruff generate-shell-completion

配置查找与解析的实现集中在 crates/ruff_workspace/src/pyproject.rscrates/ruff_workspace/src/options.rs,其中说明了 pyproject.tomlruff.toml.ruff.toml 三种配置文件形态及其在解析范围(respect-gitignore 相关的 respected_extensions 默认列表)中的处理——0.5.0 起这三种形态的匹配行为是稳定契约的一部分。

CLI 与输出格式:full 成为默认值

0.5.0 对 CLI 输出做了三处调整:

  • --statistics 统计改用规则名而非诊断消息作为聚合维度(PR #11697),统计结果对不同代码风格更加稳定;
  • 默认输出格式从简洁模式切换为 full(PR #12010),即诊断默认附带源码代码框(code frame),不再需要 --show-source
  • 语法错误不再重复打印到控制台日志(PR #11902),避免诊断与日志双份刷屏。

这一默认值在源码中有直接体现:OutputFormat 枚举将 Full 标记为 #[default],并列出全部 13 种取值(concisefulljsonjson_linesjunitgroupedgithubgitlabpylintrdjsonazuresarif 等),同时提供 is_human_readable 判定来决定是否输出页头/页脚(见 settings/types.rs)。如果 CI 中依赖旧的简洁输出做文本比对,升级后应显式加 --output-format=concise

0.5.0 的其他改动

预览功能:新增 assert-with-print-message 规则(PR #11981),检测在 assert 中使用 print 附带消息的反模式。

规则修正

  • Ruff 自有:修复 gettext 通过别名导入时 RUF027 的误报(PR #12025)
  • NumPy:更新 NPY201trapzin1d 的弃用判定(PR #11948)
  • flake8-bandit:调整 shell 相关规则的诊断范围(PR #10667)

解析器修复(6 项,均影响错误恢复与诊断范围精度):

  • 空类型参数列表(如 def f[]() -> None)现在正确报语法错误(PR #12030)
  • 未终止字符串不再吞掉换行符(PR #12067),且错误范围不再包含换行(PR #12017)
  • 行续接错误的定位使用正确的范围(PR #12016)
  • 行续接前的 2 字符行尾(如 CRLF)被正确处理(PR #12035)
  • 重新词法分析(re-lexing)时考虑行续接字符(PR #12008)

其他:用于度量 line-length 的 Unicode 表升级(PR #11194);移除 nursery 选择器的弃用报错(PR #10172)。

0.5.1:语法错误处理与缓存正确性

0.5.1 是紧随 0.5.0 的修复版本,重点围绕"存在语法错误时的行为"与缓存正确性。

预览功能

  • flake8-bugbear 新增 mutable-contextvar-defaultB039)(PR #12113)
  • pycodestyle 新增装饰器后空白规则(E204)(PR #12140)
  • pytest 插件交换了 PT001PT0023 的默认状态(PR #12106)

规则修正

  • 存在语法错误的源码上启用 token 级规则(PR #11950)
  • flake8-bandit 的 S113 现在能识别 httpx(PR #12174)
  • NPY201 覆盖异常类弃用项(PR #12065)
  • PLE0241duplicate-bases)新增 autofix(PR #12105)

服务端

  • 源码动作(source code actions)不再触发语法错误通知(PR #12148)
  • Notebook 同步时考虑新单元格内容(PR #12203)
  • 修复替换编辑范围计算(PR #12171)

Bug 修复(关键项):

  • 源码含语法错误时禁用 autofix(PR #12134)
  • 修复含分隔符路径的缓存键碰撞(PR #12159)——这是 0.5.0 缓存键实现的缺陷修复,影响 Windows 与 POSIX 混用路径的场景
  • requires-python 推断对 == 约束更健壮(PR #12091)
  • 宽度计算改用逐字符(char-wise)宽度而非 str 宽度(PR #12135)
  • pycodestyle:关键词后跟逗号或分号时不再误报 E275(PR #12136、PR #12095)
  • pylint:PLR1704 跳过哑变量(dummy variables)(PR #12190)

性能parse_identifier 去分配化(PR #12103);Identifier AST 节点改用 CompactString 存储(PR #12101)——AST 节点内存布局优化的首批实践。

0.5.2:async 规则覆盖面扩展与 Windows 缓存容错

预览功能ASYNC100ASYNC109ASYNC110ASYNC115ASYNC116 五条规则统一扩展为覆盖 anyioasyncio 命名空间(PR #12221、#12236、#12261、#12262、#12266);formatter 在带前导注释的推导式中,对括号表达式使用 space 分隔符(PR #12282)。

规则修正RET501 将 property 从显式返回检查中豁免(PR #12243);NPY201 增加 np.NANnp.nan 诊断(PR #12292);FURB187list-reverse-copy)的 autofix 改为 unsafe 标记(PR #12303)。

服务端:native server 开始考虑 includeextend-include 设置(PR #12252),并在设置重载时纳入嵌套配置(PR #12253)——这直接服务于 options.rs 中定义的文件包含/排除契约。

CLI:修复(fix)范围为空时省略代码框(PR #12304);对 D203(与 formatter 的空白行策略冲突)给出 formatter 不兼容警告(PR #12238)。

Bug 修复(关键项):

  • Windows 上缓存写入失败不再致命(PR #12302)
  • not 运算被视为布尔测试(影响若干以布尔上下文为判定条件的规则)(PR #12301)
  • flake8-bandit:HTTP 安全的 f-string 不再误报 S310(PR #12305),S310 支持显式字符串拼接的 URL 检测(PR #12315),无 timeout 参数的 httpx 调用不再误报 S113(PR #12213)
  • pycodestyle:移除 E721 的"非显而易见"豁免(PR #12300)
  • pyflakes:with 块被视为单条目分支参与重定义分析(PR #12311)
  • refurb:open()newline 参数转发修复限制在 Python ≥ 3.10(PR #12244)

其他:文档与帮助文本更新以反映 --output-format full 默认值(PR #12248);Python 文件发现使用更多线程(PR #12258)。

0.5.3:Ruff 语言服务器稳定发布

0.5.3 的标志性事件是 Ruff 语言服务器(native server)的正式稳定,配套的编辑器文档同步重构,包括编辑器安装指南与服务端设置参考(文档迁移至独立文档仓库,PR #12341;服务端文档 PR #12344;编辑器集成版本策略更新 PR #12375)。仓库内 crates/ruff_server/ 即该服务器的实现,其中 README.mdCONTRIBUTING.md 说明了其开发方式。

预览功能:formatter 在函数/类定义后、suite 与备选分支之间插入空行(PR #12294);pyupgrade 新增 unnecessary-default-type-argsUP043)(PR #12371)。

规则修正

  • B909loop-iterator-mutation)检测 enumerate 迭代中的迭代器变更,并移除对 discard/remove/pop 的豁免(PR #12366、#12365)
  • PLR1714 允许混合运算下的重复等值比较(PR #12369)
  • PLR0913 统计参数个数时忽略 self/cls(PR #12367)
  • PLW1514 的 autofix 默认使用 UTF-8 编码(PR #12370)

服务端

  • 原生服务器并行构建设置索引(PR #12299)
  • 索引项目时使用回退设置(PR #12362)
  • server 子命令开始接受 --preview 标志以分别控制 linter 与 formatter 的预览模式(PR #12208)

Bug 修复C419 允许 sum/max 推导式的额外参数(PR #12364);PLR1714 修复 autofix 丢弃多余布尔运算(PR #12368);PLR1704 在判定绑定类型时考虑语句前的表达式(PR #12346)。

其他:Wasm API 发布到 npm(PR #12317),对应仓库中的 crates/ruff_wasm/

0.5.4 与 0.5.5:命名修正与 FastAPI/pydoclint 预览

0.5.4 体量较小,核心是命名与修复质量:

  • RUF007 更名为 zip-instead-of-pairwise(PR #12399),名称更贴合规则意图
  • flake8-builtins 不再对 @override 方法报遮蔽诊断(PR #12415)
  • flake8-comprehensions 的 autofix 为多参生成器插入括号(PR #12422)
  • pydocstyle 处理 docstring 内部转义(D301,PR #12192)
  • 文档修正:Neovim 安装链接、设置参考中 output-format 默认值(PR #12409、#12410)

0.5.5 引入了两组新的预览规则,并修复 formatter 注释定位问题:

  • FastAPI 插件首发:fastapi-redundant-response-modelFAST001)与 fastapi-non-annotated-dependencyFAST002)(PR #11579)
  • pydoclint 新增 docstring-missing-exceptionDOC501)与 docstring-extraneous-exceptionDOC502)(PR #11471)
  • NumPy:修复 np.alltrue/np.sometrue 的 2.0 规则(PR #12473);except 块内忽略 NPY201 以兼容旧版 NumPy(PR #12490)
  • pep8-naming:ignore-names 不再作用于 self/cls 函数名(N804/N805,PR #12497)
  • formatter:修复带类型参数函数的前导注释错位(PR #12447)
  • Bug 修复:cmp_fixOrd 实现修正(PR #12471);多参调用中未加括号的生成器表达式报语法错误(PR #12445);DOC501 的 panic 修复(PR #12435);B013 允许含星号表达式的单元素元组(PR #12484)
  • 文档新增 Emacs/Eglot、Zed 编辑器安装指南,以及 nvim-lspconfig 破坏性变更说明(PR #12426、#12501、#12507)

0.5.6 与 0.5.7:Notebook 预览启用与 pydoclint 完善

0.5.6 的核心变化:预览模式下默认启用 Notebook 的 lint 与 format。这是对 0.5.x 服务端 Notebook 支持工作的收束。如需退出该行为,在配置中将 *.ipynb 加入 extend-exclude 即可:

[tool.ruff]
extend-exclude = ["*.ipynb"]

同版本还包括:

  • 预览规则:flake8-builtins 实现 import/lambda/module 遮蔽检测(PR #12546);pydoclint 新增 docstring-missing-returnsDOC201)与 docstring-extraneous-returnsDOC202)(PR #12485)
  • RET501 将缓存型 property 及类似 property 的装饰器豁免出显式返回检查(PR #12563)
  • 服务端:panic hook 增强容错(PR #12610);Zed 与 VS Code 使用 $/logTrace 输出服务端追踪日志(PR #12564);为单元格重排请求记录已删除单元格(PR #12575)
  • flake8-implicit-str-concat:禁止隐式拼接时始终允许显式多行拼接(PR #12532)
  • Bug 修复重点:isort 不再把必需导入标记为未使用(PR #12537)、保留 import-from 行尾内联注释(PR #12498);pycodestyle E305 补换行、错缩进注释不附带(PR #12606、#12604);pyflakes 预览模式下 __init__.py 中一方子模块 F401 自动修复缺陷(PR #12569);pyupgrade 避免对 slots=True dataclass 建议无参 super(PR #12530);移除未使用导入时的 NFKC 规范化 Bug(PR #12571)
  • 其他:更多标准库装饰器被认定为 property 风格(PR #12583)、元类在各规则中的处理改进(PR #12579)、"函数是否 property"的判定在各规则间保持一致(PR #12581)

0.5.7 继续完善 pydoclint 家族与修复质量:

  • 预览:C409 考虑列表/集合推导(PR #12657);PYI044 新增 autofix(PR #12676);RET505 autofix 处理混合缩进避免语法错误(PR #12740);pydoclint 新增 docstring-missing-yieldsDOC402)与 docstring-extraneous-yieldsDOC403)(PR #12538),并处理了 stub 函数豁免、"Returns" 开头的 docstring 豁免、re-raise 视为显式抛出等 5 处语义细节(PR #12651、#12675、#12642、#12639);新增 RUF031incorrectly-parenthesized-tuple-in-subscript)(PR #12480);RUF023__slots__ 非集合且绑定被别处使用时将修复标记为 unsafe(PR #12692)
  • 规则修正:FURB177implicit-cwd)与 RUF007zip-instead-of-pairwise)均新增 autofix(PR #12708、#12663);TRY002BaseException 纳入 raise-vanilla-class(PR #12620)
  • CLI:修复嵌套 pyproject.toml 的缓存失效问题(PR #12727)
  • Bug 修复重点:ASYNC100async with 项误报(PR #12643);S608 列表拼接构造 SQL 的误报(PR #12720);B909return 视为等价于 break(PR #12646);C419sum 接受集合推导(PR #12691);SIM114 合并 if 分支时按优先级加括号(PR #12737);DOC501 在未指定约定时尝试两种 Raises 段落风格(PR #12649)

升级实践小结

基于 0.5.x 的完整变更记录,升级时需要检查的事项可以归纳为:

  1. 检查 select/ignore 中的旧代码TRIO* 系列与 ASYNC100/ASYNC101/ASYNC102/PLR1701 会命中 rule_redirects.rs 中的重定向表自动换算,但拆分/合并类映射(ASYNC101 → 四条新规则、ASYNC102 → 并入 ASYNC220/ASYNC221)可能改变实际启用的规则集合,建议用 ruff check --statistics 对比升级前后结果;
  2. 检查 ALL 选择器:0.5.0 起 ALL 不再包含废弃规则,如依赖 E999 需显式改为依赖语法错误直出;
  3. 替换被移除的配置与命令:按上表将 output-format=texttab-size--show-source 及三种旧命令形态迁移到新写法,CI 输出文本比对需显式指定 --output-format
  4. 确认 Notebook 策略:若启用 --preview,0.5.6 起 Notebook 默认参与 lint/format,不需要时用 extend-exclude = ["*.ipynb"] 排除;
  5. 验证诊断范围依赖:使用 flake8-bandit shell 相关规则(S603/S604 等)并依赖精确高亮位置的下游工具,需对 0.5.0 的诊断范围调整做回归。

0.5.x 系列整体展示了 Ruff 的演进方法论:破坏性变更集中于 0.5.0 一次性兑现(并有重定向表兜底旧代码),0.5.1–0.5.7 则以"行为细化 + 修复质量 + 服务端能力"为主线小步推进。后续的 0.6.x 变更记录 在此基础之上继续,可作为对照参考。

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

项目优选

收起
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.79 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
988
506
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384