Ruff v0.16.0 发布:默认规则从 59 条增至 413 条,提供更全面的 Python 代码检查
Ruff v0.16.0 现已发布!可通过 PyPI 或你偏好的包管理器安装:
uv tool install ruff@latest
提醒一下:Ruff 是一个用 Rust 编写的极速 Python 代码检查器和格式化工具。 它可以替代 Black、Flake8(及其数十个插件)、isort、pydocstyle、pyupgrade 等工具,而执行速度比任何单个工具快数十倍甚至数百倍。
迁移到 v0.16 #
Ruff v0.16 包含少量破坏性变更,大多数用户无需大幅修改代码或配置即可升级。主要例外情况如下。
更好的默认规则集 #
Ruff 现在默认启用 413 条规则,而之前版本只有 59 条。
自 v0.1.0 最后一次修改默认规则集以来,Ruff 的规则总数从 708 条增长到 968 条。其中许多规则能捕获严重问题,包括 语法错误 和 即时运行时错误,但之前并未默认启用。有了新的规则集,即使不配置 Ruff,它也会让你注意到这些问题及其他许多问题。即使你已经在使用 select 或 extend-select,我们也希望这能让你注意到之前未发现的有用规则。
启用的规则完整列表太长,无法在此列出,但你可以查阅我们文档中新增的 默认规则 页面。其中一些亮点包括来自流行的 flake8-bugbear (B) 和 pyupgrade (UP) 检查器的规则,以及我们自己的 RUF 类别中的规则。
如果你想恢复到旧的默认规则集,可以使用以下配置轻松 select 旧规则:
[lint]
select = ["E4", "E7", "E9", "F"]
我们认为这项工作与我们长期推进的规则重分类目标紧密相关,期待该领域后续发展。
v0.16 新功能 #
此外,Ruff v0.16 还稳定了多项新功能,重点介绍如下。
Markdown 代码块格式化 #
Ruff 现在可以格式化 Markdown 文件中嵌入的 Python 代码块。
对于这些文件,Ruff v0.16 会格式化带有 python、py、python3、py3、pyi 或 pycon info string 的围栏代码块。pyi 代码块按存根文件格式处理,pycon 按 REPL 会话处理,其余则按普通 Python 文件格式化。例如:
# README
Here's an example:
```py
import ruff
ruff_binary = (
ruff.find_ruff_bin()
)
```
运行 ruff format 后,上述代码会被重新格式化:
这一功能同样适用于格式化 Quarto 笔记本,因为 Ruff 仍能识别花括号内的语言标识(如 ```{python})。注意,如果 Quarto 文件使用 .qmd 扩展名,你可能需要配置 extension 映射。
如果需要禁用格式化,有多种方式。若希望抑制注释出现在代码块内,可以在代码块内使用常规的 fmt: off 和 fmt: on 注释,或使用类似的 HTML 注释禁用文档的整个区域:
# README
<!-- fmt: off -->
```py
x = "this will be suppressed"
```
<!-- fmt: on -->
若想完全禁用 Markdown 格式化,可通过常规的 extend-exclude 设置,用 *.md 这样的 glob 排除所有 Markdown 文件。
更多详情请参阅完整文档。
ruff: ignore 注释新增抑制功能 #
Ruff 现在拥有自己的抑制注释格式,可以单独一行使用。
在 v0.15 中,Ruff 的 lint 工具通过配对使用 ruff: disable 和 ruff: enable 注释实现了范围抑制机制,类似于上文提到的 fmt: off 和 fmt: on 配对:
# ruff: disable[N803]
def foo(
legacyArg1,
legacyArg2,
legacyArg3,
legacyArg4,
): ...
# ruff: enable[N803]
Ruff v0.16 在此基础上新增了两种 ruff 抑制注释。ruff: ignore 可用于抑制同一行(类似 noqa)或下一逻辑行中的诊断信息:
import math # ruff: ignore[F401]
# ruff: ignore[N803]
def foo(
legacyArg1,
legacyArg2,
legacyArg3,
legacyArg4,
): ...
在此例中,逻辑行跨越了整个函数头(从 def 到冒号),因此 ruff: ignore 抑制了与上面 disable/enable 配对相同的所有 N803 诊断。
ruff: file-ignore 注释可用于抑制整个文件的诊断,类似于 ruff: noqa 注释:
# ruff: file-ignore[F401] Allow unused imports in this file
import foo
import bar
import baz
本例还展示出,每种注释都可以附带一个"原因"来说明添加理由,此处为 Allow unused imports in this file。
使用新的 --add-ignore CLI 标志可以自动添加 ruff: ignore 注释,并且在预览模式下,所有这些 ruff 抑制注释都支持使用规则名称而非代码:
❯ echo 'import math' > try.py
❯ uvx ruff@latest check --preview --add-ignore try.py
Added 1 ignore comment.
❯ cat try.py
import math # ruff: ignore[unused-import]
以上所有注释的完整规范可在文档中找到。
修复内容现显示在 check 和 format --check 输出中 #
Ruff 现在在呈现诊断信息时会显示 linter 和 formatter 修复的 diff。
check 和 format 子命令一直支持通过 --diff 标志显示应用 check --fix 或 format 修复后引入的更改,但这种方式独立于正常输出,并且会抑制附带的解释性诊断信息。在 v0.16 中,可用的修复现在作为默认 full 输出格式的一部分显示,位于 help 子诊断下方:
format --check 也是如此。给定以下输入:
# example.py
if True:
pass
elif False:
pass
格式化程序生成:
format --check 现在也支持 linter 支持的所有输出格式。例如,你可以用它来获取机器可读的 JSON 输出,或生成 GitHub 和 GitLab 在 CI 中渲染注释所需的格式。完整的支持格式列表请参阅 CLI 帮助或文档。
关于输出格式的最后一点说明:v0.16 对 JSON 输出引入了一个小的不兼容变更。filename、location、end_location、fix.edits[].location 和 fix.edits[].end_location 字段现在可能为 null,而不是分别默认为空字符串和行 1、列 1。这应该会影响很少的 Ruff 现有诊断,但能更好地反映内部诊断表示,并且未来规则中可能会更常见。
规则稳定化 #
以下规则已稳定,不再处于预览状态:
airflow3-incompatible-function-signature(AIR303)missing-copyright-notice(CPY001)unnecessary-from-float(FURB164)sorted-min-max(FURB192)implicit-string-concatenation-in-collection-literal(ISC004)log-exception-outside-except-handler(LOG004)invalid-bool-return-type(PLE0304)too-many-positional-arguments(PLR0917)stop-iteration-return(PLR1708)none-not-at-end-of-union(RUF036)access-annotations-from-class-dict(RUF063)duplicate-entry-in-dunder-all(RUF068)
其他行为稳定化 #
本次发布还稳定了其他一些此前仅存在于预览模式中的行为:
blind-except(BLE001)现在会在异常通过除critical、error和exception之外的logging方法记录时被抑制。
future-required-type-annotation(FA102)现在会检查更多兼容 PEP 585 的 API,例如 collections.abc 中的接口。f-string-in-get-text-func-call(INT001)、format-in-get-text-func-call(INT002)和 printf-in-get-text-func-call(INT003)现在会检查更多 gettext 模块的常见用法,例如将其赋值给 builtins._。suspicious-url-open-usage(S310)现可解析局部字符串字面量绑定,以减少误报。snmp-insecure-version(S508)和 snmp-weak-cryptography(S509)现在支持新版本 PySNMP 推荐的 API。typing-text-str-alias(UP019)现在除了 typing.Text 外,也识别 typing_extensions.Text。致谢!#
感谢所有对 Ruff 的 预览模式 变更提供反馈的各位,以及我们的贡献者。能与你们一起构建 Ruff,是我们的荣幸!
完整变更日志请查看 GitHub。
了解更多关于 Astral——Ruff 背后的公司。
感谢参与本博文的 Zanie Blue、David Peter、Micha Reiser 和 Alex Waygood。