Ruff 0.2 系列版本演进全解析:配置命名空间迁移、规则重映射与 Preview 特性转正
2026/9/6 19:06:35 网站建设 项目流程

Ruff 0.2 系列版本演进全解析:配置命名空间迁移、规则重映射与 Preview 特性转正

【免费下载链接】ruffAn extremely fast Python linter and code formatter, written in Rust.项目地址: https://gitcode.com/GitHub_Trending/ru/ruff

Ruff 0.2.x 是该项目早期演进中最具结构性的一批版本:0.2.0 完成了配置项向lint命名空间的迁移、5 条规则代码的重映射以及大量 Preview 规则的转正;0.2.1 为ruff format引入按行范围格式化(--range);0.2.2 则带来 f-string 初步格式化、CLI 任意配置覆盖(--config "key=value")与词法/解析层的显著提速。读完本文,你将掌握从 0.1.x 平滑升级到 0.2.x 所需的完整迁移清单,并能通过仓库源码验证每一项变更的实际落点。

0.2.0:配置架构重构与规则体系大调整

0.2.0 是 0.2.x 中变更幅度最大的版本,包含破坏性变更、大规模弃用、规则重映射和 Preview 转正四类内容,下面逐一展开。

破坏性变更:NURSERY 选择器下线

  • NURSERY选择器不再可用。
  • 在 Preview 未启用的情况下,不再允许通过精确规则代码选择(select)nursery(孵化中)规则。

