Ruff 的 --fix 没有修改代码?排查 safe 与 unsafe 修复默认策略
Ruff 的 --fix 没有修改代码排查 safe 与 unsafe 修复默认策略【免费下载链接】ruffAn extremely fast Python linter and code formatter, written in Rust.项目地址: https://gitcode.com/GitHub_Trending/ru/ruff运行ruff check --fix后终端列出了一堆违规但文件内容原封不动。多数情况下这不是 bugRuff 把每个自动修复标记为 safe 或 unsafe而默认只应用 safe 修复——unsafe 修复可能会改变代码的运行时行为或删掉注释所以必须先显式开启。这篇文章基于 Ruff 的 Linter 文档 和 FAQ给出一条从症状到配置的完整排查路径先判断你的修复属于哪一类、为什么没被应用再决定是开启 unsafe 修复还是调整 per-rule 的修复安全级别。症状--fix之后文件没有变化ruff check是 Ruff linter 的主入口--fix开启自动修复$ ruff check --fix # Lint current directory and fix any fixable errors.按文档--fix开启后 Ruff 的行为是修复所有存在safe修复的违规存在 unsafe 修复但未开启时Ruff 不会应用修复而是显示一条提示信息。所以没修改代码通常对应三种情况之一违规只有 unsafe 修复未开启--unsafe-fixes该规则本身不支持修复文档要求到 rules 参考 核对每条规则的修复能力配置把该规则排除在修复范围之外unfixable或fixable白名单或违规被noqa抑制而未参与修复。先跑一次不带--fix的检查确认违规本身存在$ ruff check如果连违规都列不出来问题在规则选择select/ignore而不是修复策略需要另行处理只有列出了违规而文件没变才继续按下面的顺序排查。默认策略只有 safe 修复会被应用Ruff 对修复安全性的定义来自 Fix safety 章节safe应用后代码含义不变只有整条语句或表达式被删除时例如删未使用的 import才会连带移除注释unsafe可能导致运行时行为变化、删除注释或两者兼有。文档给出的例子是unnecessary-iterable-allocation-for-first-elementRUF015把list(...)[0]改写为next(iter(...))可以大幅提升性能文档示例前者python -m timeit测得约 1.69 sec/loop后者约 70.8 nsec/loop为文档示例数据而非固定预期但集合为空时抛出的异常从IndexError变成StopIteration可能破坏上游错误处理因此该修复被归为 unsafe。由此推出默认行为Ruff 只默认启用 safe 修复。如果你的违规恰好只有 unsafe 修复--fix单独使用时就不会写文件。排查第一步区分无修复可用与有 unsafe 修复用--unsafe-fixes临时把 unsafe 修复纳入再配合--diff预览改动而不写回文件# 只查看 unsafe 修复会做什么不应用 ruff check --unsafe-fixes # 预览 diff不写回任何文件把每个改动文件的 diff 输出到 stdout无 diff 时退出码为 0 ruff check --fix --diff--diff会避免写回任何修复后的文件改为把每个改动文件的 diff 打印到 stdout且无 diff 时退出 0并隐含--fix-only。用这两条命令可以快速区分加上--unsafe-fixes后违规消失了或--diff打出了 diff——说明违规有修复只是属于 unsafe 且未开启加了--unsafe-fixes和--fix后违规仍在、diff 仍为空——说明该规则不支持修复或违规被其他设置排除继续往下排查。另外使用json输出格式时 Ruff 会始终展示所有修复包括 unsafe 的每个修复的安全级别位于applicability字段。需要脚本化判断某条违规到底有没有修复、是什么级别时这是最直接的依据$ ruff check --output-format json排查第二步检查配置里的unfixable/fixableRuff 还有一层是否允许修复的设置与安全级别相互独立。要限制 Ruff 修复的规则集合用lint.fixable、lint.extend-fixable、lint.unfixable。两个容易踩的坑配置里写了unfixable [F401]或对应前缀该规则的违规即使带 safe 修复也不会被--fix修改fixable是白名单语义。写成fixable [F401]表示只允许修复F401其他规则的修复全部禁用——这是比unfixable更隐蔽的没修改代码原因。文档给出的两个配置示例ruff.toml写法# 允许所有规则修复但排除 F401 [lint] fixable [ALL] unfixable [F401]# 只允许修复 F401 [lint] fixable [F401]pyproject.toml中对应写在[tool.ruff.lint]下键名相同。对照你自己的配置文件确认目标规则没有被unfixable排除、也没有被fixable白名单挡在外面。排查第三步检查noqa抑制ruff check默认尊重# noqa注释可用--ignore-noqa忽略它们。被行级# noqa: CODE或文件级# ruff: noqa抑制的违规不会出现在报告里也不会参与修复。如果你记得代码行尾有 noqa 注释先确认是不是这条原因。确认是 unsafe 之后如何开启如果你接受 unsafe 修复可能不保留代码原意这是 args 定义 中--unsafe-fixes的原文描述有两条开启路径# 查看 unsafe 修复 ruff check --unsafe-fixes # 应用 unsafe 修复 ruff check --fix --unsafe-fixes或者在配置文件中设置unsafe-fixesruff.toml顶层键pyproject.toml为[tool.ruff]下同名键避免每次都带命令行参数# ruff.toml unsafe-fixes true反向的提示抑制也值得知道默认情况下当存在可用但未开启的 unsafe 修复时Ruff 会显示一条提示把unsafe-fixes设为false或传--no-unsafe-fixes可以关掉这条提示。可选按规则调整修复安全级别如果你只对个别规则信任 unsafe 修复或反过来觉得某个 safe 修复在你的场景下不安全不必全局开关可以用lint.extend-safe-fixes和lint.extend-unsafe-fixes逐规则升降级。文档示例把F601的 unsafe 修复提升为 safe同时把UP034的 safe 修复降级为 unsafe# ruff.toml [lint] extend-safe-fixes [F601] extend-unsafe-fixes [UP034]# pyproject.toml [tool.ruff.lint] extend-safe-fixes [F601] extend-unsafe-fixes [UP034]这两个设置同样接受前缀比如F表示把 Pyflakes 全部规则的修复提升为 safe。注意它们是extend语义在默认安全级别基础上做增量调整适合全局保持默认、个别规则例外的场景。验证修复是否生效确认修复路径选对之后用下面几种方式验证结果$ ruff check --fix --show-fixes--show-fixes会在修复后列出所有被修复的违规方便逐条核对。退出码是最客观的判定Exit codes 章节0没有违规或所有违规都被自动修复了1仍有违规2配置、CLI 选项或内部错误导致异常终止。也就是说ruff check --fix跑完退出码为0说明违规已清零包括被修复的部分退出码为1时剩余违规要么没有可用修复要么属于未开启的 unsafe 修复可以再用--diff预览它们会如何被修改。限制与已知边界判断某条规则是否可修复文档给出的依据是 rules 参考 中每条规则的修复标注没有更快的全局开关可查。FAQ 明确承认由于 Python 的动态性即使是看似 trivial 的 safe 修复也无法保证 100% 不出问题。如果 safe 修复改坏了你的代码文档建议提交 Issue而不是自行归类为unsafe 未开启。unsafe 修复的开启是项目级决策--unsafe-fixes只影响当次命令unsafe-fixes true则对所有使用者生效两者语义一致包含可能不保留原意的修复按团队能接受的程度选择写在 CLI 还是配置文件里。按这条路径走完--fix没动文件的原因就落在三处之一unsafe 修复未开启加--fix --unsafe-fixes或配置unsafe-fixes true、规则/配置层面被fixable/unfixable或noqa排除调整对应配置或者该规则本身不支持修复无解只能手动修改。【免费下载链接】ruffAn extremely fast Python linter and code formatter, written in Rust.项目地址: https://gitcode.com/GitHub_Trending/ru/ruff创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →