Ruff 0.2 系列版本演进全解析:配置命名空间迁移、规则重映射与 Preview 特性转正
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-self(ANN101)missing-type-cls(ANN102)
被弃用的命令行选项(应改用输出格式控制):
| 弃用选项 | 替代方式 |
|---|---|
--show-source |
--output-format full |
--no-show-source |
--output-format concise |
--output-format text |
改用 full 或 concise |
迁移到 lint 命名空间的配置项(旧顶层名称被弃用)。这是 0.2.0 最主要的迁移工作:原先平铺在顶层的 lint 相关配置全部收敛进 [lint] 表,旧名称仍可解析但会触发弃用提示。完整迁移对照如下(左侧为旧名,右侧为新名):
| 旧配置项 | 新配置项 |
|---|---|
ruff.allowed-confusables |
ruff.lint.allowed-confusables |
ruff.dummy-variable-rgx |
ruff.lint.dummy-variable-rgx |
ruff.explicit-preview-rules |
ruff.lint.explicit-preview-rules |
ruff.extend-fixable |
ruff.lint.extend-fixable |
ruff.extend-ignore |
ruff.lint.extend-ignore |
ruff.extend-per-file-ignores |
ruff.lint.extend-per-file-ignores |
ruff.extend-safe-fixes |
ruff.lint.extend-safe-fixes |
ruff.extend-select |
ruff.lint.extend-select |
ruff.extend-unfixable |
ruff.lint.extend-unfixable |
ruff.extend-unsafe-fixes |
ruff.lint.extend-unsafe-fixes |
ruff.external |
ruff.lint.external |
ruff.fixable |
ruff.lint.fixable |
ruff.flake8-annotations |
ruff.lint.flake8-annotations |
ruff.flake8-bandit |
ruff.lint.flake8-bandit |
ruff.flake8-bugbear |
ruff.lint.flake8-bugbear |
ruff.flake8-builtins |
ruff.lint.flake8-builtins |
ruff.flake8-comprehensions |
ruff.lint.flake8-comprehensions |
ruff.flake8-copyright |
ruff.lint.flake8-copyright |
ruff.flake8-errmsg |
ruff.lint.flake8-errmsg |
ruff.flake8-gettext |
ruff.lint.flake8-gettext |
ruff.flake8-implicit-str-concat |
ruff.lint.flake8-implicit-str-concat |
ruff.flake8-import-conventions |
ruff.lint.flake8-import-conventions |
ruff.flake8-pytest-style |
ruff.lint.flake8-pytest-style |
ruff.flake8-quotes |
ruff.lint.flake8-quotes |
ruff.flake8-self |
ruff.lint.flake8-self |
ruff.flake8-tidy-imports |
ruff.lint.flake8-tidy-imports |
ruff.flake8-type-checking |
ruff.lint.flake8-type-checking |
ruff.flake8-unused-arguments |
ruff.lint.flake8-unused-arguments |
ruff.ignore |
ruff.lint.ignore |
ruff.ignore-init-module-imports |
ruff.lint.ignore-init-module-imports |
ruff.isort |
ruff.lint.isort |
ruff.logger-objects |
ruff.lint.logger-objects |
ruff.mccabe |
ruff.lint.mccabe |
ruff.pep8-naming |
ruff.lint.pep8-naming |
ruff.per-file-ignores |
ruff.lint.per-file-ignores |
ruff.pycodestyle |
ruff.lint.pycodestyle |
ruff.pydocstyle |
ruff.lint.pydocstyle |
ruff.pyflakes |
ruff.lint.pyflakes |
ruff.pylint |
ruff.lint.pylint |
ruff.pyupgrade |
ruff.lint.pyupgrade |
ruff.select |
ruff.lint.select |
ruff.task-tags |
ruff.lint.task-tags |
ruff.typing-modules |
ruff.lint.typing-modules |
ruff.unfixable |
ruff.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-except |
TRY200 |
B904 |
suspicious-eval-usage |
PGH001 |
S307 |
logging-warn |
PGH002 |
G010 |
static-key-dict-comprehension |
RUF011 |
B035 |
runtime-string-union |
TCH006 |
TCH010 |
重映射的实现位于 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-await(TRIO100)、trio-sync-call(TRIO105)、trio-async-function-with-timeout(TRIO109)、trio-unneeded-sleep(TRIO110)、trio-zero-sleep-call(TRIO115)unnecessary-escaped-quote(Q004)enumerate-for-loop(SIM113)、zip-dict-keys-and-values(SIM911)timeout-error-alias(UP041)flask-debug-true(S201)、tarfile-unsafe-members(S202)、ssl-insecure-version(S502)、ssl-with-bad-defaults(S503)、ssl-with-no-version(S504)、weak-cryptographic-key(S505)、ssh-no-host-key-verification(S507)、django-raw-sql(S611)、mako-templates(S702)generator-return-from-iter-method(PYI058)、runtime-string-union(TCH006)numpy2-deprecation(NPY201)quadratic-list-summation(RUF017)、assignment-in-assert(RUF018)、unnecessary-key-check(RUF019)、never-union(RUF020)direct-logger-instantiation(LOG001)、invalid-get-logger-argument(LOG002)、exception-without-exc-info(LOG007)、undocumented-warn(LOG009)
修复(Fix)转正——以下规则的自动修复不再需要 Preview:
triple-single-quotes(D300)、non-pep604-annotation(UP007)dict-get-with-none-default(SIM910)、in-dict-keys(SIM118)、if-with-same-arms(SIM114)collapsible-else-if(PLR5501)、useless-else-on-loop(PLW0120)unnecessary-literal-union(PYI030)unnecessary-spread(PIE800)error-instead-of-exception(TRY400)redefined-while-unused(F811)、duplicate-value(B033)multiple-imports-on-one-line(E401)non-pep585-annotation(UP006)
修复安全级别提升:unaliased-collections-abc-set-import(PYI025)的修复从 unsafe 提升为 safe,即默认 --fix 即会应用,无需 --unsafe-fixes。
行为层面的稳定化:
module-import-not-at-top-of-file(E402)允许在 import 语句之间插入sys.path修改;reimplemented-container-builtin(PIE807)把可替换为dict的 lambda 也纳入检测;unnecessary-placeholder(PIE790)扩展到无用的省略号(...);if-else-block-instead-of-dict-get(SIM401)扩展到if-else表达式。
0.2.0 的 Preview 新特性与 Bug 修复
Preview 特性:
- [refurb] 新增
metaclass_abcmeta(FURB180) - 新增
blank_line_after_nested_stub_class格式化预览样式 - 移除 Preview 规则
and-or-ternary(PLR1706)
Bug 修复:
- [flake8-async] 分析异步函数时计入
pathlib.Path - [flake8-return] 修复
RET505的缩进语法错误 - else 移除(autofix)时检测多语句行
RUF022、RUF023:序列末尾绝不追加两个尾逗号RUF023:只排序__slots__,不再排序__match_args__- [flake8-simplify] 修复
SIM114autofix 的语法错误 - [pylint]
magic-value-comparison(PLR2004)展示原样常量 - 多行字符串内部移除尾随空白被重新标记为 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-syntax(RUF027) - 格式化模块级 docstring
Formatter:
ruff format新增--range选项- 修复 docstring 末尾空行被误删的问题
Bug 修复:
- 判定基础缩进时跳过空行
unnecessary-dunder-call不再针对__get__与__set__- 省略号移除时尊重泛型
Protocol - 回滚一项 CI 相关变更(Apple Silicon runner)
性能优化(本版本是性能工程密集的一版):
- 标准 dedent 调整跳过 LibCST 解析
- 移除
C408的 CST 修复器 - 引入自有 ignored-names 抽象,降低对上游库的依赖
- 移除
C400、C401、C410、C418的 CST 修复器 - 使用
AhoCorasick加速引号匹配 - 移除
C405、C409的 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] 新增空行规则(
E301、E302、E303、E304、E305、E306) - [refurb] 新增
readlines_in_for(FURB129)
规则行为变更:
- [ruff] 多行序列的闭合括号必须独立成行(
RUF022、RUF023) - [numpy] 补充缺失的弃用违规检测(
NPY002) - [flake8-bandit] 检测装饰器中的
mark_safe用法 - [ruff]
asyncio-dangling-task(RUF006)扩展覆盖new_event_loop - [flake8-pyi] 忽略类作用域中“未使用”的私有类型字典
Formatter:
indent-style=tabs时 docstring 格式化保留 tab 缩进- notebook 禁用顶层 docstring 格式化
quote-style的preserve模式转正稳定
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] 消除
SIM113对async 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 内容,迁移检查项可以归纳为四步:
- 配置迁移:把上表列出的 43 个顶层 lint 选项整体移入
[lint]表;被弃用的旧名称在过渡期仍可用,但应尽早消除警告。 - 规则代码更新:全局搜索并替换
TRY200→B904、PGH001→S307、PGH002→G010、RUF011→B035、TCH006→TCH010(含noqa注释与select/ignore列表);删除ANN101、ANN102的选择。 - 选择器清理:移除配置中的
NURSERY选择器;如果原本依赖精确代码选择 nursery 规则,改为开启 preview 或显式选择。 - 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 是掌握该项目版本策略的关键一环。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00