内容提要
Ruff v0.0.285 发布,稳定支持 Jupyter Notebook,可解析 IPython 魔法命令、显示渲染后差异,并调整 F841、F704 规则。新增规则:PT027 建议用 pytest.raises、PT014 查重复参数化、TID253 禁模块级导入、W3201 查错误双下划线名、W1510 要求 subprocess.run 显式 check、RUF017 避免 sum 展平列表。
延伸解读
Jupyter Notebook 支持转正:从实验到生产可用
Ruff 对 Jupyter Notebook 的支持在 v0.0.276 引入实验性功能,v0.0.285 正式稳定。关键改进包括解析 IPython 魔法命令(如 %matplotlib inline),避免因跳过含魔法命令的单元格而误报未定义名称(F821);同时 --diff 现在能展示渲染后单元格的差异,便于预览修复。但 Notebook 默认不被检查,需在配置中显式包含 *.ipynb 路径。
规则调整:适配 Notebook 语义与新增检查
针对 Notebook 的特殊语义,F841(未使用变量)不再删除整个语句,而是保留魔法命令的副作用;F704(yield 在函数外)允许顶层 await。此外新增六条规则:PT027 建议用 pytest.raises 替代 unittest 断言、PT014 检测重复参数化用例、TID253 禁止模块级导入(需配置)、W3201 检查错误双下划线名(nursery 阶段)、W1510 要求 subprocess.run 显式设置 check、RUF017 避免用 sum 展平列表(二次复杂度)。
实践建议:如何启用与注意事项
要使用 Notebook 支持,需在 pyproject.toml 的 [tool.ruff] 中设置 include 包含 *.ipynb。新规则中,TID253 需配置 flake8-tidy-imports.banned-module-level-imports 指定模块名;W3201 位于 nursery 阶段,可能不稳定。W1510 和 RUF017 分别帮助避免静默失败和性能问题,建议根据项目情况选择性启用。
Q&A
Ruff v0.0.285 对 Jupyter Notebook 的支持有什么变化?
Ruff v0.0.285 稳定了对 Jupyter Notebook 的支持,包括解析 IPython 魔法命令、为 notebook 提供 --diff 显示渲染后的差异,并调整了部分规则在 notebook 中的行为。但 notebook 默认仍不被 lint,需要在配置中显式包含,例如在 pyproject.toml 中设置 include = ["*.py", "*.pyi", "**/pyproject.toml", "*.ipynb"]。
Ruff 如何处理 Jupyter Notebook 中的 IPython 魔法命令?
Ruff 现在支持解析 Jupyter Notebook 中的 IPython 魔法命令(如 %、%%、! 开头的命令),包含魔法命令的单元格会被纳入分析,从而避免因跳过这些单元格而导致的误报(例如 F821 未定义名称)。
Ruff 在 Jupyter Notebook 中如何显示修复差异?
使用 --diff 标志时,Ruff 会显示渲染后单元格的差异,而不是原始 notebook 文件的差异,方便用户预览和验证对 notebook 的修改。
Ruff v0.0.285 新增了哪些规则?
新增规则包括:PT027(建议使用 pytest.raises 替代 unittest 的异常断言)、PT014(检查 pytest.mark.parametrize 中的重复测试用例)、TID253(禁止模块级导入,需配置 banned-module-level-imports)、W3201(检查错误的双下划线名称,位于 nursery)、W1510(要求 subprocess.run 显式设置 check 参数)、RUF017(避免使用 sum 展平列表)。
为什么应该用 pytest.raises 替代 unittest 的 assertRaises?
pytest 推荐使用 pytest.raises 作为异常断言的风格,它比 unittest 的 assertRaises 更符合 pytest 的惯用法。Ruff 新增的 PT027 规则会检查并建议将 unittest 的异常断言方法替换为 pytest.raises。
Ruff 的 RUF017 规则为什么建议避免用 sum 展平列表?
因为使用 sum() 展平列表的复杂度是二次的(quadratic),sum() 在求和过程中会为每个元素创建新列表,导致性能问题。RUF017 建议改用线性复杂度的方法,如 functools.reduce(operator.iconcat, lists, [])、list(itertools.chain.from_iterable(lists)) 或列表推导式。
Ruff 的 W1510 规则对 subprocess.run 有什么要求?
W1510 规则要求使用 subprocess.run 时显式设置 check 参数。因为默认情况下 subprocess.run 不会检查返回码,可能导致静默失败。建议设置 check=True 以在命令失败时抛出异常,或显式设置 check=False 表明有意不检查。