这一点可以在当前源码中得到印证。在 规则选择器解析逻辑 中,NURSERY仅作为PREVIEW的别名被保留解析,且按类别、按名称选择规则均要求开启 Preview 模式:

} else if matches!(selector, "PREVIEW" | "NURSERY") { // ... "Selecting rules by category requires preview mode" "Selecting rules by name requires preview mode"

而选择器实际生效时的过滤逻辑(rules()方法)根据PreviewOptions决定是否纳入 preview 规则,并支持explicit-preview-rules要求显式代码选择,这与 0.2.0 中“未开启 preview 不得按精确代码选择 nursery 规则”的声明一致。

弃用项清单

被弃用的规则(迁移到其他命名空间或由其他规则取代):

  • missing-type-selfANN101
  • missing-type-clsANN102

被弃用的命令行选项(应改用输出格式控制):

弃用选项替代方式
--show-source--output-format full
--no-show-source--output-format concise
--output-format text改用fullconcise

迁移到lint命名空间的配置项(旧顶层名称被弃用)。这是 0.2.0 最主要的迁移工作:原先平铺在顶层的 lint 相关配置全部收敛进[lint]表,旧名称仍可解析但会触发弃用提示。完整迁移对照如下(左侧为旧名,右侧为新名):

旧配置项新配置项
ruff.allowed-confusablesruff.lint.allowed-confusables
ruff.dummy-variable-rgxruff.lint.dummy-variable-rgx
ruff.explicit-preview-rulesruff.lint.explicit-preview-rules
ruff.extend-fixableruff.lint.extend-fixable
ruff.extend-ignoreruff.lint.extend-ignore
ruff.extend-per-file-ignoresruff.lint.extend-per-file-ignores
ruff.extend-safe-fixesruff.lint.extend-safe-fixes
ruff.extend-selectruff.lint.extend-select
ruff.extend-unfixableruff.lint.extend-unfixable
ruff.extend-unsafe-fixesruff.lint.extend-unsafe-fixes
ruff.externalruff.lint.external
ruff.fixableruff.lint.fixable
ruff.flake8-annotationsruff.lint.flake8-annotations
ruff.flake8-banditruff.lint.flake8-bandit
ruff.flake8-bugbearruff.lint.flake8-bugbear
ruff.flake8-builtinsruff.lint.flake8-builtins
ruff.flake8-comprehensionsruff.lint.flake8-comprehensions
ruff.flake8-copyrightruff.lint.flake8-copyright
ruff.flake8-errmsgruff.lint.flake8-errmsg
ruff.flake8-gettextruff.lint.flake8-gettext
ruff.flake8-implicit-str-concatruff.lint.flake8-implicit-str-concat
ruff.flake8-import-conventionsruff.lint.flake8-import-conventions
ruff.flake8-pytest-styleruff.lint.flake8-pytest-style
ruff.flake8-quotesruff.lint.flake8-quotes
ruff.flake8-selfruff.lint.flake8-self
ruff.flake8-tidy-importsruff.lint.flake8-tidy-imports
ruff.flake8-type-checkingruff.lint.flake8-type-checking
ruff.flake8-unused-argumentsruff.lint.flake8-unused-arguments
ruff.ignoreruff.lint.ignore
ruff.ignore-init-module-importsruff.lint.ignore-init-module-imports
ruff.isortruff.lint.isort
ruff.logger-objectsruff.lint.logger-objects
ruff.mccaberuff.lint.mccabe
ruff.pep8-namingruff.lint.pep8-naming
ruff.per-file-ignoresruff.lint.per-file-ignores
ruff.pycodestyleruff.lint.pycodestyle
ruff.pydocstyleruff.lint.pydocstyle
ruff.pyflakesruff.lint.pyflakes
ruff.pylintruff.lint.pylint
ruff.pyupgraderuff.lint.pyupgrade
ruff.selectruff.lint.select
ruff.task-tagsruff.lint.task-tags
ruff.typing-modulesruff.lint.typing-modules
ruff.unfixableruff.lint.unfixable

这一设计的动因在 workspace 选项定义 中可见:lint小节下的选项优先于被弃用的顶层设置,即“Options specified in the lint section take precedence over the deprecated top-level settings”。对用户而言,迁移策略就是把pyproject.toml/ruff.toml中上述顶层键整体挪进[lint]表,例如:

# 旧写法(弃用) select = ["E", "F", "I"] ignore = ["E501"] # 新写法 [lint] select = ["E", "F", "I"] ignore = ["E501"]

规则代码重映射

5 条规则被重映射到新代码。若你的配置或noqa注释仍使用旧代码,规则将实际上被“禁用”(旧代码指向新代码,而旧代码对应的规则本体不复存在),这也是 changelog 特别提示“见 Remapped rules 一节,否则可能导致规则被禁用”的原因:

规则旧代码新代码
raise-without-from-inside-exceptTRY200B904
suspicious-eval-usagePGH001S307
logging-warnPGH002G010
static-key-dict-comprehensionRUF011B035
runtime-string-unionTCH006TCH010

重映射的实现位于 rule_redirects.rs:一张静态HashMap把所有历史代码映射到现行代码。其中本版本的 5 条重映射对应表中的条目:

("RUF011", "B035"), ("TRY200", "B904"), ("PGH001", "S307"), ("PGH002", "G010"), // TCH 前缀后来整体更名为 TC ("TCH006", "TC010"), ("TCH010", "TC010"),

从源码结构看,TCH006的重映射目标经过了两步演进:0.2.0 时重映射到TCH010,之后整个TCH前缀与上游插件统一更名为TC,于是现在的重映射表直接将其指向TC010。该文件末尾还内置了overshadowing_redirects测试,确保任何现行规则代码都不会被重映射条目意外遮蔽——这是重映射机制的安全网。

Preview 规则转正(Stabilizations)

以下规则在 0.2.0 中稳定,脱离 Preview 直接生效:

  • trio-timeout-without-awaitTRIO100)、trio-sync-callTRIO105)、trio-async-function-with-timeoutTRIO109)、trio-unneeded-sleepTRIO110)、trio-zero-sleep-callTRIO115
  • unnecessary-escaped-quoteQ004
  • enumerate-for-loopSIM113)、zip-dict-keys-and-valuesSIM911
  • timeout-error-aliasUP041
  • flask-debug-trueS201)、tarfile-unsafe-membersS202)、ssl-insecure-versionS502)、ssl-with-bad-defaultsS503)、ssl-with-no-versionS504)、weak-cryptographic-keyS505)、ssh-no-host-key-verificationS507)、django-raw-sqlS611)、mako-templatesS702
  • generator-return-from-iter-methodPYI058)、runtime-string-unionTCH006
  • numpy2-deprecationNPY201
  • quadratic-list-summationRUF017)、assignment-in-assertRUF018)、unnecessary-key-checkRUF019)、never-unionRUF020
  • direct-logger-instantiationLOG001)、invalid-get-logger-argumentLOG002)、exception-without-exc-infoLOG007)、undocumented-warnLOG009

