ruff - 一个极快的 Python linter,用 Rust 编写。

Created at: 2022-08-10 01:17:44
Language: Rust
License: MIT

流苏鹬

流苏鹬 图像 图像 图像 操作状态

一个非常快的Python linter,用Rust编写。

显示包含基准测试结果的条形图。

从头开始检查CPython代码库。

  • ⚡️ 比现有短绒快 10-100 倍
  • 🐍可通过
    pip
  • 🤝Python 3.11 兼容性
  • 🛠️ 支持
    pyproject.toml
  • 📦内置缓存,避免重新分析未更改的文件
  • 🔧自动修复支持,用于自动纠错(例如,自动删除未使用的导入)
  • ⚖️ 与内置的 Flake8 规则集接近奇偶校验
  • 🔌数十个 Flake8 插件的原生重新实现,如 flake8-bugbear
  • ⌨️VS Code 等的第一方编辑器集成
  • 🌎单存储库友好,具有分层和级联配置

Ruff的目标是比其他工具快几个数量级,同时在单个通用界面后面集成更多功能。

Ruff可以用来替换Flake8(以及各种插件),isortpydocstyleyesqaeradicatepyupgradeautoflake,同时执行速度比任何单个工具快数十倍或数百倍。

Ruff 超越了传统 linter 的职责,而是充当高级代码转换工具,能够升级类型注释、重写类定义、对导入进行排序等。

Ruff非常积极地开发和用于主要的开源项目,例如:

阅读发布博客文章

推荐

Sebastián RamírezFastAPI的创建者:

Ruff 的速度如此之快,以至于有时我会在代码中添加一个故意的错误,只是为了确认它确实正在运行并检查代码。

Nick SchrockElementl创始人,GraphQL联合创建者:

为什么拉夫会改变游戏规则?主要是因为它快了近 1000 倍。按照字面。不是错别字。在我们最大的模块( Dagger 本身,250k LOC)上,pylint 大约需要 2.5 分钟,在我的 M1 上的 4 个内核上并行化。针对我们的整个代码库运行 ruff 需要 .4 秒。

Bryan Van de VenBokeh的联合创作者,Conda的原作者:

Ruff 在我的机器上比 flake8 快 ~150-200 倍,扫描整个存储库需要 ~0.2 秒而不是 ~20 秒。对于本地开发人员来说,这是一个巨大的生活质量改善。它足够快,我将其添加为实际的提交钩子,这很棒。

Timothy Crosleyisort的创建者:

刚刚将我的第一个项目切换到 Ruff。到目前为止只有一个缺点:它太快了,直到我故意引入一些错误,我才敢相信它正在工作。

Tim AbbottZulip的首席开发人员:

这简直快得离谱... 太神奇了。

ruff

目录

  1. 安装和使用
  2. 配置
  3. 支持的规则
    1. 皮弗利特 (F)
    2. pycodestyle (E, W)
    3. 麦凯布(C90)
    4. isort (I)
    5. PEP8 命名 (N)
    6. 皮多克风格 (D)
    7. pyupgrade (UP)
    8. 片状8-2020 (YTT)
    9. 薄片8注释 (ANN)
    10. 片状8-强盗(S)
    11. 片状8-盲区-除了 (BLE)
    12. 薄片8-布尔陷阱 (FBT)
    13. 薄片8-虫熊(B)
    14. 薄片8-内置 (A)
    15. 片状8-逗号 (COM)
    16. 薄片8-理解 (C4)
    17. flake8-datetimez (DTZ)
    18. 薄片8-调试器 (T10)
    19. 薄片8-errmsg (EM)
    20. flake8-可执行文件 (EXE)
    21. flake8-implicit-str-concat (ISC)
    22. 薄片8-进口公约 (ICN)
    23. 片状8-日志记录格式 (G)
    24. 薄片8-无PEP420 (INP)
    25. 薄片8-馅饼 (馅饼)
    26. 片状8印花 (T20)
    27. 薄片8-pytest风格(PT)
    28. 片状8引号 (Q)
    29. 薄片8-返回 (RET)
    30. 薄片8-简化 (SIM)
    31. 片状8-整齐-进口 (TID)
    32. 片状8型检查(TCH)
    33. flake8-unused-arguments (ARG)
    34. flake8-use-pathlib (PTH)
    35. 根除(时代)
    36. pandas 兽医 (PD)
    37. 侏儒钩 (PGH)
    38. 皮林特(波兰)
    39. 锥角龙 (土耳其里拉)
    40. 特定于褶皱的规则(联阵)
  4. 编辑器集成
  5. 常见问题
  6. 贡献
  7. 释放
  8. 基准
  9. 参考
  10. 许可证

安装和使用

安装

Ruff在PyPI上可以作为ruff使用:

pip install ruff

对于macOS Homebrew和Linuxbrew用户,Ruff也可以在Homebrew上作为ruff使用:

brew install ruff

对于 Conda 用户,Ruff 也可在以下位置作为 ruff 使用:

conda-forge

conda install -c conda-forge ruff

对于 Arch Linux 用户,Ruff 也可以在官方仓库中作为 ruff 使用:

pacman -S ruff

对于 Alpine 用户,Ruff 也可在测试存储库中作为 ruff 使用:

apk add ruff

包装状态

用法

要运行 Ruff,请尝试以下任一操作:

ruff .                        # Lint all files in the current directory (and any subdirectories)
ruff path/to/code/            # Lint all files in `/path/to/code` (and any subdirectories)
ruff path/to/code/*.py        # Lint all `.py` files in `/path/to/code`
ruff path/to/code/to/file.py  # Lint `file.py`

你可以在模式下运行 Ruff 以在更改时自动重新运行:

--watch

ruff path/to/code/ --watch

Ruff 还使用预提交

- repo: https://github.com/charliermarsh/ruff-pre-commit
  # Ruff version.
  rev: 'v0.0.237'
  hooks:
    - id: ruff

配置

Ruff 可通过 和命令行进行配置。有关可配置选项的完整列表,请参阅 API 参考

pyproject.toml

如果未指定,则默认配置等效于:

[tool.ruff]
# Enable Pyflakes `E` and `F` codes by default.
select = ["E", "F"]
ignore = []

# Allow autofix for all enabled rules (when `--fix`) is provided.
fixable = ["A", "B", "C", "D", "E", "F", "..."]
unfixable = []

# Exclude a variety of commonly ignored directories.
exclude = [
    ".bzr",
    ".direnv",
    ".eggs",
    ".git",
    ".hg",
    ".mypy_cache",
    ".nox",
    ".pants.d",
    ".ruff_cache",
    ".svn",
    ".tox",
    ".venv",
    "__pypackages__",
    "_build",
    "buck-out",
    "build",
    "dist",
    "node_modules",
    "venv",
]
per-file-ignores = {}

# Same as Black.
line-length = 88

# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

# Assume Python 3.10.
target-version = "py310"

[tool.ruff.mccabe]
# Unlike Flake8, default to a complexity level of 10.
max-complexity = 10

例如,以下内容将 Ruff 配置为:(1) 除了默认值之外,还强制执行 flake8-bugbear 规则;(2)避免执行行长违规();(3)避免想修复Flake8-bugbear()违规行为;(3) 忽略文件中文件顶部的导入冲突 ():

E501
B
E402
__init__.py

[tool.ruff]
# Enable flake8-bugbear (`B`) rules.
select = ["E", "F", "B"]

# Never enforce `E501` (line length violations).
ignore = ["E501"]

# Avoid trying to fix flake8-bugbear (`B`) violations.
unfixable = ["B"]

# Ignore `E402` (import violations) in all `__init__.py` files, and in `path/to/file.py`.
[tool.ruff.per-file-ignores]
"__init__.py" = ["E402"]
"path/to/file.py" = ["E402"]

插件配置应表示为小节,例如:

[tool.ruff]
# Add "Q" to the list of enabled codes.
select = ["E", "F", "Q"]

[tool.ruff.flake8-quotes]
docstring-quotes = "double"

Ruff镜像了Flake8的规则代码系统,其中每个规则代码由一到三个字母的前缀组成,后跟三位数字(例如,)。前缀表示规则的“源”(例如,对于 Pyflakes,for ,for )。启用的规则集由 和 选项确定,它们同时支持完整代码(例如 )和前缀(例如 )。

F401
F
E
pycodestyle
ANN
flake8-annotations
select
ignore
F401
F

作为特殊情况,Ruff 还支持启用所有规则的代码。请注意,某些规则冲突(例如,和),因为它们表示替代的文档字符串格式。在没有进一步配置的情况下启用可能会导致次优行为,尤其是对于插件。

ALL
pydocstyle
D203
D211
ALL
pydocstyle

如果你想知道如何配置 Ruff,以下是一些推荐的准则

  • 首选和 over 和 ,以使规则集显式。
    select
    ignore
    extend-select
    extend-ignore
  • 谨慎使用。启用将在升级时隐式启用新规则。
    ALL
    ALL
  • 从一小组规则 () 开始,然后一次添加一个类别。例如,你可以考虑扩展到以启用常用扩展。
    select = ["E", "F"]
    select = ["E", "F", "B"]
    flake8-bugbear
  • 默认情况下,Ruff的自动修复是激进的。如果你发现它过于激进,不符合你的喜好,请考虑关闭特定规则或类别的自动修复(请参阅:常见问题解答)。

作为 的替代方法,Ruff 也将遵循一个文件,该文件实现了等效的模式(尽管可以省略层次结构)。例如,上述内容将通过以下方式表示:

pyproject.toml
ruff.toml
[tool.ruff]
pyproject.toml
ruff.toml

# Enable Pyflakes and pycodestyle rules.
select = ["E", "F"]

# Never enforce `E501` (line length violations).
ignore = ["E501"]

# Always autofix, but never try to fix `F401` (unused imports).
fix = true
unfixable = ["F401"]

# Ignore `E402` (import violations) in all `__init__.py` files, and in `path/to/file.py`.
[per-file-ignores]
"__init__.py" = ["E402"]
"path/to/file.py" = ["E402"]

有关可配置选项的完整列表,请参阅 API 参考

可以通过命令行提供一些常见的配置设置:

ruff path/to/code/ --select F401 --select F403

查看更多:

ruff --help

Ruff: An extremely fast Python linter.

Usage: ruff [OPTIONS] <COMMAND>

Commands:
  check  Run Ruff on the given files or directories (default)
  rule   Explain a rule
  clean  Clear any caches in the current directory and any subdirectories
  help   Print this message or the help of the given subcommand(s)

Options:
  -h, --help     Print help
  -V, --version  Print version

Log levels:
  -v, --verbose  Enable verbose logging
  -q, --quiet    Print lint violations, but nothing else
  -s, --silent   Disable all logging (but still exit with status code "1" upon detecting lint violations)

For help with a specific command, see: `ruff help <command>`.

pyproject.toml
发现

ESLint 类似,Ruff 支持分层配置,因此目录层次结构中的“最接近”文件用于每个单独的文件,文件中的所有路径(例如,globs、路径)相对于包含文件的目录进行解析。

pyproject.toml
pyproject.toml
exclude
src
pyproject.toml

这些规则有一些例外:

  1. 在查找给定路径的“最近”文件时,Ruff 会忽略任何缺少部分的文件。
    pyproject.toml
    pyproject.toml
    [tool.ruff]
  2. 如果配置文件直接通过 传递,则这些设置将用于跨文件。该配置文件中的任何相对路径(如 glob 或路径)都是相对于当前工作目录解析的。
    --config
    exclude
    src
  3. 如果在文件系统层次结构中找不到任何文件,Ruff 将回退到使用默认配置。如果用户特定的配置文件存在于 ,则将使用该文件而不是默认配置,通过 dirs crate 确定,并且所有相对路径再次相对于当前工作目录解析。
    pyproject.toml
    ${config_dir}/ruff/pyproject.toml
    ${config_dir}
  4. 命令行上提供的任何支持的设置(例如,via )都将覆盖每个解析的配置文件中的设置。
    pyproject.toml
    --select

ESLint 不同,Ruff 不会跨配置文件合并设置;相反,将使用“最接近”的配置文件,并忽略任何父配置文件。代替这种隐式级联,Ruff 支持扩展字段,它允许你从另一个文件继承设置,如下所示:

pyproject.toml

# Extend the `pyproject.toml` file in the parent directory.
extend = "../pyproject.toml"
# But use a different line length.
line-length = 100

上述所有规则等效地应用于文件。如果 Ruff 同时检测到 a 和 文件,它将遵从 .

ruff.toml
ruff.toml
pyproject.toml
ruff.toml

anaconda 文件发现

在命令行上传递路径时,Ruff 将自动发现该路径中的所有 Python 文件,同时考虑每个目录文件中的排除和扩展-排除设置。

pyproject.toml

默认情况下,Ruff 还会跳过通过 、 和全局文件省略的任何文件(请参阅:respect-gitignore)。

.ignore
.gitignore
.git/info/exclude
gitignore

无论上述条件如何,直接传递到的文件始终会进行 lind。例如,将始终 lint .

ruff
ruff /path/to/excluded/file.py
file.py

忽略错误

要完全省略 lint 规则,请在命令行或文件中通过忽略或扩展忽略将其添加到“忽略”列表中。

pyproject.toml

为了忽略内联违规,Ruff 使用类似于 Flake8 的系统。要忽略单个违规,请在行尾添加,如下所示:

noqa
# noqa: {code}

# Ignore F841.
x = 1  # noqa: F841

# Ignore E741 and F841.
i = 1  # noqa: E741, F841

# Ignore _all_ violations.
x = 1  # noqa

请注意,对于多行字符串,指令应位于字符串的末尾,并将应用于整个字符串,如下所示:

noqa

"""Lorem ipsum dolor sit amet.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
"""  # noqa: E501

为了忽略整个文件中的所有违规行为,Ruff 支持 Flake8 的指令(或者,等效地,)。将这些指令中的任何一个添加到文件的任何部分都将禁用对整个文件的强制实施。

# flake8: noqa
# ruff: noqa

有关跨整个文件的目标排除项(例如,“忽略 in 中的所有 F841 冲突”),请参阅每个文件忽略配置设置。

/path/to/file.py

“操作注释”

Ruff 遵循 的“操作注释”(、、、 和 ),可以有选择地启用和禁用代码块和其他内联配置的导入排序。

isort
# isort: skip_file
# isort: on
# isort: off
# isort: skip
# isort: split

有关详细信息,请参阅 isort 文档

自动化指令
noqa

Ruff 支持多个工作流来帮助管理。

noqa

首先,Ruff 提供了一个特殊的规则代码,以强制你的指令是“有效的”,因为他们说他们忽略的违规实际上是在该行上触发的(因此被抑制)。你可以运行以标记未使用的指令。

RUF100
noqa
ruff /path/to/file.py --extend-select RUF100
noqa

其次,Ruff可以通过其自动修复功能自动删除未使用的指令。你可以运行以自动删除未使用的指令。

noqa
ruff /path/to/file.py --extend-select RUF100 --fix
noqa

第三,Ruff可以自动向所有故障行添加指令。这在将新代码库迁移到 Ruff 时很有用。你可以运行以使用适当的规则代码自动向所有故障行添加指令。

noqa
ruff /path/to/file.py --add-noqa
noqa

支持的规则

无论规则的来源如何,Ruff 都会将 Rust 中的每个规则作为第一方功能重新实现。

默认情况下,Ruff 启用 Flake8 和规则。Ruff 支持类别中的所有规则以及类别的子集,省略了那些因使用自动格式化程序(如 Black)而过时的样式规则。

E
F
F
E

表情符号表示🛠可通过命令行选项自动修复规则。

--fix

皮弗利特 (F)

有关更多信息,请参阅 PyPI 上的 Pyflakes

法典 名字 消息 修复
F401 未使用的导入
{name}
进口但未使用;考虑添加或使用冗余别名
__all__
🛠
F402系列 import-shadowed-by-loop-var 从循环变量阴影的行 {line} 导入
{name}
F403系列 进口星型使用
from {name} import *
使用;无法检测未定义的名称
F404系列 后期导入
from __future__
导入必须在文件的开头进行
F405 导入星型用法
{name}
可能未定义,或从星形导入定义:{源}
F406系列 不允许进口星星
from {name} import *
仅在模块级别允许
F407系列 未来未定义功能 未定义未来功能
{name}
F501系列 百分比格式无效格式
%
-格式字符串具有无效的格式字符串:{消息}
F502系列 百分比格式预期映射
%
-格式字符串预期映射,但得到序列
F503系列 百分比格式预期序列
%
-格式字符串预期序列,但得到映射
F504系列 百分比格式额外命名参数
%
-format 字符串具有未使用的命名参数:{消息}
🛠
F505系列 百分比格式缺失参数
%
-格式字符串缺少占位符的参数:{消息}
F506系列 百分比格式混合位置和命名
%
-format 字符串具有混合的位置和命名占位符
F507系列 百分比格式位置计数不匹配
%
-format 字符串具有 {wanted} 占位符,但 {got} 替换
F508系列 百分比格式星形要求序列
%
-格式字符串说明符需要序列
*
F509系列 百分比格式不支持的格式字符
%
-格式字符串具有不支持的格式字符“{char}”
F521 字符串点格式无效格式
.format
调用具有无效的格式字符串:{消息}
F522 字符串点格式额外命名参数
.format
调用具有未使用的命名参数:{消息}
🛠
F523 字符串点格式额外位置参数
.format
调用在位置有未使用的参数:{消息}
F524 字符串点格式缺少参数
.format
调用缺少占位符的参数:{消息}
F525 字符串-点-格式-混合-自动
.format
字符串混合自动和手动编号
F541 f 字符串缺失占位符 不带任何占位符的 f 字符串 🛠
F601 多值重复键文本 字典键文本重复
{name}
🛠
F602 多值重复键变量 字典键重复
{name}
🛠
F621 星形表达式赋值 星星解包分配中的表达式过多
F622 双星表达式 作业中的两个带星标的表达式
F631 断言元组 断言测试是一个非空元组,它总是
True
F632 是文字 用于比较常量文本
==
🛠
F633 无效的打印语法 函数使用无效
>>
print
F634 if-tuple 如果测试是一个元组,则始终
True
F701 断外循环
break
外环
F702 继续外循环
continue
未正确循环
F704 屈服外函数
{keyword}
函数外部的语句
F706 返回外部函数
return
函数/方法之外的语句
F707 默认,除非最后 不是最后一个异常处理程序的块
except
F722 前向批注语法错误 前向批注中的语法错误:
{body}
F811 未使用时重新定义 从行 {行} 重新定义未使用
{name}
F821 未定义的名称 未定义的名称
{name}
F822 未定义导出 中未定义的名称
{name}
__all__
F823 未定义本地 赋值前引用的局部变量
{name}
F841 未使用的变量 局部变量被赋值但从未使用
{name}
🛠
F842 未使用的注释 局部变量被批注但从未使用
{name}
F901 未实施的加注
raise NotImplemented
应该是
raise NotImplementedError
🛠

pycodestyle (E, W)

有关更多信息,请参阅 PyPI 上的 pycodestyle

错误 (E)

法典 名字 消息 修复
E101 混合空格和制表符 缩进包含混合空格和制表符
E401 一行多导入 一行多导入
E402 模块导入不在文件顶部 模块级导入不在文件顶部
E501 行太长 行太长({长度} > {限制} 个字符)
E711 无比较 比较应该是
None
cond is None
🛠
E712 真假比较 比较应该是
True
cond is True
🛠
E713 未在测试 成员资格测试应该是
not in
🛠
E714 非测试即测试 对象标识的测试应为
is not
🛠
E721 类型比较 不要比较类型,使用
isinstance()
E722 请勿使用裸露 不要裸露
except
E731 不要分配 lambda 不要分配表达式,请使用
lambda
def
🛠
E741 不明确的变量名称 不明确的变量名称:
{name}
E742 不明确的类名 不明确的类名:
{name}
E743 不明确的函数名称 不明确的函数名称:
{name}
E902 io-错误 {消息}
E999 语法错误 语法错误: {消息}

警告 (W)

法典 名字 消息 修复
W292 文件末尾无换行符 文件末尾没有换行符 🛠
W505系列 文档行太长 文档行太长({长度} > {限制} 个字符)
W605 无效转义序列 无效的转义序列:“{字符}” 🛠

麦凯布(C90)

有关更多信息,请参阅 PyPI 上的 mccabe

法典 名字 消息 修复
C901 功能太复杂
{name}
太复杂({复杂性})

isort (I)

有关更多信息,请参阅 PyPI 上的 isort

法典 名字 消息 修复
I001 未排序导入 导入块未排序或未格式化 🛠
I002型 缺少必需导入 缺少必需的导入:
{name}
🛠

PEP8 命名 (N)

有关更多信息,请参阅 PyPI 上的 pep8-nameing

法典 名字 消息 修复
N801 无效的类名 类名应使用CapWords约定
{name}
N802 无效的函数名称 函数名称应为小写
{name}
N803 无效的参数名称 参数名称应为小写
{name}
N804 无效的第一个参数名称的类方法 类方法的第一个参数应命名
cls
N805 方法的第一个参数名称无效 方法的第一个参数应命名
self
N806 函数中的非小写变量 函数中的变量应为小写
{name}
N807 下沉函数名称 函数名称不应以 开头和结尾
__
N811 常量导入为非常量 常量作为非常量导入
{name}
{asname}
N812 小写导入为非小写 以非小写形式导入的小写
{name}
{asname}
N813 驼峰大小写导入为小写 驼峰大小写作为小写导入
{name}
{asname}
N814 Camel 箱进口为常数 Camel 箱作为常量导入
{name}
{asname}
N815 类范围内的混合大小写变量 类范围内的变量不应混合大小写
{name}
N816 全局范围内的混合大小写变量 全局范围内的变量不应混合大小写
{name}
N817 驼峰-导入为首字母缩略词 驼峰作为首字母缩略词导入
{name}
{asname}
N818 异常名称上的错误后缀 异常名称应使用错误后缀命名
{name}

皮多克风格 (D)

有关更多信息,请参阅 PyPI 上的 pydocstyle

法典 名字 消息 修复
D100 公共模块 公共模块中缺少文档字符串
D101 公共类 公共类中缺少文档字符串
D102 公共方法 公共方法中缺少文档字符串
D103 公共功能 公共函数中缺少文档字符串
D104 公共包 公共包中缺少文档字符串
D105 魔术法 魔术方法中缺少文档字符串
D106 公共嵌套类 公共嵌套类中缺少文档字符串
D107 public-init 中缺少文档字符串
__init__
D200 适合单线 一行文档字符串应适合一行 🛠
D201 函数前无空行 函数文档字符串之前不允许有空行(找到 {num_lines}) 🛠
D202 无空行后函数 函数文档字符串后不允许有空行(找到 {num_lines}) 🛠
D203 课前一行空行 类文档字符串前需要 1 个空行 🛠
D204 课后一行空行 类文档字符串后需要 1 个空行 🛠
D205 摘要后的空行 摘要行和说明之间需要 1 个空行 🛠
D206 带空格的缩进 文档字符串应该用空格缩进,而不是制表符
D207 无压痕 文档字符串缩进不足 🛠
D208 无过度缩进 文档字符串过度缩进 🛠
D209 最后一段后换行符 多行文档字符串结束引号应位于单独的行上 🛠
D210 无环绕空格 文档字符串文本周围不允许有空格 🛠
D211 课前无空行 类文档字符串之前不允许有空行 🛠
D212 多行摘要第一行 多行文档字符串摘要应从第一行开始 🛠
D213 多行摘要第二行 多行文档字符串摘要应从第二行开始 🛠
D214 节不过度缩进 节过度缩进(“{name}”) 🛠
D215 节下划线不过度缩进 节下划线过度缩进(“{name}”) 🛠
D300 使用三引号 使用 “”“”三重双引号“””
D301 使用反斜杠内容的 r 前缀 如果文档字符串中有任何反斜杠,请使用 r“””
D400 期末 第一行应以句点结尾 🛠
D401 非命令性情绪 文档字符串的第一行应该是命令式的:“{first_line}”
D402 无签名 第一行不应是函数的签名
D403 首行大写 第一行的第一个单词应正确大写
D404 无此前缀 文档字符串的第一个单词不应该是“This”
D405 大写部分名称 节名应正确大写(“{name}”) 🛠
D406 节后换行符名称 节名称应以换行符(“{name}”)结尾 🛠
D407 节后虚线下划线 节后缺少虚线下划线(“{name}”) 🛠
D408 部分下划线后的名称 节下划线应位于节名称(“{name}”)后面的行中 🛠
D409 节-下划线匹配-节长度 节下划线应与其名称(“{name}”)的长度匹配 🛠
D410 节后空行 节后缺少空行(“{name}”) 🛠
D411 节前空行 节前缺少空行(“{name}”) 🛠
D412 标题和内容之间无空行 节标题与其内容之间不允许有空行(“{name}”) 🛠
D413 最后一个部分之后的空行 最后一节(“{name}”)后缺少空行 🛠
D414 非空部分 部分没有内容(“{名称}”)
D415 标点符号结尾 第一行应以句点、问号或感叹号结尾 🛠
D416 节名以冒号结尾 节名称应以冒号(“{name}”)结尾 🛠
D417 记录所有参数 文档字符串中缺少参数描述:
{name}
D418 跳过文档字符串 用 修饰的函数不应包含文档字符串
@overload
D419 非空 文档字符串为空

pyupgrade (UP)

有关更多信息,请参阅 PyPI 上的 pyupgrade

法典 名字 消息 修复
UP001 无用元类类型
__metaclass__ = type
是隐含的
🛠
UP003 基元类型 使用代替
{}
type(...)
🛠
UP004 无用对象继承 类继承自
{name}
object
🛠
UP005 已弃用的单元测试别名
{alias}
已弃用,使用
{target}
🛠
UP006 使用-pep585-注释 用于代替类型批注
{}
{}
🛠
UP007 使用-pep604-注释 用于类型批注
X | Y
🛠
UP008 带参数的超级调用 使用代替
super()
super(__class__, self)
🛠
UP009 pep3120-不必要的编码注释 不需要 UTF-8 编码声明 🛠
UP010 不必要的未来导入 目标 Python 版本的不必要导入
__future__
{import}
🛠
UP011 lru-cache-without-parameters 不必要的参数
functools.lru_cache
🛠
UP012 不必要的编码utf8 不必要的调用 UTF-8
encode
🛠
UP013 将类型字典函数转换为类 从函数语法转换为类语法
{name}
TypedDict
🛠
UP014 将命名元组函数转换为类 从函数语法转换为类语法
{name}
NamedTuple
🛠
UP015 冗余开放模式 不必要的开放模式参数 🛠
UP016 删除六兼容 不必要的兼容性使用
six
🛠
UP017 日期时间-时区-utc 使用别名
datetime.UTC
🛠
UP018 本机文本 不必要的调用
{literal_type}
🛠
UP019 键入文本 str 别名
typing.Text
已弃用,使用
str
🛠
UP020 打开别名 使用内置
open
🛠
UP021 替换通用换行符
universal_newlines
已弃用,使用
text
🛠
UP022 replace-stdout-stderr 不推荐将标准输出和标准输出发送到管道,请使用
capture_output
🛠
UP023 重写-c-元素树
cElementTree
已弃用,使用
ElementTree
🛠
UP024 操作系统错误别名 将别名错误替换为
OSError
🛠
UP025 重写-unicode-文字 从字符串中删除 unicode 文本 🛠
UP026 重写-模拟-导入
mock
已弃用,使用
unittest.mock
🛠
UP027 重写列表理解 将解压缩列表推导式替换为生成器表达式 🛠
UP028 重写产量 将 over 循环替换为
yield
for
yield from
🛠
UP029 不必要的内置导入 不必要的内置导入:
{import}
🛠
UP030 格式文本 对位置格式字段使用隐式引用 🛠
UP031 printf-string-format 使用格式说明符而不是百分比格式 🛠
UP032 f 字符串 使用 f 字符串代替调用
format
🛠
UP033 functools-cache 使用代替
@functools.cache
@functools.lru_cache(maxsize=None)
🛠
UP034 无关括号 避免使用多余的括号 🛠

片状8-2020 (YTT)

有关更多信息,请参阅 PyPI 上的 flake8-2020

法典 名字 消息 修复
YTT101 系统版本切片3引用
sys.version[:3]
参考 (python3.10),使用
sys.version_info
YTT102 系统版本 2 引用
sys.version[2]
参考 (python3.10),使用
sys.version_info
YTT103 sys-version-cmp-str3
sys.version
与字符串 (python3.10) 相比,请使用
sys.version_info
YTT201 sys-version-info0-eq3-reference
sys.version_info[0] == 3
引用 (python4),使用
>=
YTT202 六 py3 引用
six.PY3
引用 (python4),使用
not six.PY2
YTT203 sys-version-info1-cmp-int
sys.version_info[1]
与整数(python4)相比,与元组相比
sys.version_info
YTT204 sys-version-info-minor-cmp-int
sys.version_info.minor
与整数(python4)相比,与元组相比
sys.version_info
YTT301 系统版本 0 引用
sys.version[0]
引用 (python10),使用
sys.version_info
YTT302 sys-version-cmp-str10
sys.version
与字符串 (python10) 相比,使用
sys.version_info
YTT303 系统版本切片1引用
sys.version[:1]
引用 (python10),使用
sys.version_info

薄片8注释 (ANN)

有关更多信息,请参阅 PyPI 上的 flake8-annotations

法典 名字 消息 修复
ANN001 缺少类型函数参数 缺少函数参数的类型注释
{name}
安002 缺少类型参数 缺少 的类型批注
*{name}
ANN003 失踪型夸格斯 缺少 的类型批注
**{name}
安101 失踪型自我 缺少 in 方法的类型批注
{name}
安102 缺少类型-cls 缺少类方法中的类型批注
{name}
安201 缺少返回类型公共函数 缺少公共函数的返回类型注释
{name}
安202 缺少返回类型私有函数 缺少私有函数的返回类型注释
{name}
安204 缺少返回类型特殊方法 缺少特殊方法的返回类型注释
{name}
🛠
安205 缺少返回类型静态方法 缺少静态方法的返回类型注释
{name}
安206 缺少返回类型类方法 缺少类方法的返回类型批注
{name}
安401 动态类型表达式 动态类型化表达式(键入。任何)在
{name}

片状8-强盗(S)

有关更多信息,请参阅 PyPI 上的 flake8-bandit

法典 名字 消息 修复
S101系列 断言使用 使用检测到的
assert
S102系列 执行器使用 使用检测到的
exec
S103 错误的文件权限
os.chmod
在文件或目录上设置宽松掩码
{mask:#o}
S104 硬编码绑定所有接口 可能绑定到所有接口
S105系列 硬编码密码字符串 可能的硬编码密码:“{}”
S106系列 硬编码密码函数参数 可能的硬编码密码:“{}”
S107系列 硬编码密码默认值 可能的硬编码密码:“{}”
S108系列 硬编码临时文件 临时文件或目录可能不安全的使用:“{}”
S110系列 尝试-例外-通过
try
-
except
-
pass
检测到,请考虑记录异常
S113系列 无超时请求 可能使用超时设置为
{value}
S324系列 hashlib-insecure-hash-function 可能在:“{}”中使用不安全的哈希函数
hashlib
S501系列 无证书验证的请求 可能使用禁用 SSL 证书检查的调用
{string}
verify=False
S506系列 不安全的 yaml 负载 可能将不安全的装载机与 一起使用。允许实例化任意对象。考虑。
{name}
yaml.load
yaml.safe_load
S508系列 snmp-不安全版本 SNMPv1 和 SNMPv2 的使用不安全。如果可以,请使用 SNMPv3。
S509系列 snmp-弱密码学 不应在未加密的情况下使用 SNMPv3。 并且不安全。
noAuthNoPriv
authNoPriv
S612系列 logging-config-insecure-listen 检测到不安全的使用
logging.config.listen
S701系列 金贾2-自动转义-假 使用 jinja2 模板很危险,可能会导致 XSS。确保或使用该功能。
autoescape=False
autoescape=True
select_autoescape

片状8-盲区-除了 (BLE)

有关更多信息,请参阅 PyPI 上的 flake8-blind-except

法典 名字 消息 修复
BLE001 盲人除外 不要捕获盲目异常:
{name}

薄片8-布尔陷阱 (FBT)

有关更多信息,请参阅 PyPI 上的 flake8-boolean-trap

法典 名字 消息 修复
FBT001 布尔-位置-参数-在函数定义 函数定义中的布尔位置参数
FBT002 布尔默认值函数定义 函数定义中的布尔默认值
FBT003 布尔值位置函数调用 函数调用中的布尔位置值

薄片8-虫熊(B)

有关更多信息,请参阅 PyPI 上的 flake8-bugbear

法典 名字 消息 修复
B002系列 一元前缀增量 Python 不支持一元前缀增量
B003系列 assignment-to-os-environ 分配给不会清除环境
os.environ
B004系列 不可靠的可调用支票 用于测试 x 是否可调用是不可靠的。用于获得一致的结果。
hasattr(x, '__call__')
callable(x)
B005系列 带多字符的条 使用多字符字符串会误导读者
.strip()
B006系列 可变参数默认值 不要将可变数据结构用于参数默认值
B007系列 未使用的循环控制变量 回路主体内未使用的环路控制变量
{name}
🛠
货号 B008系列 函数调用参数默认值 不要在参数默认值中执行函数调用
{name}
货号 B009系列 获取常量吸引力 不要使用常量属性值进行调用。它并不比正常的财产访问更安全。
getattr
🛠
B010系列 设置常量属性 不要使用常量属性值进行调用。它并不比正常的财产访问更安全。
setattr
🛠
B011系列 不要断言错误 不要(删除这些调用),提高
assert False
python -O
AssertionError()
🛠
B012系列 跳入最后的语句
{name}
内部块会导致异常被静音
finally
B013系列 冗余元组异常处理程序 长度为一的元组文本是多余的。用“写入”代替 。
except {name}
except ({name},)
🛠
B014系列 重复处理程序异常 具有重复异常的异常处理程序:
{name}
🛠
B015系列 无用的比较 毫无意义的比较。这种比较只会浪费 CPU 指令。预置或删除它。
assert
B016系列 不能提高字面意思 不能提出文字。你打算退回它还是提出异常?
B017系列 无断言引发异常
assertRaises(Exception)
应该被认为是邪恶的
B018系列 无用的表达 发现无用的表达。将其分配给变量或删除它。
B019系列 缓存实例方法 使用 或 on 方法可能会导致内存泄漏
functools.lru_cache
functools.cache
B020系列 循环变量覆盖迭代器 循环控制变量覆盖它迭代的可迭代
{name}
B021系列 f-string-docstring 用作文档字符串的 F 字符串。这将被 python 解释为连接的字符串而不是文档字符串。
B022系列 无用的上下文库抑制 没有参数传递给 。不会禁止任何异常,因此此上下文管理器是多余的
contextlib.suppress
B023系列 函数使用循环变量 函数定义不绑定循环变量
{name}
B024系列 抽象基类无抽象方法
{name}
是一个抽象基类,但它没有抽象方法
B025系列 重复尝试块异常 具有重复异常的 try-except 块
{name}
B026系列 Asterisk -参数-解包-后关键字-参数 强烈建议不要在关键字参数后进行星形参数解包
B027系列 空方法没有抽象装饰器
{name}
是抽象基类中的空方法,但没有抽象修饰器
B904系列 从内到外加 在 except 子句中,在异常处理中引发异常或将其与错误区分开来
raise ... from err
raise ... from None
B905系列 zip-without-explicit-strict
zip()
没有显式参数
strict=

薄片8-内置 (A)

有关更多信息,请参阅 PyPI 上的 flake8-builtins

法典 名字 消息 修复
货段:A001型 内置变量阴影 变量正在隐藏内置的python
{name}
A002 内置参数阴影 参数正在隐藏内置的python
{name}
货A003 内置属性阴影 类属性正在隐藏内置的python
{name}

片状8-逗号 (COM)

有关更多信息,请参阅 PyPI 上的 flake8 逗号

法典 名字 消息 修复
COM812 尾随逗号缺失 缺少尾随逗号 🛠
COM818 禁止在裸元组上使用尾随逗号 禁止在裸元组上使用尾随逗号
COM819 禁止尾随逗号 禁止尾随逗号 🛠

薄片8-理解 (C4)

有关更多信息,请参阅 PyPI 上的 flake8-comprehensions

法典 名字 消息 修复
C400 不必要的生成器列表 不必要的生成器(重写为理解)
list
🛠
C401 不必要的发电机组 不必要的生成器(重写为理解)
set
🛠
C402 不必要的生成器字典 不必要的生成器(重写为理解)
dict
🛠
C403 不必要的列表理解集 不必要的理解(重写为理解)
list
set
🛠
C404 不必要的列表理解字典 不必要的理解(重写为理解)
list
dict
🛠
C405 不必要的文字集 不必要的文字(重写为文字)
{obj_type}
set
🛠
C406 不必要的字面词典 不必要的文字(重写为文字)
{obj_type}
dict
🛠
C408 不必要的收集调用 不必要的调用(重写为文字)
{obj_type}
🛠
C409 不必要的元组内文字调用 不必要的文字传递给(重写为文字)
{literal}
tuple()
tuple
🛠
C410 不必要的文本列表内调用 不必要的文本传递给 (删除对
{literal}
list()
list()
)
🛠
C411 不必要的列表调用 不必要的调用(删除对 的外部调用)
list
list()
)
🛠
C413 不必要的呼叫排序 不必要的通话
{func}
sorted()
🛠
C414 不必要的双转换或过程 内部不必要的呼叫
{inner}
{outer}()
C415 不必要的下标反转 在可迭代中不必要的下标反转
{func}()
C416 不必要的理解 不必要的理解(使用
{obj_type}
{obj_type}()
)
🛠
C417 不必要的 map 不必要的用法(使用生成器表达式重写)
map

flake8-datetimez (DTZ)

有关更多信息,请参阅 PyPI 上的 flake8-datetimez

法典 名字 消息 修复
DTZ001 call-datetime-without-tzinfo 不允许使用不带参数的
datetime.datetime()
tzinfo
DTZ002 呼叫日期时间-今天 不允许使用,而是使用。
datetime.datetime.today()
datetime.datetime.now(tz=)
DTZ003 呼叫日期时间-utcnow 不允许使用,而是使用。
datetime.datetime.utcnow()
datetime.datetime.now(tz=)
DTZ004 调用日期时间 utc来自时间戳 不允许使用,而是使用。
datetime.datetime.utcfromtimestamp()
datetime.datetime.fromtimestamp(ts, tz=)
DTZ005 呼叫日期时间-现在-没有-tzinfo 不允许使用不带参数的
datetime.datetime.now()
tz
DTZ006 调用日期时间从时间戳 不允许使用不带参数的
datetime.datetime.fromtimestamp()
tz
DTZ007 调用日期时间-时间-无区域 使用不带 %z 时必须跟 或
datetime.datetime.strptime()
.replace(tzinfo=)
.astimezone()
DTZ011 呼叫日期-今天 不允许使用,而是使用。
datetime.date.today()
datetime.datetime.now(tz=).date()
DTZ012 调用日期发件人时间戳 不允许使用,而是使用。
datetime.date.fromtimestamp()
datetime.datetime.fromtimestamp(ts, tz=).date()

薄片8-调试器 (T10)

有关更多信息,请参阅 PyPI 上的 flake8-debugger

法典 名字 消息 修复
T100 调试器 找到的跟踪:已使用
{name}

薄片8-errmsg (EM)

有关更多信息,请参阅 PyPI 上的 flake8-errmsg

法典 名字 消息 修复
EM101 异常中的原始字符串 异常不得使用字符串文字,首先分配给变量
EM102 f-string-in-exception 异常不得使用 f 字符串文字,首先分配给变量
EM103 点格式异常 异常不能直接使用字符串,先赋给变量
.format()

flake8-可执行文件 (EXE)

有关更多信息,请参阅 PyPI 上的 flake8-可执行文件

法典 名字 消息 修复
EXE001 社邦-不可执行 社邦存在,但文件不可执行
EXE002 社邦-丢失-可执行文件 该文件是可执行的,但不存在 shebang
EXE003 蛇邦 anaconda 社邦应该包含“ anaconda ”
EXE004 社邦-空白 避免在 shebang 之前留空格 🛠
EXE005 社邦-换行线 社邦应该在文件的开头

flake8-implicit-str-concat (ISC)

有关更多信息,请参阅 PyPI 上的 flake8-implicit-str-concat

法典 名字 消息 修复
国际标准书号001 单行隐式字符串串联 一行上的隐式串联字符串文本
国际标准刊号002 多行隐式字符串串联 延续行上的隐式串联字符串文本
国际标准书号003 显式字符串串联 显式连接的字符串应隐式连接

薄片8-进口公约 (ICN)

有关更多信息,请参阅 GitHub 上的 flake8-import-Convention

法典 名字 消息 修复
ICN001 导入别名不是常规的
{name}
应导入为
{asname}

片状8-日志记录格式 (G)

有关详细信息,请参阅 PyPI 上的 flake8-logging-format

法典 名字 消息 修复
G001 日志记录字符串格式 日志记录语句使用
string.format()
G002 日志记录百分比格式 日志记录语句使用
%
G003 logging-string-concat 日志记录语句使用
+
G004 logging-f-string 日志记录语句使用 f 字符串
G010 日志记录警告 日志记录语句使用代替
warn
warning
🛠
G101 日志记录-额外属性-冲突 日志记录语句使用与 LogRecord 字段冲突的额外字段:
{key}
G201 日志记录-exc-info 应使用日志记录而不是
.exception(...)
.error(..., exc_info=True)
G202 logging-redundant-exc-info 日志记录语句具有冗余
exc_info

薄片8-无PEP420 (INP)

有关更多信息,请参阅 PyPI 上的 flake8-no-pep420

法典 名字 消息 修复
INP001 隐式命名空间包 文件是隐式命名空间包的一部分。添加一个 .
{filename}
__init__.py

薄片8-馅饼 (馅饼)

有关更多信息,请参阅 PyPI 上的 flake8-pie

法典 名字 消息 修复
PIE790 无不必要的通行证 不必要的语句
pass
🛠
PIE794 重复类字段定义 多次定义类字段
{name}
🛠
PIE796 首选唯一枚举 枚举包含重复值:
{value}
PIE800 无不必要的传播 不必要的点差
**
PIE804 没有不必要的字典-夸格斯 不必要的夸格
dict
PIE807 首选列表内置 更喜欢无用的 lambda
list
🛠

片状8印花 (T20)

有关更多信息,请参阅 PyPI 上的 flake8-print

法典 名字 消息 修复
T201 打印找到
print
发现
🛠
T203 p-打印找到
pprint
发现
🛠

薄片8-pytest风格(PT)

有关更多信息,请参阅 PyPI 上的 flake8-pytest 样式

法典 名字 消息 修复
PT001 不正确的夹具括号样式 使用过度
@pytest.fixture{expected_parens}
@pytest.fixture{actual_parens}
🛠
PT002 夹具-位置-参数 通过位置参数指定的夹具配置,使用 kwargs
{function}
PT003 无关范围函数
scope='function'
隐含在
@pytest.fixture()
PT004 缺少灯具名称下划线 夹具不返回任何内容,添加前导下划线
{function}
PT005 不正确的灯具名称下划线 灯具返回一个值,删除前导下划线
{function}
PT006 参数名称错误类型 在 中键入错误的名称,预计
@pytest.mark.parametrize
{expected}
🛠
PT007 参数化值错误类型 预期值类型错误
@pytest.mark.parametrize
{values}
{row}
PT008 带有λ的补丁 使用而不是修补
return_value=
lambda
PT009 单元测试断言 使用常规样式而不是单元测试样式
assert
{assertion}
🛠
PT010 无一例外地加薪 在 中设置预期的异常
pytest.raises()
PT011 加得太宽泛
pytest.raises({exception})
过于宽泛,设置参数或使用更具体的例外
match
PT012 使用多个语句提高
pytest.raises()
块应包含单个简单语句
PT013 不正确的-pytest-import 发现 pytest 导入不正确,改用简单
import pytest
PT015 断言总是错误的 断言总是失败,替换为
pytest.fail()
PT016 失败而不显示消息 没有消息传递到
pytest.fail()
PT017 断言在除非 在除块之外发现异常断言,请改用
{name}
pytest.raises()
PT018 复合断言 断言应分解为多个部分
PT019 没有值的夹具参数 没有值的夹具作为参数注入,改用
{name}
@pytest.mark.usefixtures
PT020 已弃用的产量夹具
@pytest.yield_fixture
已弃用,使用
@pytest.fixture
PT021 赛程终结器回调 使用代替
yield
request.addfinalizer
PT022 无用的产量夹具 夹具中无需拆卸,代替
{name}
return
yield
🛠
PT023 不正确的标记括号样式 使用过度
@pytest.mark.{mark_name}{expected_parens}
@pytest.mark.{mark_name}{actual_parens}
🛠
PT024 不必要-异步-标记-在-夹具上
pytest.mark.asyncio
对于夹具是不必要的
🛠
PT025 错误使用夹具上的夹具
pytest.mark.usefixtures
对夹具没有影响
🛠
PT026 使用夹具不带参数 没有参数就没用
pytest.mark.usefixtures
🛠

片状8引号 (Q)

有关更多信息,请参阅 PyPI 上的 flake8 引号

法典 名字 消息 修复
Q000 错误引号内联字符串 找到双引号,但首选单引号 🛠
Q001 错误引号-多行字符串 找到双引号多行,但首选单引号 🛠
Q002 错误引号文档字符串 找到双引号文档字符串,但首选单引号 🛠
Q003 避免-引用-转义 更改外部引号以避免转义内部引号 🛠

薄片8-返回 (RET)

有关更多信息,请参阅 PyPI 上的 flake8-return

法典 名字 消息 修复
RET501 不必要-返回-无 如果函数是唯一可能的返回值,则不要在函数中显式执行
return None
🛠
RET502 隐式返回值 不要隐式地在函数中能够返回非值
return None
None
🛠
RET503 隐式返回 在函数末尾缺少显式,能够返回非值
return
None
🛠
RET504 不必要的分配 语句前不必要的变量赋值
return
RET505 多余的其他回报 语句后不必要的
{branch}
return
RET506 多余的其他加薪 语句后不必要的
{branch}
raise
RET507 多余-否则-继续 语句后不必要的
{branch}
continue
RET508 多余的其他休息 语句后不必要的
{branch}
break

薄片8-简化 (SIM)

有关更多信息,请参阅 PyPI 上的 flake8-simple

法典 名字 消息 修复
SIM101 重复是实例调用 多个调用 ,合并为单个调用
isinstance
{name}
🛠
SIM102 嵌套的 if 语句 使用单个语句而不是嵌套语句
if
if
🛠
SIM103 直接返回布尔条件 直接返回条件
{cond}
🛠
SIM105 use-contextlib-suppress 使用而不是尝试-例外-通过
contextlib.suppress({exception})
SIM107 返回尝试,但最终除外 不要在/和
return
try
except
finally
SIM108 使用三元运算符 使用三元运算符代替 if-else-block
{contents}
🛠
SIM109 与元组比较 使用而不是多个相等比较
{replacement}
🛠
SIM110 将循环转换为任意 使用代替循环
{any}
for
🛠
SIM111 转换循环到全部 使用代替循环
{all}
for
🛠
SIM112 使用-资本-环境-变量 使用大写的环境变量而不是
{expected}
{original}
🛠
SIM115 打开带上下文的文件处理程序 使用上下文处理程序打开文件
SIM117 多个语句 使用具有多个上下文的单个语句而不是嵌套语句
with
with
🛠
SIM118 键在字典 使用代替
{key} in {dict}
{key} in {dict}.keys()
🛠
SIM201 否定相等运算 使用代替
{left} != {right}
not {left} == {right}
🛠
SIM202 否定不等于操作 使用代替
{left} == {right}
not {left} != {right}
🛠
SIM208 双重否定 使用代替
{expr}
not (not {expr})
🛠
SIM210 if-expr-with-true-false 使用代替
bool({expr})
True if {expr} else False
🛠
SIM211 if-expr-with-false-true 使用代替
not {expr}
False if {expr} else True
🛠
SIM212 如果用扭曲的手臂 使用代替
{expr_else} if {expr_else} else {expr_body}
{expr_body} if not {expr_else} else {expr_else}
🛠
SIM220 a-and-not-a 使用代替
False
{name} and not {name}
🛠
SIM221 a-or not-a 使用代替
True
{name} or not {name}
🛠
SIM222 或-真 使用代替
True
... or True
🛠
SIM223 和假 使用代替
False
... and False
🛠
SIM300 尤达条件 不鼓励尤达条件,改用
{suggestion}
🛠
SIM401 字典获取默认值 使用代替块
{contents}
if
🛠

片状8-整齐-进口 (TID)

有关更多信息,请参阅 PyPI 上的 flake8-tidy-import

法典 名字 消息 修复
TID251 禁止的 api
{name}
被禁止:{消息}
TID252 相对进口 禁止从父模块进行相对导入

片状8型检查(TCH)

有关详细信息,请参阅 PyPI 上的 flake8 类型检查

法典 名字 消息 修复
TCH001 仅键入第一方导入 将应用程序导入移动到类型检查块中
{}
TCH002 仅键入第三方导入 将第三方导入移动到类型检查块中
{}
TCH003 仅键入标准库导入 将标准库导入移动到类型检查块中
{}
TCH004 运行时导入类型检查块 将导入移出类型检查块。导入不仅仅用于类型提示。
{}
TCH005 空类型检查块 找到空的类型检查块

flake8-unused-arguments (ARG)

有关更多信息,请参阅 PyPI 上的 flake8-unused-argument

法典 名字 消息 修复
ARG001 未使用的函数参数 未使用的函数参数:
{name}
ARG002 未使用的方法参数 未使用的方法参数:
{name}
ARG003 未使用的类方法参数 未使用的类方法参数:
{name}
ARG004 未使用的静态方法参数 未使用的静态方法参数:
{name}
ARG005 未使用的 lambda 参数 未使用的 lambda 参数:
{name}

flake8-use-pathlib (PTH)

有关更多信息,请参阅 PyPI 上的 flake8-use-pathlib

法典 名字 消息 修复
PTH100 pathlib-abspath
os.path.abspath
应替换为
.resolve()
PTH101 pathlib-chmod
os.chmod
应替换为
.chmod()
PTH102 pathlib-mkdir
os.mkdir
应替换为
.mkdir()
PTH103 pathlib-makedirs
os.makedirs
应替换为
.mkdir(parents=True)
PTH104 路径库重命名
os.rename
应替换为
.rename()
PTH105 路径库-替换
os.replace
应替换为
.replace()
PTH106 pathlib-rmdir
os.rmdir
应替换为
.rmdir()
PTH107 路径库删除
os.remove
应替换为
.unlink()
PTH108 路径库-取消链接
os.unlink
应替换为
.unlink()
PTH109 pathlib-getcwd
os.getcwd()
应替换为
Path.cwd()
PTH110 路径库-存在
os.path.exists
应替换为
.exists()
PTH111 pathlib-expanduser
os.path.expanduser
应替换为
.expanduser()
PTH112 pathlib-is-dir
os.path.isdir
应替换为
.is_dir()
PTH113 路径库是文件
os.path.isfile
应替换为
.is_file()
PTH114 路径库是链接
os.path.islink
应替换为
.is_symlink()
PTH115 pathlib-readlink
os.readlink(
应替换为
.readlink()
PTH116 pathlib-stat
os.stat
应替换为 或 或
.stat()
.owner()
.group()
PTH117 pathlib-is-abs
os.path.isabs
应替换为
.is_absolute()
PTH118 路径库-联接
os.path.join
应替换为foo_path/“bar”
PTH119 路径库-基名
os.path.basename
应替换为
.name
PTH120 pathlib-dirname
os.path.dirname
应替换为
.parent
PTH121 路径库-相同文件
os.path.samefile
应替换为
.samefile()
PTH122 pathlib-splitext
os.path.splitext
应替换为
.suffix
PTH123 路径库开放
open("foo")
应替换为
Path("foo").open()
PTH124 pathlib-py-path
py.path
处于维护模式,请改用
pathlib

根除(时代)

有关更多信息,请参阅PyPI上的根除

法典 名字 消息 修复
时代001 注释掉的代码 找到注释掉的代码 🛠

pandas 兽医 (PD)

有关更多信息,请参阅PyPI上的pandas-vet

法典 名字 消息 修复
PD002 使用就地参数
inplace=True
应避免;它的行为不一致
PD003 点的使用为空
.isna
优先于 ;功能等效
.isnull
PD004 使用点不为空
.notna
优先于 ;功能等效
.notnull
PD007 点九的使用
.ix
已弃用;使用更明确的或
.loc
.iloc
PD008 点点的使用 使用代替 。如果速度很重要,请使用 numpy。
.loc
.at
PD009 点 iat 的使用 使用代替 。如果速度很重要,请使用 numpy。
.iloc
.iat
PD010 使用点枢轴或取消堆叠
.pivot_table
优先于 或 ;提供相同的功能
.pivot
.unstack
PD011 点值的使用 使用代替
.to_numpy()
.values
PD012 点读取表的使用
.read_csv
优先于 ;提供相同的功能
.read_table
PD013 点堆的使用
.melt
优先于 ;提供相同的功能
.stack
PD015 pd合并的使用 使用方法而不是函数。它们具有等效的功能。
.merge
pd.merge
PD901 df-is-a-bad-variable-name
df
是一个错误的变量名称。善待未来的自己。

侏儒钩 (PGH)

有关更多信息,请参阅 GitHub 上的 pygrep-hooks

法典 名字 消息 修复
PGH001 无评估 不允许内置
eval()
PGH002 已弃用的日志警告
warn
已弃用,取而代之的是
warning
PGH003 毯子类型忽略 忽略类型问题时使用特定规则代码
PGH004 毯子-诺卡 使用时使用特定规则代码
noqa

皮林特(波兰)

有关更多信息,请参阅 PyPI 上的 Pylint

公约 (PLC)

法典 名字 消息 修复
PLC0414 无用导入别名 导入别名不重命名原始包 🛠
PLC3002 不必要的直接 lambda 调用 直接调用的 Lambda 表达式。改为以内联方式执行表达式。

错误 (PLE)

法典 名字 消息 修复
PLE0117 非本地无绑定 找到未绑定的非本地名称
{name}
PLE0118 使用的先行全局声明 名称在第 {line } 行上的全局声明之前使用
{name}
编号: PLE0604 无效的所有对象 中的无效对象必须仅包含字符串
__all__
PLE0605 无效的所有格式 的格式无效,必须为 或
__all__
tuple
list
PLE1142 await-outside-async
await
应在异步函数中使用

重构 (公共出借权)

法典 名字 消息 修复
PLR0133 常量比较 比较比较两个常量,考虑替换
{left_constant} {op} {right_constant}
PLR0206 带参数的属性 不能为属性定义参数
PLR0402 考虑从导入使用-使用 用于代替别名
from {module} import {name}
PLR1701 考虑合并是实例 合并这些实例调用:
isinstance({obj}, ({types}))
PLR1722 使用系统退出 使用代替
sys.exit()
{name}
🛠
PLR2004 魔术值比较 比较中使用的魔术值,请考虑将 {value} 替换为常量变量

警告 (PLW)

法典 名字 消息 修复
PLW0120 无用的在环上 循环中的 else 子句没有 break 语句,删除 else 并取消缩进其中的所有代码
PLW0602 全局变量未赋值 使用全局 for 但不进行赋值
{name}

锥角龙 (土耳其里拉)

有关更多信息,请参阅 PyPI 上的锥角龙

法典 名字 消息 修复
TRY002 雷西 Vanilla 级 创建你自己的例外
TRY003 赖斯- Vanilla -参数 避免在异常类之外指定长消息
TRY004 首选类型错误 无效类型首选异常
TypeError
🛠
TRY200 无缘无故的重新提出 用于指定异常原因
raise from
TRY201 详细提高 使用而不指定异常名称
raise
TRY300 尝试考虑其他 考虑将此语句移动到块
else
TRY301 在尝试中提高 抽象为内部函数
raise
TRY400 错误而不是异常 使用代替
logging.exception
logging.error

特定于褶皱的规则(联阵)

法典 名字 消息 修复
RUF001 歧义-统一码-字符串 字符串包含不明确的 unicode 字符“{confusable}”(你的意思是“{representant}”吗? 🛠
RUF002 模棱两可的统一码字符文档字符串 文档字符串包含不明确的 unicode 字符“{confusable}”(你的意思是“{representant}”吗? 🛠
RUF003 歧义-unicode-字符-注释 注释包含不明确的 unicode 字符“{confusable}”(你的意思是“{representant}”吗? 🛠
RUF004 关键字参数-在 Asterisk 参数之前 关键字参数必须位于加星标的参数之后
{name}
RUF005 解压缩而不是连接到集合文本 考虑而不是串联
{expr}
RUF100 未使用的-noqa 未使用的总指令
noqa
🛠

编辑器集成

VS 代码(官方)

下载 Ruff VS Code 扩展,它支持自动修复操作、导入排序等。

语言服务器协议(官方)

Ruff通过PyPI上提供的ruff-lsp Python包支持语言服务器协议

ruff-lsp使Ruff能够与任何支持语言服务器协议的编辑器一起使用,包括NeovimSublime Text,Emacs等。

例如,要与 Neovim 一起使用,请从 PyPI 与 nvim-lspconfig 一起安装。然后,将类似以下内容的内容添加到你的:

ruff-lsp
ruff-lsp
init.lua

-- See: https://github.com/neovim/nvim-lspconfig/tree/54eb2a070a4f389b1be0f98070f81d23e2b1a715#suggested-configuration
local opts = { noremap=true, silent=true }
vim.keymap.set('n', '<space>e', vim.diagnostic.open_float, opts)
vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, opts)
vim.keymap.set('n', ']d', vim.diagnostic.goto_next, opts)
vim.keymap.set('n', '<space>q', vim.diagnostic.setloclist, opts)

-- Use an on_attach function to only map the following keys
-- after the language server attaches to the current buffer
local on_attach = function(client, bufnr)
  -- Enable completion triggered by <c-x><c-o>
  vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc')

  -- Mappings.
  -- See `:help vim.lsp.*` for documentation on any of the below functions
  local bufopts = { noremap=true, silent=true, buffer=bufnr }
  vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, bufopts)
  vim.keymap.set('n', 'gd', vim.lsp.buf.definition, bufopts)
  vim.keymap.set('n', 'K', vim.lsp.buf.hover, bufopts)
  vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, bufopts)
  vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help, bufopts)
  vim.keymap.set('n', '<space>wa', vim.lsp.buf.add_workspace_folder, bufopts)
  vim.keymap.set('n', '<space>wr', vim.lsp.buf.remove_workspace_folder, bufopts)
  vim.keymap.set('n', '<space>wl', function()
    print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
  end, bufopts)
  vim.keymap.set('n', '<space>D', vim.lsp.buf.type_definition, bufopts)
  vim.keymap.set('n', '<space>rn', vim.lsp.buf.rename, bufopts)
  vim.keymap.set('n', '<space>ca', vim.lsp.buf.code_action, bufopts)
  vim.keymap.set('n', 'gr', vim.lsp.buf.references, bufopts)
  vim.keymap.set('n', '<space>f', function() vim.lsp.buf.format { async = true } end, bufopts)
end

-- Configure `ruff-lsp`.
local configs = require 'lspconfig.configs'
if not configs.ruff_lsp then
  configs.ruff_lsp = {
    default_config = {
      cmd = { 'ruff-lsp' },
      filetypes = { 'python' },
      root_dir = require('lspconfig').util.find_git_ancestor,
      init_options = {
        settings = {
          args = {}
        }
      }
    }
  }
end
require('lspconfig').ruff_lsp.setup {
  on_attach = on_attach,
}

成功安装后,你应该会看到 Raff 的诊断直接显示在编辑器中:

Neovim中可用的代码操作

要与其他编辑器(包括Sublime Text和Helix)一起使用,请参阅ruff-lsp文档

ruff-lsp

语言服务器协议(非官方)

Ruff也可以作为python-lsp-serverpython-lsp-ruff插件使用,两者都可以从PyPI安装:

pip install python-lsp-server python-lsp-ruff

然后,LSP 服务器可以与支持语言服务器协议的任何编辑器一起使用。

例如,要与 Neovim 一起使用,请在你的 :

python-lsp-ruff
init.lua

require'lspconfig'.pylsp.setup {
  settings = {
    pylsp = {
      plugins = {
        ruff = {
          enabled = true
        },
        pycodestyle = {
          enabled = false
        },
        pyflakes = {
          enabled = false
        },
        mccabe = {
          enabled = false
        }
      }
    }
  },
}

Vim & Neovim

Ruff 可以通过 ruff-lsp 集成到任何支持语言服务器协议的编辑器中(参见:语言服务器协议),包括 Vim 和 Neovim。

建议你使用 ruff-lsp,这是官方支持的 Ruff LSP 服务器。

但是,Ruff 也可以作为 的 coc-pyright 扩展的一部分提供。

coc.nvim

使用(Neo)Vim的ALE插件。
let g:ale_linters = { "python": ["ruff"] }
let g:ale_fixers = {
\       "python": ["black", "ruff"],
\}
拉夫也可以通过EFM几条生产线上集成。
tools:
  python-ruff: &python-ruff
    lint-command: 'ruff --config ~/myconfigs/linters/ruff.toml --quiet ${INPUT}'
    lint-stdin: true
    lint-formats:
      - '%f:%l:%c: %m'
    format-command: 'ruff --stdin-filename ${INPUT} --config ~/myconfigs/linters/ruff.toml --fix --exit-zero --quiet -'
    format-stdin: true
对于使用 null-ls 的 neovim 用户,Ruff 已经集成了。
local null_ls = require("null-ls")
local methods = require("null-ls.methods")
local helpers = require("null-ls.helpers")

local function ruff_fix()
    return helpers.make_builtin({
        name = "ruff",
        meta = {
            url = "https://github.com/charliermarsh/ruff/",
            description = "An extremely fast Python linter, written in Rust.",
        },
        method = methods.internal.FORMATTING,
        filetypes = { "python" },
        generator_opts = {
            command = "ruff",
            args = { "--fix", "-e", "-n", "--stdin-filename", "$FILENAME", "-" },
            to_stdin = true
        },
        factory = helpers.formatter_factory
    })
end

null_ls.setup({
    sources = {
        ruff_fix(),
        null_ls.builtins.diagnostics.ruff,
    }
})

PyCharm (外部工具)

Ruff可以作为外部工具安装在PyCharm中。打开“首选项”窗格,然后导航到“工具”,然后导航到“外部工具”。从那里,添加具有以下配置的新工具:

将 Ruff 安装为外部工具

然后,Ruff 应显示为可运行的动作:

拉夫作为可运行的动作

PyCharm (非官方)

Ruff也可作为IntelliJ Marketplace(由@koxudaxi维护)上的Ruff插件使用。

GitHub 操作

GitHub Actions 拥有开箱即用运行 Ruff 所需的一切:

name: CI
on: push
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install Python
        uses: actions/setup-python@v4
        with:
          python-version: "3.11"
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install ruff
      # Include `--format=github` to enable automatic inline annotations.
      - name: Run Ruff
        run: ruff --format=github .

常见问题

拉夫与布莱克兼容吗?

是的。Ruff 与开箱即用的黑色兼容,只要两者之间的设置一致即可。

line-length

作为一个项目,Ruff被设计为与Black一起使用,因此,将推迟实现通过自动格式化来避免的样式lint规则。

拉夫与Flake8相比如何?

(来自Flake8?尝试 flake8 到 ruff 以自动转换你的现有配置。

当 (1) 没有或与少量插件一起使用时,Ruff 可以用作 Flake8 的直接替代品,(2) 与 Black 一起使用,以及 (3) 在 Python 3 代码上使用。

在这些条件下,Ruff 实现了 Flake8 中的所有规则。在实践中,这意味着 Ruff 实现了所有规则(源自 Pyflakes),以及 and 规则的子集(源自 pycodestyle)。

F
E
W

Ruff还在本地重新实现了一些最流行的Flake8插件和相关的代码质量工具,包括:

请注意,在某些情况下,Ruff 使用的规则代码和前缀与原始 Flake8 插件中的规则代码和前缀不同。例如,Ruff 用于表示 中的规则。这有助于最大限度地减少插件之间的冲突,并允许使用单个(例如)打开或关闭任何单个插件,而不是(以避免与规则冲突,例如)。

TID252
I252
flake8-tidy-imports
--select TID
--select I2
isort
I001

除了规则集之外,Ruff 还受到 Flake8 的以下限制:

  1. Ruff 尚不支持结构模式匹配。
  2. Flake8 有一个插件架构,支持编写自定义 lint 规则。(相反,流行的 Flake8 插件作为 Ruff 本身的一部分在 Rust 中重新实现。

Ruff和原始的Flake8插件之间还有其他一些小的不兼容性:

  • Ruff 没有实现 中的所有“固执己见”的 lint 规则。
    flake8-bugbear
  • 根据你的项目结构,Ruff 和对第一方代码的检测可能会有所不同。(这通常可以通过修改属性来解决,例如,如果你的代码嵌套在目录中,则修改为 。
    isort
    src
    src = ["src"]
    src

拉夫与皮林特相比如何?

在撰写本文时,Pylint 总共实现了 409 条规则,而 Ruff 实现了 224 条规则,其中至少有 60 条与 Pylint 规则集重叠。主观上,Pylint 倾向于基于类型推断实现更多规则(例如,验证函数调用中的参数数量)。

与 Flake8 一样,Pylint 支持插件(称为“检查器”),而 Ruff 则在本地实现所有规则。

与 Pylint 不同,Ruff 能够自动修复自己的 lint 违规行为。

#970 中跟踪 Pylint 奇偶校验。

拉夫与Mypy,Pyright或Pyre相比如何?

拉夫是短绒,而不是类型检查器。它可以检测到一些与类型检查器相同的问题,但类型检查器将捕获 Ruff 会遗漏的某些错误。反之亦然:Ruff 会捕获某些类型检查器通常会忽略的错误。

例如,与类型检查器不同,Ruff 会通过在源代码中查找对该导入的引用来通知你导入是否未使用;另一方面,类型检查器可以标记你将整数参数传递给需要字符串的函数,而 Ruff 会错过该字符串。这些工具是互补的。

建议将 Ruff 与类型检查器(如 Mypy、Pyright 或 Pyre)结合使用,Ruff 提供有关 lint 违规的更快反馈,类型检查器提供有关类型错误的更详细反馈。

拉夫取代了哪些工具?

今天,当与以下任何插件一起使用时,Ruff可以用来替换Flake8:

Ruff 还可以替换 isortyesqaeradicatepygrep-hooks (#980) 和 pyupgrade 中实现的规则子集 (#827)。

如果你想使用 Ruff,但依赖不受支持的 Flake8 插件,请随时提交问题。

我需要安装 Rust 才能使用 Ruff 吗?

不!Ruff在PyPI上可以作为ruff使用:

pip install ruff

Ruff 为所有主要平台提供轮子,这使得可以在完全依赖 Rust 的情况下安装 Ruff。

pip

我可以为 Ruff 编写自己的插件吗?

Ruff尚不支持第三方插件,尽管插件系统在项目范围内。参见 #283 了解更多信息。

Ruff的导入排序与isort相比如何?

Ruff的导入排序几乎等同于使用时。在 Ruff 和 isort 如何断开类似导入之间的联系,以及在某些情况下 Ruff 和 isort 如何处理内联注释方面,有一些已知的细微差异(参见:#1381#2104)。

isort
profile = "black"

像,Ruff的导入排序与Black兼容。

isort

Ruff还不支持所有的配置选项,尽管它确实支持其中的许多选项。你可以在 API 参考中找到支持的设置。例如,你可以像这样设置:

isort
known-first-party

[tool.ruff]
select = [
    # Pyflakes
    "F",
    # Pycodestyle
    "E",
    "W",
    # isort
    "I001"
]
src = ["src", "tests"]

[tool.ruff.isort]
known-first-party = ["my_module1", "my_module2"]

Ruff 是否支持 Jupyter Notebooks?

Ruff被集成到nbQA中,nbQA是一个用于在Jupyter Notebooks上运行linters和代码格式化程序的工具。

安装 和 后,你可以在笔记本上运行 Ruff,如下所示:

ruff
nbqa

> nbqa ruff Untitled.ipynb
Untitled.ipynb:cell_1:2:5: F841 Local variable `x` is assigned to but never used
Untitled.ipynb:cell_2:1:1: E402 Module level import not at top of file
Untitled.ipynb:cell_2:1:8: F401 `os` imported but unused
Found 3 errors.
1 potentially fixable with the --fix option.

Ruff 是否支持 NumPy 或 Google 风格的文档字符串?

是的!要启用特定的文档字符串约定,请将以下内容添加到你的 :

pyproject.toml

[tool.ruff.pydocstyle]
convention = "google"  # Accepts: "google", "numpy", or "pep257".

例如,如果你来自 ,并且你的原始配置使用 ,则改为在 中设置,如上所述。

flake8-docstrings
--docstring-convention=numpy
convention = "numpy"
pyproject.toml

除了 ,还需要显式启用规则代码前缀,如下所示:

convention
D

[tool.ruff]
select = [
    "D",
]

[tool.ruff.pydocstyle]
convention = "google"

设置强制禁用与该约定不兼容的任何规则,无论这些规则是如何提供的,从而避免意外不兼容并简化配置。

convention

如何知道 Ruff 正在使用哪些设置来检查我的代码?

运行以查看给定文件的已解析设置。

ruff /path/to/code.py --show-settings

我想使用 Ruff,但我不想使用 .这可能吗?
pyproject.toml

是的!你可以使用文件代替文件进行配置。这两个文件在功能上是等效的,并且具有相同的架构,但文件可以省略节标题。

pyproject.toml
ruff.toml
ruff.toml
[tool.ruff]

例如,给定这个:

pyproject.toml

[tool.ruff]
line-length = 88

[tool.ruff.pydocstyle]
convention = "google"

你可以改用这样的文件:

ruff.toml

line-length = 88

[pydocstyle]
convention = "google"

Ruff目前不支持INI文件,例如或.

setup.cfg
tox.ini

如何更改 Ruff 的默认配置?

当找不到配置文件时,Ruff 将查找特定于用户的文件或文件作为最后的手段。此行为类似于 Flake8 的 。

pyproject.toml
ruff.toml
~/.config/flake8

在 macOS 上,Ruff 希望该文件位于 .

/Users/Alice/Library/Application Support/ruff/ruff.toml

在 Linux 上,Ruff 希望该文件位于 .

/home/alice/.config/ruff/ruff.toml

在 Windows 上,Ruff 希望该文件位于 。

C:\Users\Alice\AppData\Roaming\ruff\ruff.toml

有关更多信息,请参阅目录板条箱。

拉夫想修复一些东西,但它破坏了我的代码。我该怎么办?

Ruff的自动修复是一种尽力而为的机制。鉴于 Python 的动态特性,在更改代码时很难完全确定,即使是看似微不足道的修复。

将来,Ruff 将支持基于补丁的安全性启用自动修复行为。

同时,如果你发现自动修复过于激进,则可以使用不可修复的机制按规则或按类别禁用它。例如,要禁用某些可能不安全的规则的自动修复,你可以向 :

pyproject.toml

[tool.ruff]
unfixable = ["B", "SIM", "TRY", "RUF"]

如果你发现 Ruff 的自动修复会破坏你的代码,请提交问题!

贡献

欢迎并非常感谢你的贡献。要开始使用,请查看贡献指南

释放

Ruff在PyPI上分发,并通过maturin发布。

看:。

.github/workflows/release.yaml

基准

首先,克隆CPython。这是一个庞大而多样化的Python代码库,这使其成为基准测试的良好目标。

git clone --branch 3.10 https://github.com/python/cpython.git resources/test/cpython

要对发布版本进行基准测试,请执行以下操作:

cargo build --release && hyperfine --ignore-failure --warmup 10 \
  "./target/release/ruff ./resources/test/cpython/ --no-cache" \
  "./target/release/ruff ./resources/test/cpython/"

Benchmark 1: ./target/release/ruff ./resources/test/cpython/ --no-cache
  Time (mean ± σ):     293.8 ms ±   3.2 ms    [User: 2384.6 ms, System: 90.3 ms]
  Range (min … max):   289.9 ms … 301.6 ms    10 runs

  Warning: Ignoring non-zero exit code.

Benchmark 2: ./target/release/ruff ./resources/test/cpython/
  Time (mean ± σ):      48.0 ms ±   3.1 ms    [User: 65.2 ms, System: 124.7 ms]
  Range (min … max):    45.0 ms …  66.7 ms    62 runs

  Warning: Ignoring non-zero exit code.

Summary
  './target/release/ruff ./resources/test/cpython/' ran
    6.12 ± 0.41 times faster than './target/release/ruff ./resources/test/cpython/ --no-cache'

以生态系统的现有工具为基准:

hyperfine --ignore-failure --warmup 5 \
  "./target/release/ruff ./resources/test/cpython/ --no-cache" \
  "pyflakes resources/test/cpython" \
  "autoflake --recursive --expand-star-imports --remove-all-unused-imports --remove-unused-variables --remove-duplicate-keys resources/test/cpython" \
  "pycodestyle resources/test/cpython" \
  "flake8 resources/test/cpython"

Benchmark 1: ./target/release/ruff ./resources/test/cpython/ --no-cache
  Time (mean ± σ):     294.3 ms ±   3.3 ms    [User: 2467.5 ms, System: 89.6 ms]
  Range (min … max):   291.1 ms … 302.8 ms    10 runs

  Warning: Ignoring non-zero exit code.

Benchmark 2: pyflakes resources/test/cpython
  Time (mean ± σ):     15.786 s ±  0.143 s    [User: 15.560 s, System: 0.214 s]
  Range (min … max):   15.640 s … 16.157 s    10 runs

  Warning: Ignoring non-zero exit code.

Benchmark 3: autoflake --recursive --expand-star-imports --remove-all-unused-imports --remove-unused-variables --remove-duplicate-keys resources/test/cpython
  Time (mean ± σ):      6.175 s ±  0.169 s    [User: 54.102 s, System: 1.057 s]
  Range (min … max):    5.950 s …  6.391 s    10 runs

Benchmark 4: pycodestyle resources/test/cpython
  Time (mean ± σ):     46.921 s ±  0.508 s    [User: 46.699 s, System: 0.202 s]
  Range (min … max):   46.171 s … 47.863 s    10 runs

  Warning: Ignoring non-zero exit code.

Benchmark 5: flake8 resources/test/cpython
  Time (mean ± σ):     12.260 s ±  0.321 s    [User: 102.934 s, System: 1.230 s]
  Range (min … max):   11.848 s … 12.933 s    10 runs

  Warning: Ignoring non-zero exit code.

Summary
  './target/release/ruff ./resources/test/cpython/ --no-cache' ran
   20.98 ± 0.62 times faster than 'autoflake --recursive --expand-star-imports --remove-all-unused-imports --remove-unused-variables --remove-duplicate-keys resources/test/cpython'
   41.66 ± 1.18 times faster than 'flake8 resources/test/cpython'
   53.64 ± 0.77 times faster than 'pyflakes resources/test/cpython'
  159.43 ± 2.48 times faster than 'pycodestyle resources/test/cpython'

你可以运行 from 为上述内容创建工作环境。所有报告的基准测试都是使用 Python 3.11 上指定的版本计算的。

poetry install
./scripts
./scripts/pyproject.toml

要对 Pylint 进行基准测试,请从 CPython 存储库中删除以下文件:

rm Lib/test/bad_coding.py \
  Lib/test/bad_coding2.py \
  Lib/test/bad_getattr.py \
  Lib/test/bad_getattr2.py \
  Lib/test/bad_getattr3.py \
  Lib/test/badcert.pem \
  Lib/test/badkey.pem \
  Lib/test/badsyntax_3131.py \
  Lib/test/badsyntax_future10.py \
  Lib/test/badsyntax_future3.py \
  Lib/test/badsyntax_future4.py \
  Lib/test/badsyntax_future5.py \
  Lib/test/badsyntax_future6.py \
  Lib/test/badsyntax_future7.py \
  Lib/test/badsyntax_future8.py \
  Lib/test/badsyntax_future9.py \
  Lib/test/badsyntax_pep3120.py \
  Lib/test/test_asyncio/test_runners.py \
  Lib/test/test_copy.py \
  Lib/test/test_inspect.py \
  Lib/test/test_typing.py

然后,从 运行:。这将以最大的并行度执行 Pylint,并且只报告错误。

resources/test/cpython
time pylint -j 0 -E $(git ls-files '*.py')

要对 Pyupgrade 进行基准测试,请从以下位置运行以下命令:

resources/test/cpython

hyperfine --ignore-failure --warmup 5 --prepare "git reset --hard HEAD" \
  "find . -type f -name \"*.py\" | xargs -P 0 pyupgrade --py311-plus"

Benchmark 1: find . -type f -name "*.py" | xargs -P 0 pyupgrade --py311-plus
  Time (mean ± σ):     30.119 s ±  0.195 s    [User: 28.638 s, System: 0.390 s]
  Range (min … max):   29.813 s … 30.356 s    10 runs

参考

顶级

allowed-confusables

在强制执行 、 和 时允许忽略的“可混淆”Unicode 字符的列表。

RUF001
RUF002
RUF003

默认值

[]

类型

Vec<char>

用法示例

[tool.ruff]
# Allow minus-sign (U+2212), greek-small-letter-rho (U+03C1), and the asterisk-operator (U+2217),
# which could be confused for "-", "p", and "*", respectively.
allowed-confusables = ["", "ρ", ""]

builtins

除系统内置项外,要视为已定义引用的内置项列表。

默认值

[]

类型

Vec<String>

用法示例

[tool.ruff]
builtins = ["_"]

cache-dir

缓存目录的路径。

默认情况下,Ruff 将缓存结果存储在当前项目根目录的目录中。

.ruff_cache

但是,Ruff 也将遵循环境变量,该变量优先于该默认值。

RUFF_CACHE_DIR

此设置甚至会覆盖环境变量(如果已设置)。

RUFF_CACHE_DIR

默认值

.ruff_cache

类型

PathBuf

用法示例

[tool.ruff]
cache-dir = "~/.cache/ruff"

dummy-variable-rgx

用于标识“虚拟”变量或在执行时应忽略的变量(例如)未使用的变量规则的正则表达式。默认表达式匹配 、 和 ,但不匹配。

_
__
_var
_var_

默认值

"^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

类型

Regex

用法示例

[tool.ruff]
# Only ignore variables named "_".
dummy-variable-rgx = "^_$"

exclude

要从 linting 中排除的文件模式列表。

排除项基于全局,可以是:

  • 单路径模式,如(排除树中命名的任何目录)、(排除任何名为的文件)或(排除任何文件匹配)。
    .mypy_cache
    .mypy_cache
    foo.py
    foo.py
    foo_*.py
    foo_*.py
  • 相对模式,例如(排除该特定文件)或(排除 中的任何 Python 文件)。请注意,这些路径是相对于项目根目录(例如,包含 .
    directory/foo.py
    directory/*.py
    directory
    pyproject.toml

有关 glob 语法的更多信息,请参阅 globset 文档

请注意,通常需要使用扩展排除来修改排除的路径。

默认值

[".bzr", ".direnv", ".eggs", ".git", ".hg", ".mypy_cache", ".nox", ".pants.d", ".ruff_cache", ".svn", ".tox", ".venv", "__pypackages__", "_build", "buck-out", "build", "dist", "node_modules", "venv"]

类型

Vec<FilePattern>

用法示例

[tool.ruff]
exclude = [".venv"]

extend

要合并到此配置中的本地文件的路径。将扩展用户主目录和环境变量。

pyproject.toml

要解析当前文件,Ruff 将首先解析此基本配置文件,然后合并当前配置文件中定义的任何属性。

pyproject.toml

默认值

None

类型

Path

用法示例

[tool.ruff]
# Extend the `pyproject.toml` file in the parent directory.
extend = "../pyproject.toml"
# But use a different line length.
line-length = 100

extend-exclude

除 指定的文件模式外,要从 linting 中省略的文件模式列表。

exclude

排除项基于全局,可以是:

  • 单路径模式,如(排除树中命名的任何目录)、(排除任何名为的文件)或(排除任何文件匹配)。
    .mypy_cache
    .mypy_cache
    foo.py
    foo.py
    foo_*.py
    foo_*.py
  • 相对模式,例如(排除该特定文件)或(排除 中的任何 Python 文件)。请注意,这些路径是相对于项目根目录(例如,包含 .
    directory/foo.py
    directory/*.py
    directory
    pyproject.toml

有关 glob 语法的更多信息,请参阅 globset 文档

默认值

[]

类型

Vec<FilePattern>

用法示例

[tool.ruff]
# In addition to the standard set of exclusions, omit all tests, plus a specific file.
extend-exclude = ["tests", "src/bad.py"]

extend-ignore

要忽略的规则代码或前缀的列表,以及 指定的规则代码或前缀。

ignore

请注意,在解析 / 中的规则后应用,并且 中不太具体的规则将覆盖 中更具体的规则。建议仅在通过 扩展文件时使用。

extend-ignore
ignore
select
extend-ignore
select
extend-ignore
pyproject.toml
extend

默认值

[]

类型

Vec<RuleSelector>

用法示例

[tool.ruff]
# Skip unused variable rules (`F841`).
extend-ignore = ["F841"]

extend-select

要启用的规则代码或前缀的列表,以及 指定的规则代码或前缀。

select

请注意,在解析 / 中的规则后应用,并且 中不太具体的规则将覆盖 中更具体的规则。建议仅在通过 扩展文件时使用。

extend-select
ignore
select
extend-select
ignore
extend-select
pyproject.toml
extend

默认值

[]

类型

Vec<RuleSelector>

用法示例

[tool.ruff]
# On top of the default `select` (`E`, `F`), enable flake8-bugbear (`B`) and flake8-quotes (`Q`).
extend-select = ["B", "Q"]

external

Ruff不支持的规则代码列表,但在(例如)验证指令时应保留。对于保留涵盖 Ruff 尚未实现的插件的指令很有用。

# noqa
# noqa

默认值

[]

类型

Vec<String>

用法示例

[tool.ruff]
# Avoiding flagging (and removing) `V101` from any `# noqa`
# directives, despite Ruff's lack of support for `vulture`.
external = ["V101"]

fix

运行时默认启用自动修复行为(由 和 命令行标志覆盖)。

ruff
--fix
--no-fix

默认值

false

类型

bool

用法示例

[tool.ruff]
fix = true

fix-only

喜欢,但禁用报告剩余违规。意味 着。

fix
fix

默认值

false

类型

bool

用法示例

[tool.ruff]
fix-only = true

fixable

要视为可自动修复的规则代码或前缀的列表。默认情况下,所有规则都被视为可自动修复。

默认值

["A", "ANN", "ARG", "B", "BLE", "C", "COM", "D", "DTZ", "E", "EM", "ERA", "EXE", "F", "FBT", "G", "I", "ICN", "INP", "ISC", "N", "PD", "PGH", "PIE", "PL", "PT", "PTH", "Q", "RET", "RUF", "S", "SIM", "T", "TCH", "TID", "TRY", "UP", "W", "YTT"]

类型

Vec<RuleSelector>

用法示例

[tool.ruff]
# Only allow autofix behavior for `E` and `F` rules.
fixable = ["E", "F"]

force-exclude

是否强制执行和模式化,即使对于显式传递给 Ruff 的路径也是如此。通常,Ruff 会检查直接传入的任何路径,即使它们通常会被排除。设置将使 Ruff 明确尊重这些排除项。

exclude
extend-exclude
force-exclude = true

这对于预提交很有用,它会将所有更改的文件显式传递给 ruff-pre-commit 插件,无论它们是否被 Ruff 自己的设置标记为排除。

默认值

false

类型

bool

用法示例

[tool.ruff]
force-exclude = true

format

违规消息的格式应采用:(默认)、(按文件对消息进行分组)、(机器可读)、(机器可读 XML)、(GitHub 操作注释)、(GitLab CI 代码质量报告)或(Pylint 文本格式)。

"text"
"grouped"
"json"
"junit"
"github"
"gitlab"
"pylint"

默认值

"text"

类型

SerializationType

用法示例

[tool.ruff]
# Group violations by containing file.
format = "grouped"

ignore

要忽略的规则代码或前缀的列表。前缀可以指定确切的规则(如)、整个类别(如)或介于两者之间的任何内容。

F841
F

断开启用和禁用规则之间的连接(分别为 via 和 )时,更具体的前缀会覆盖不太具体的前缀。

select
ignore

默认值

[]

类型

Vec<RuleSelector>

用法示例

[tool.ruff]
# Skip unused variable rules (`F841`).
ignore = ["F841"]

ignore-init-module-imports

避免自动删除文件中未使用的导入。此类导入仍将被标记,但会显示一条专用消息,建议导入要么添加到模块的符号中,要么使用冗余别名重新导出(例如,)。

__init__.py
__all__
import os as os

默认值

false

类型

bool

用法示例

[tool.ruff]
ignore-init-module-imports = true

line-length

强制执行长线违规时使用的行长(如 )。

E501

默认值

88

类型

usize

用法示例

[tool.ruff]
# Allow lines to be as long as 120 characters.
line-length = 120

namespace-packages

将指定的目录标记为命名空间包。出于模块解析的目的,Ruff 会将这些目录视为包含文件。

__init__.py

默认值

[]

类型

Vec<PathBuf>

用法示例

[tool.ruff]
namespace-packages = ["airflow/providers"]

per-file-ignores

考虑任何匹配文件时,从文件模式到要排除的规则代码或前缀的映射列表。

默认值

{}

类型

HashMap<String, Vec<RuleSelector>>

用法示例

[tool.ruff]
# Ignore `E402` (import violations) in all `__init__.py` files, and in `path/to/file.py`.
[tool.ruff.per-file-ignores]
"__init__.py" = ["E402"]
"path/to/file.py" = ["E402"]

required-version

需要运行特定版本的 Ruff(对于统一许多环境中的结果很有用,例如,使用文件)。

pyproject.toml

默认值

None

类型

String

用法示例

[tool.ruff]
required-version = "0.0.193"

respect-gitignore

是否自动排除被 、 和全局文件忽略的文件。默认启用。

.ignore
.gitignore
.git/info/exclude
gitignore

默认值

true

类型

bool

用法示例

[tool.ruff]
respect-gitignore = false

select

要启用的规则代码或前缀的列表。前缀可以指定确切的规则(如)、整个类别(如)或介于两者之间的任何内容。

F841
F

断开启用和禁用规则之间的连接(分别为 via 和 )时,更具体的前缀会覆盖不太具体的前缀。

select
ignore

默认值

["E", "F"]

类型

Vec<RuleSelector>

用法示例

[tool.ruff]
# On top of the defaults (`E`, `F`), enable flake8-bugbear (`B`) and flake8-quotes (`Q`).
select = ["E", "F", "B", "Q"]

show-source

是否在报告 lint 冲突时显示源代码片段(由命令行标志覆盖)。

--show-source

默认值

false

类型

bool

用法示例

[tool.ruff]
# By default, always show source code snippets.
show-source = true

src

要考虑的源代码路径,例如,在解析第一方导入与第三方导入时。

举个例子:给定一个 Python 包结构,如下所示:

my_package/
  pyproject.toml
  src/
    my_package/
      __init__.py
      foo.py
      bar.py

The

src
directory should be included in the
src
option (e.g.,
src = ["src"]
), such that when resolving imports,
my_package.foo
is considered a first-party import.

This field supports globs. For example, if you have a series of Python packages in a

python_modules
directory,
src = ["python_modules/*"]
would expand to incorporate all of the packages in that directory. User home directory and environment variables will also be expanded.

Default value:

["."]

Type:

Vec<PathBuf>

Example usage:

[tool.ruff]
# Allow imports relative to the "src" and "test" directories.
src = ["src", "test"]

target-version

The Python version to target, e.g., when considering automatic code upgrades, like rewriting type annotations. Note that the target version will not be inferred from the current Python version, and instead must be specified explicitly (as seen below).

Default value:

"py310"

Type:

PythonVersion

Example usage:

[tool.ruff]
# Always generate Python 3.7-compatible code.
target-version = "py37"

task-tags

A list of task tags to recognize (e.g., "TODO", "FIXME", "XXX").

Comments starting with these tags will be ignored by commented-out code detection (

ERA
), and skipped by line-length rules (
E501
) if
ignore-overlong-task-comments
is set to
true
.

Default value:

["TODO", "FIXME", "XXX"]

Type:

Vec<String>

Example usage:

[tool.ruff]
task-tags = ["HACK"]

typing-modules

A list of modules whose imports should be treated equivalently to members of the

typing
module.

This is useful for ensuring proper type annotation inference for projects that re-export

typing
and
typing_extensions
members from a compatibility module. If omitted, any members imported from modules apart from
typing
and
typing_extensions
will be treated as ordinary Python objects.

Default value:

[]

Type:

Vec<String>

Example usage:

[tool.ruff]
typing-modules = ["airflow.typing_compat"]

unfixable

A list of rule codes or prefixes to consider non-autofix-able.

Default value:

[]

Type:

Vec<RuleSelector>

Example usage:

[tool.ruff]
# Disable autofix for unused imports (`F401`).
unfixable = ["F401"]

update-check

Enable or disable automatic update checks (overridden by the

--update-check
and
--no-update-check
command-line flags).

Default value:

false

Type:

bool

Example usage:

[tool.ruff]
update-check = true

flake8-annotations

allow-star-arg-any

Whether to suppress

ANN401
for dynamically typed
*args
and
**kwargs
arguments.

Default value:

false

Type:

bool

Example usage:

[tool.ruff.flake8-annotations]
allow-star-arg-any = true

mypy-init-return

Whether to allow the omission of a return type hint for

__init__
if at least one argument is annotated.

Default value:

false

Type:

bool

Example usage:

[tool.ruff.flake8-annotations]
mypy-init-return = true

suppress-dummy-args

Whether to suppress

ANN000
-level violations for arguments matching the "dummy" variable regex (like
_
).

Default value:

false

Type:

bool

Example usage:

[tool.ruff.flake8-annotations]
suppress-dummy-args = true

suppress-none-returning

Whether to suppress

ANN200
-level violations for functions that meet either of the following criteria:

  • Contain no
    return
    statement.
  • Explicit
    return
    statement(s) all return
    None
    (explicitly or implicitly).

Default value:

false

Type:

bool

Example usage:

[tool.ruff.flake8-annotations]
suppress-none-returning = true

flake8-bandit

check-typed-exception

Whether to disallow

try
-
except
-
pass
(
S110
) for specific exception types. By default,
try
-
except
-
pass
is only disallowed for
Exception
and
BaseException
.

Default value:

false

Type:

bool

Example usage:

[tool.ruff.flake8-bandit]
check-typed-exception = true

hardcoded-tmp-directory

A list of directories to consider temporary.

Default value:

["/tmp", "/var/tmp", "/dev/shm"]

Type:

Vec<String>

Example usage:

[tool.ruff.flake8-bandit]
hardcoded-tmp-directory = ["/foo/bar"]

hardcoded-tmp-directory-extend

A list of directories to consider temporary, in addition to those specified by

hardcoded-tmp-directory
.

Default value:

[]

Type:

Vec<String>

Example usage:

[tool.ruff.flake8-bandit]
extend-hardcoded-tmp-directory = ["/foo/bar"]

flake8-bugbear

extend-immutable-calls

Additional callable functions to consider "immutable" when evaluating, e.g., the

no-mutable-default-argument
rule (
B006
).

Default value:

[]

Type:

Vec<String>

Example usage:

[tool.ruff.flake8-bugbear]
# Allow default arguments like, e.g., `data: List[str] = fastapi.Query(None)`.
extend-immutable-calls = ["fastapi.Depends", "fastapi.Query"]

flake8-builtins

builtins-ignorelist

Ignore list of builtins.

Default value:

[]

Type:

Vec<String>

Example usage:

[tool.ruff.flake8-builtins]
builtins-ignorelist = ["id"]

flake8-errmsg

max-string-length

Maximum string length for string literals in exception messages.

Default value:

0

Type:

usize

Example usage:

[tool.ruff.flake8-errmsg]
max-string-length = 20

flake8-implicit-str-concat

allow-multiline

Whether to allow implicit string concatenations for multiline strings. By default, implicit concatenations of multiline strings are allowed (but continuation lines, delimited with a backslash, are prohibited).

Default value:

true

Type:

bool

Example usage:

[tool.ruff.flake8-implicit-str-concat]
allow-multiline = false

flake8-import-conventions

aliases

The conventional aliases for imports. These aliases can be extended by the

extend_aliases
option.

Default value:

{"altair": "alt", "matplotlib.pyplot": "plt", "numpy": "np", "pandas": "pd", "seaborn": "sns"}

Type:

FxHashMap<String, String>

Example usage:

[tool.ruff.flake8-import-conventions]
[tool.ruff.flake8-import-conventions.aliases]
# Declare the default aliases.
altair = "alt"
"matplotlib.pyplot" = "plt"
numpy = "np"
pandas = "pd"
seaborn = "sns"

extend-aliases

A mapping of modules to their conventional import aliases. These aliases will be added to the

aliases
mapping.

Default value:

{}

Type:

FxHashMap<String, String>

Example usage:

[tool.ruff.flake8-import-conventions]
[tool.ruff.flake8-import-conventions.extend-aliases]
# Declare a custom alias for the `matplotlib` module.
"dask.dataframe" = "dd"

flake8-pytest-style

fixture-parentheses

Boolean flag specifying whether

@pytest.fixture()
without parameters should have parentheses. If the option is set to
true
(the default),
@pytest.fixture()
is valid and
@pytest.fixture
is invalid. If set to
false
,
@pytest.fixture
is valid and
@pytest.fixture()
is invalid.

Default value:

true

Type:

bool

Example usage:

[tool.ruff.flake8-pytest-style]
fixture-parentheses = true

mark-parentheses

Boolean flag specifying whether

@pytest.mark.foo()
without parameters should have parentheses. If the option is set to
true
(the default),
@pytest.mark.foo()
is valid and
@pytest.mark.foo
is invalid. If set to
false
,
@pytest.fixture
is valid and
@pytest.mark.foo()
is invalid.

Default value:

true

Type:

bool

Example usage:

[tool.ruff.flake8-pytest-style]
mark-parentheses = true

parametrize-names-type

Expected type for multiple argument names in

@pytest.mark.parametrize
. The following values are supported:

  • csv
    — a comma-separated list, e.g.
    @pytest.mark.parametrize('name1,name2', ...)
  • tuple
    (default) — e.g.
    @pytest.mark.parametrize(('name1', 'name2'), ...)
  • list
    — e.g.
    @pytest.mark.parametrize(['name1', 'name2'], ...)

Default value:

tuple

Type:

ParametrizeNameType

Example usage:

[tool.ruff.flake8-pytest-style]
parametrize-names-type = "list"

parametrize-values-row-type

Expected type for each row of values in

@pytest.mark.parametrize
in case of multiple parameters. The following values are supported:

  • tuple
    (default) — e.g.
    @pytest.mark.parametrize(('name1', 'name2'), [(1, 2), (3, 4)])
  • list
    — e.g.
    @pytest.mark.parametrize(('name1', 'name2'), [[1, 2], [3, 4]])

Default value:

tuple

Type:

ParametrizeValuesRowType

Example usage:

[tool.ruff.flake8-pytest-style]
parametrize-values-row-type = "list"

parametrize-values-type

Expected type for the list of values rows in

@pytest.mark.parametrize
. The following values are supported:

  • tuple
    — e.g.
    @pytest.mark.parametrize('name', (1, 2, 3))
  • list
    (default) — e.g.
    @pytest.mark.parametrize('name', [1, 2, 3])

Default value:

list

Type:

ParametrizeValuesType

Example usage:

[tool.ruff.flake8-pytest-style]
parametrize-values-type = "tuple"

raises-extend-require-match-for

List of additional exception names that require a match= parameter in a

pytest.raises()
call. This extends the default list of exceptions that require a match= parameter. This option is useful if you want to extend the default list of exceptions that require a match= parameter without having to specify the entire list. Note that this option does not remove any exceptions from the default list.

Default value:

[]

Type:

Vec<String>

Example usage:

[tool.ruff.flake8-pytest-style]
raises-extend-require-match-for = ["requests.RequestException"]

raises-require-match-for

List of exception names that require a match= parameter in a

pytest.raises()
call.

Default value:

["BaseException", "Exception", "ValueError", "OSError", "IOError", "EnvironmentError", "socket.error"]

Type:

Vec<String>

Example usage:

[tool.ruff.flake8-pytest-style]
raises-require-match-for = ["requests.RequestException"]

flake8-quotes

avoid-escape

Whether to avoid using single quotes if a string contains single quotes, or vice-versa with double quotes, as per PEP8. This minimizes the need to escape quotation marks within strings.

Default value:

true

Type:

bool

Example usage:

[tool.ruff.flake8-quotes]
# Don't bother trying to avoid escapes.
avoid-escape = false

docstring-quotes

Quote style to prefer for docstrings (either "single" (

'
) or "double" (
"
)).

Default value:

"double"

Type:

Quote

Example usage:

[tool.ruff.flake8-quotes]
docstring-quotes = "single"

inline-quotes

Quote style to prefer for inline strings (either "single" (

'
) or "double" (
"
)).

Default value:

"double"

Type:

Quote

Example usage:

[tool.ruff.flake8-quotes]
inline-quotes = "single"

multiline-quotes

Quote style to prefer for multiline strings (either "single" (

'
) or "double" (
"
)).

Default value:

"double"

Type:

Quote

Example usage:

[tool.ruff.flake8-quotes]
multiline-quotes = "single"

flake8-tidy-imports

ban-relative-imports

Whether to ban all relative imports (

"all"
), or only those imports that extend into the parent module or beyond (
"parents"
).

Default value:

"parents"

Type:

Strictness

Example usage:

[tool.ruff.flake8-tidy-imports]
# Disallow all relative imports.
ban-relative-imports = "all"

banned-api

Specific modules or module members that may not be imported or accessed. Note that this rule is only meant to flag accidental uses, and can be circumvented via

eval
or
importlib
.

Default value:

{}

Type:

HashMap<String, BannedApi>

Example usage:

[tool.ruff.flake8-tidy-imports]
[tool.ruff.flake8-tidy-imports.banned-api]
"cgi".msg = "The cgi module is deprecated, see https://peps.python.org/pep-0594/#cgi."
"typing.TypedDict".msg = "Use typing_extensions.TypedDict instead."

flake8-type-checking

exempt-modules

Exempt certain modules from needing to be moved into type-checking blocks.

Default value:

["typing"]

Type:

Vec<String>

Example usage:

[tool.ruff.flake8-type-checking]
exempt-modules = ["typing", "typing_extensions"]

strict

Enforce TC001, TC002, and TC003 rules even when valid runtime imports are present for the same module. See: https://github.com/snok/flake8-type-checking#strict.

Default value:

false

Type:

bool

Example usage:

[tool.ruff.flake8-type-checking]
strict = true

flake8-unused-arguments

ignore-variadic-names

Whether to allow unused variadic arguments, like

*args
and
**kwargs
.

Default value:

false

Type:

bool

Example usage:

[tool.ruff.flake8-unused-arguments]
ignore-variadic-names = true

isort

classes

An override list of tokens to always recognize as a Class for

order-by-type
regardless of casing.

Default value:

[]

Type:

Vec<String>

Example usage:

[tool.ruff.isort]
classes = ["SVC"]

combine-as-imports

Combines as imports on the same line. See isort's

combine-as-imports
option.

Default value:

false

Type:

bool

Example usage:

[tool.ruff.isort]
combine-as-imports = true

constants

An override list of tokens to always recognize as a CONSTANT for

order-by-type
regardless of casing.

Default value:

[]

Type:

Vec<String>

Example usage:

[tool.ruff.isort]
constants = ["constant"]

extra-standard-library

A list of modules to consider standard-library, in addition to those known to Ruff in advance.

Default value:

[]

Type:

Vec<String>

Example usage:

[tool.ruff.isort]
extra-standard-library = ["path"]

force-single-line

Forces all from imports to appear on their own line.

Default value:

false

Type:

bool

Example usage:

[tool.ruff.isort]
force-single-line = true

force-sort-within-sections

Don't sort straight-style imports (like

import sys
) before from-style imports (like
from itertools import groupby
). Instead, sort the imports by module, independent of import style.

Default value:

false

Type:

bool

Example usage:

[tool.ruff.isort]
force-sort-within-sections = true

force-wrap-aliases

Force

import from
statements with multiple members and at least one alias (e.g.,
import A as B
) to wrap such that every line contains exactly one member. For example, this formatting would be retained, rather than condensing to a single line:

from .utils import (
    test_directory as test_directory,
    test_id as test_id
)

Note that this setting is only effective when combined with

combine-as-imports = true
. When
combine-as-imports
isn't enabled, every aliased
import from
will be given its own line, in which case, wrapping is not necessary.

Default value:

false

Type:

bool

Example usage:

[tool.ruff.isort]
force-wrap-aliases = true
combine-as-imports = true

known-first-party

A list of modules to consider first-party, regardless of whether they can be identified as such via introspection of the local filesystem.

Default value:

[]

Type:

Vec<String>

Example usage:

[tool.ruff.isort]
known-first-party = ["src"]

known-third-party

A list of modules to consider third-party, regardless of whether they can be identified as such via introspection of the local filesystem.

Default value:

[]

Type:

Vec<String>

Example usage:

[tool.ruff.isort]
known-third-party = ["src"]

no-lines-before

A list of sections that should not be delineated from the previous section via empty lines.

Default value:

[]

Type:

Option<Vec<ImportType>>

Example usage:

[tool.ruff.isort]
no-lines-before = ["future", "standard-library"]

order-by-type

Order imports by type, which is determined by case, in addition to alphabetically.

Default value:

true

Type:

bool

Example usage:

[tool.ruff.isort]
order-by-type = true

relative-imports-order

Whether to place "closer" imports (fewer

.
characters, most local) before "further" imports (more
.
characters, least local), or vice versa.

The default ("furthest-to-closest") is equivalent to isort's

reverse-relative
default (
reverse-relative = false
); setting this to "closest-to-furthest" is equivalent to isort's
reverse-relative = true
.

Default value:

furthest-to-closest

Type:

RelatveImportsOrder

Example usage:

[tool.ruff.isort]
relative-imports-order = "closest-to-furthest"

required-imports

Add the specified import line to all files.

Default value:

[]

Type:

Vec<String>

Example usage:

[tool.ruff.isort]
required-imports = ["from __future__ import annotations"]

single-line-exclusions

One or more modules to exclude from the single line rule.

Default value:

[]

Type:

Vec<String>

Example usage:

[tool.ruff.isort]
single-line-exclusions = ["os", "json"]

split-on-trailing-comma

If a comma is placed after the last member in a multi-line import, then the imports will never be folded into one line.

See isort's

split-on-trailing-comma
option.

Default value:

true

Type:

bool

Example usage:

[tool.ruff.isort]
split-on-trailing-comma = false

variables

An override list of tokens to always recognize as a var for

order-by-type
regardless of casing.

Default value:

[]

Type:

Vec<String>

Example usage:

[tool.ruff.isort]
variables = ["VAR"]

mccabe

max-complexity

The maximum McCabe complexity to allow before triggering

C901
errors.

Default value:

10

Type:

usize

Example usage:

[tool.ruff.mccabe]
# Flag errors (`C901`) whenever the complexity level exceeds 5.
max-complexity = 5

pep8-naming

classmethod-decorators

A list of decorators that, when applied to a method, indicate that the method should be treated as a class method. For example, Ruff will expect that any method decorated by a decorator in this list takes a

cls
argument as its first argument.

Default value:

["classmethod"]

Type:

Vec<String>

Example usage:

[tool.ruff.pep8-naming]
# Allow Pydantic's `@validator` decorator to trigger class method treatment.
classmethod-decorators = ["classmethod", "pydantic.validator"]

ignore-names

A list of names to ignore when considering

pep8-naming
violations.

Default value:

["setUp", "tearDown", "setUpClass", "tearDownClass", "setUpModule", "tearDownModule", "asyncSetUp", "asyncTearDown", "setUpTestData", "failureException", "longMessage", "maxDiff"]

Type:

Vec<String>

Example usage:

[tool.ruff.pep8-naming]
ignore-names = ["callMethod"]

staticmethod-decorators

A list of decorators that, when applied to a method, indicate that the method should be treated as a static method. For example, Ruff will expect that any method decorated by a decorator in this list has no

self
or
cls
argument.

Default value:

["staticmethod"]

Type:

Vec<String>

Example usage:

[tool.ruff.pep8-naming]
# Allow a shorthand alias, `@stcmthd`, to trigger static method treatment.
staticmethod-decorators = ["staticmethod", "stcmthd"]

pycodestyle

ignore-overlong-task-comments

Whether or not line-length violations (

E501
) should be triggered for comments starting with
task-tags
(by default: ["TODO", "FIXME", and "XXX"]).

Default value:

false

Type:

bool

Example usage:

[tool.ruff.pycodestyle]
ignore-overlong-task-comments = true

max-doc-length

The maximum line length to allow for line-length violations within documentation (

W505
), including standalone comments.

Default value:

None

Type:

usize

Example usage:

[tool.ruff.pycodestyle]
max-doc-length = 88

pydocstyle

convention

Whether to use Google-style or NumPy-style conventions or the PEP257 defaults when analyzing docstring sections.

Default value:

None

Type:

Convention

Example usage:

[tool.ruff.pydocstyle]
# Use Google-style docstrings.
convention = "google"

pylint

allow-magic-value-types

Constant types to ignore when used as "magic values".

Default value:

["str"]

Type:

Vec<ConstantType>

Example usage:

[tool.ruff.pylint]
allow-magic-value-types = ["int"]

pyupgrade

keep-runtime-typing

Whether to avoid PEP 585 (

List[int]
->
list[int]
) and PEP 604 (
Optional[str]
->
str | None
) rewrites even if a file imports
from __future__ import annotations
. Note that this setting is only applicable when the target Python version is below 3.9 and 3.10 respectively.

Default value:

false

Type:

bool

Example usage:

[tool.ruff.pyupgrade]
# Preserve types, even if a file imports `from __future__ import annotations`.
keep-runtime-typing = true

License

MIT