修复(Fix)转正——以下规则的自动修复不再需要 Preview:

  • triple-single-quotesD300)、non-pep604-annotationUP007
  • dict-get-with-none-defaultSIM910)、in-dict-keysSIM118)、if-with-same-armsSIM114
  • collapsible-else-ifPLR5501)、useless-else-on-loopPLW0120
  • unnecessary-literal-unionPYI030
  • unnecessary-spreadPIE800
  • error-instead-of-exceptionTRY400
  • redefined-while-unusedF811)、duplicate-valueB033
  • multiple-imports-on-one-lineE401
  • non-pep585-annotationUP006

修复安全级别提升unaliased-collections-abc-set-importPYI025)的修复从 unsafe 提升为 safe,即默认--fix即会应用,无需--unsafe-fixes

行为层面的稳定化

  • module-import-not-at-top-of-fileE402)允许在 import 语句之间插入sys.path修改;
  • reimplemented-container-builtinPIE807)把可替换为dict的 lambda 也纳入检测;
  • unnecessary-placeholderPIE790)扩展到无用的省略号(...);
  • if-else-block-instead-of-dict-getSIM401)扩展到if-else表达式。

0.2.0 的 Preview 新特性与 Bug 修复

Preview 特性

  • [refurb] 新增metaclass_abcmetaFURB180
  • 新增blank_line_after_nested_stub_class格式化预览样式
  • 移除 Preview 规则and-or-ternaryPLR1706

Bug 修复

  • [flake8-async] 分析异步函数时计入pathlib.Path
  • [flake8-return] 修复RET505的缩进语法错误
  • else 移除(autofix)时检测多语句行
  • RUF022RUF023:序列末尾绝不追加两个尾逗号
  • RUF023:只排序__slots__,不再排序__match_args__
  • [flake8-simplify] 修复SIM114autofix 的语法错误
  • [pylint]magic-value-comparisonPLR2004)展示原样常量
  • 多行字符串内部移除尾随空白被重新标记为 unsafe
  • invalid-envvar-default支持双臂均为字符串的IfExp
  • [pylint] 将__mro_entries__加入已知 dunder 方法(PLW3201

文档改进:被移除的规则现在保留在文档中;被弃用的规则现在在文档中被明确标注。

0.2.1:引入范围格式化(Range Formatting)

0.2.1 的核心能力是范围格式化:可以对源文件中的特定行进行格式化,即ruff format --range选项(起始行到结束行)。这对编辑器集成场景(仅格式化当前编辑区域)意义重大。

Preview 特性

  • [refurb] 新增missing-f-string-syntaxRUF027
  • 格式化模块级 docstring

Formatter

  • ruff format新增--range选项
  • 修复 docstring 末尾空行被误删的问题

Bug 修复

  • 判定基础缩进时跳过空行
  • unnecessary-dunder-call不再针对__get____set__
  • 省略号移除时尊重泛型Protocol
  • 回滚一项 CI 相关变更(Apple Silicon runner)

性能优化(本版本是性能工程密集的一版):

  • 标准 dedent 调整跳过 LibCST 解析
  • 移除C408的 CST 修复器
  • 引入自有 ignored-names 抽象,降低对上游库的依赖
  • 移除C400C401C410C418的 CST 修复器
  • 使用AhoCorasick加速引号匹配
  • 移除C405C409的 CST 修复器
  • 注释检测加入快速路径
  • zero-sleep-call反转检查顺序以提前短路
  • 基于导入信息短路 typing 匹配
  • dunder 方法规则直接在方法上运行
  • 语义模型中跟踪顶层模块导入
  • 小写/大写标识符检查小幅提速
  • 移除C403的 LibCST 修复器

从这些条目可以推断:0.2.x 阶段项目正在系统性地把早期借用 LibCST 的修复逻辑替换为基于自家 AST/CST 的轻量实现,从而压缩解析与修复开销。

文档修正max-pos-args示例更正为max-positional-args;修正weak_cryptographic_key规则中的示例代码;修正 changelog 中对已弃用ANN规则的引用;修正max-positional-args默认值。

0.2.2:f-string 格式化、CLI 配置覆盖与词法层提速

0.2.2 的官方亮点有三条:f-string 格式化的初步支持(--preview下)、通过扩展的--config参数在 CLI 覆盖任意配置项(如--config "lint.isort.combine-as-imports=false")、以及词法器(lexer)、解析器与 lint 规则的显著性能提升。

Preview 特性

  • 实现最小化 f-string 格式化
  • [pycodestyle] 新增空行规则(E301E302E303E304E305E306
  • [refurb] 新增readlines_in_forFURB129

规则行为变更

  • [ruff] 多行序列的闭合括号必须独立成行(RUF022RUF023
  • [numpy] 补充缺失的弃用违规检测(NPY002
  • [flake8-bandit] 检测装饰器中的mark_safe用法
  • [ruff]asyncio-dangling-taskRUF006)扩展覆盖new_event_loop
  • [flake8-pyi] 忽略类作用域中“未使用”的私有类型字典

Formatter

  • indent-style=tabs时 docstring 格式化保留 tab 缩进
  • notebook 禁用顶层 docstring 格式化
  • quote-stylepreserve模式转正稳定

CLI

  • 允许在命令行覆盖任意配置选项。当前 全局参数定义 中,--config的文档注释明确说明它既可以是配置文件路径,也可以是形如KEY = VALUE的 TOML 键值对(例如--config "lint.line-length = 100"--config "format.quote-style = 'single'"),且这种逐项覆盖的优先级高于所有配置文件(包括同样通过--config指定的文件)。这与 0.2.2 “任意配置项 CLI 覆盖”的声明完全对应。

Bug 修复

  • show-settings过滤器不再受目录影响
  • 重写类型别名时尊重重名
  • typing 分析器尊重元组赋值
  • 缓存持久化改用原子写入
  • DebugText使用无括号范围
  • [flake8-simplify] 消除SIM113async for循环的误报
  • [flake8-trio]timeout-without-await尊重async with
  • [perflint]PERF101捕获更广泛的变异操作
  • [pycodestyle] 修复E30X在带尾随空白的空行上 panic
  • [pydocstyle] 允许parameters作为小节标题(D405);修复模块级 docstring 的空行规则
  • [pylint]PLR2004接受 0.0 和 1.0 为常见魔数;不再对不可哈希类型建议 set 重写
  • [ruff] 方法调用内部字符串字面量消除RUF027漏报与 panic;缺失 f-string 检测忽略 builtin

性能

  • 字符串词法分析改用memchr
  • tab 缩进检测改用memchr
  • Box<str>替代String缩小Result<Tok, LexicalError>体积
  • Expr结构体从 80 字节压缩到 64 字节
  • 尾逗号规则性能优化
  • 解析器移除不必要的字符串克隆

升级实操清单:从 0.1.x 迁移到 0.2.x

结合 changelog 内容,迁移检查项可以归纳为四步:

  1. 配置迁移:把上表列出的 43 个顶层 lint 选项整体移入[lint]表;被弃用的旧名称在过渡期仍可用,但应尽早消除警告。
  2. 规则代码更新:全局搜索并替换TRY200B904PGH001S307PGH002G010RUF011B035TCH006TCH010(含noqa注释与select/ignore列表);删除ANN101ANN102的选择。
  3. 选择器清理:移除配置中的NURSERY选择器;如果原本依赖精确代码选择 nursery 规则,改为开启 preview 或显式选择。
  4. CLI 选项替换--show-source/--no-show-source/--output-format text分别替换为--output-format full/concise的显式取值。

验证方面,仓库提供了 0.2.x 完整变更记录 作为权威对照;若升级后 lint 结果出现规则“凭空消失”,优先检查第 2 步的重映射代码是否遗漏。

版本脉络小结

0.2.x 三个版本呈现清晰的分工:0.2.0 做“减法与归位”(弃用旧接口、收敛配置命名空间、规则重映射、Preview 大规模转正),0.2.1 做“能力增量”(范围格式化)兼做性能工程,0.2.2 做“编辑器友好化”(f-string 格式化起步、--range落地后的 CLI 配置覆盖)并持续压榨词法/解析性能。这套节奏——破坏性变更集中发布、弃用期保留兼容别名、Preview 通道先行试验——贯穿了 ruff 后续的演进(可对照 changelogs/0.3.x.md 及之后的版本记录),理解 0.2.x 是掌握该项目版本策略的关键一环。

【免费下载链接】ruffAn extremely fast Python linter and code formatter, written in Rust.项目地址: https://gitcode.com/GitHub_Trending/ru/ruff

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询