教程
本教程将引导您完成将 Ruff 的 linter 和 formatter 集成到您的项目中的过程。有关更详细的概述,请参阅配置 Ruff。
入门
首先,我们将使用 uv 初始化一个项目
此命令创建一个具有以下结构的 Python 项目
然后,我们将清除 src/numbers/__init__.py
中自动生成的内容,并使用以下代码创建 src/numbers/calculate.py
from typing import Iterable
import os
def sum_even_numbers(numbers: Iterable[int]) -> int:
"""Given an iterable of integers, return the sum of all even numbers in the iterable."""
return sum(
num for num in numbers
if num % 2 == 0
)
接下来,我们将 Ruff 添加到我们的项目中
然后,我们可以通过 uv run ruff check
在我们的项目上运行 Ruff linter
$ uv run ruff check
src/numbers/calculate.py:3:8: F401 [*] `os` imported but unused
Found 1 error.
[*] 1 fixable with the `--fix` option.
注意
作为 uv run
的替代方法,您还可以通过激活项目的虚拟环境(Linux 和 macOS 上为 source .venv/bin/active
,Windows 上为 .venv\Scripts\activate
)并直接运行 ruff check
来运行 Ruff。
Ruff 识别出一个未使用的导入,这是 Python 代码中的常见错误。Ruff 认为这是一个“可修复”的错误,因此我们可以通过运行 ruff check --fix
自动解决该问题
运行 git diff
显示以下内容
--- a/src/numbers/calculate.py
+++ b/src/numbers/calculate.py
@@ -1,7 +1,5 @@
from typing import Iterable
-import os
-
def sum_even_numbers(numbers: Iterable[int]) -> int:
"""Given an iterable of integers, return the sum of all even numbers in the iterable."""
return sum(
num for num in numbers
if num % 2 == 0
)
请注意,Ruff 默认在当前目录中运行,但是您可以传递特定路径来检查
现在我们的项目通过了 ruff check
,我们可以通过 ruff format
运行 Ruff 格式化程序
运行 git diff
表明 sum
调用被重新格式化以适应默认的 88 个字符的行长度限制
--- a/src/numbers/calculate.py
+++ b/src/numbers/calculate.py
@@ -3,7 +3,4 @@ from typing import Iterable
def sum_even_numbers(numbers: Iterable[int]) -> int:
"""Given an iterable of integers, return the sum of all even numbers in the iterable."""
- return sum(
- num for num in numbers
- if num % 2 == 0
- )
+ return sum(num for num in numbers if num % 2 == 0)
到目前为止,我们一直在使用 Ruff 的默认配置。让我们看看如何自定义 Ruff 的行为。
配置
为了确定每个 Python 文件的适当设置,Ruff 会查找文件目录或任何父目录中的第一个 pyproject.toml
、ruff.toml
或 .ruff.toml
文件。
要配置 Ruff,我们将以下内容添加到项目根目录中的配置文件中
[tool.ruff]
# Set the maximum line length to 79.
line-length = 79
[tool.ruff.lint]
# Add the `line-too-long` rule to the enforced rule set. By default, Ruff omits rules that
# overlap with the use of a formatter, like Black, but we can override this behavior by
# explicitly adding the rule.
extend-select = ["E501"]
再次运行 Ruff,我们看到它现在强制执行最大行宽,限制为 79
有关支持的设置的完整枚举,请参见设置。对于我们的项目,我们将特别注意支持的最低 Python 版本
规则选择
Ruff 支持超过800 个 lint 规则,分布在超过 50 个内置插件中,但是确定正确的规则集将取决于您的项目需求:某些规则可能过于严格,某些规则是框架特定的,等等。
默认情况下,Ruff 启用 Flake8 的 F
规则,以及 E
规则的子集,省略了任何与格式化程序(例如 ruff format
或 Black)的使用重叠的样式规则。
如果您是第一次引入 linter,默认规则集是一个很好的起点:它范围窄且重点突出,同时以零配置捕获各种常见错误(例如未使用的导入)。
如果您要从另一个 linter 迁移到 Ruff,则可以启用与先前配置中强制执行的规则等效的规则。例如,如果我们想强制执行 pyupgrade 规则,我们可以将配置文件设置为以下内容
如果我们再次运行 Ruff,我们将看到它现在强制执行 pyupgrade 规则。特别是,Ruff 标记了使用已弃用的 typing.Iterable
而不是 collections.abc.Iterable
$ uv run ruff check
src/numbers/calculate.py:1:1: UP035 [*] Import from `collections.abc` instead: `Iterable`
Found 1 error.
[*] 1 fixable with the `--fix` option.
随着时间的推移,我们可能会选择强制执行其他规则。例如,我们可能希望强制所有函数都具有文档字符串
如果我们再次运行 Ruff,我们将看到它现在强制执行 pydocstyle 规则
$ uv run ruff check
src/numbers/__init__.py:1:1: D104 Missing docstring in public package
src/numbers/calculate.py:1:1: UP035 [*] Import from `collections.abc` instead: `Iterable`
|
1 | from typing import Iterable
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP035
|
= help: Import from `collections.abc`
src/numbers/calculate.py:1:1: D100 Missing docstring in public module
Found 3 errors.
[*] 1 fixable with the `--fix` option.
忽略错误
可以通过将 # noqa
注释添加到相关行来忽略任何 lint 规则。例如,让我们忽略 Iterable
导入的 UP035
规则
from typing import Iterable # noqa: UP035
def sum_even_numbers(numbers: Iterable[int]) -> int:
"""Given an iterable of integers, return the sum of all even numbers in the iterable."""
return sum(num for num in numbers if num % 2 == 0)
再次运行 ruff check
,我们将看到它不再标记 Iterable
导入
$ uv run ruff check
src/numbers/__init__.py:1:1: D104 Missing docstring in public package
src/numbers/calculate.py:1:1: D100 Missing docstring in public module
Found 2 errors.
如果我们想忽略整个文件的规则,我们可以在文件中的任何位置添加行 # ruff: noqa: {code}
,最好是在顶部附近,例如
# ruff: noqa: UP035
from typing import Iterable
def sum_even_numbers(numbers: Iterable[int]) -> int:
"""Given an iterable of integers, return the sum of all even numbers in the iterable."""
return sum(num for num in numbers if num % 2 == 0)
有关忽略错误的更深入说明,请参见错误抑制。
添加规则
在现有代码库上启用新规则时,您可能希望忽略该规则的所有现有违规行为,而是专注于在将来强制执行它。
Ruff 通过 --add-noqa
标志启用此工作流程,该标志将根据其现有违规行为将 # noqa
指令添加到每一行。我们可以将 --add-noqa
与 --select
命令行标志结合使用,以将 # noqa
指令添加到所有现有的 UP035
违规行为
运行 git diff
显示以下内容
diff --git a/numbers/src/numbers/calculate.py b/numbers/src/numbers/calculate.py
index 71fca60c8d..e92d839f1b 100644
--- a/numbers/src/numbers/calculate.py
+++ b/numbers/src/numbers/calculate.py
@@ -1,4 +1,4 @@
-from typing import Iterable
+from typing import Iterable # noqa: UP035
集成
本教程重点介绍了 Ruff 的命令行界面,但是 Ruff 也可以通过 ruff-pre-commit
用作 pre-commit hook
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.12.4
hooks:
# Run the linter.
- id: ruff
# Run the formatter.
- id: ruff-format
Ruff 也可以集成到您选择的编辑器中。有关更多信息,请参考编辑器部分。
有关其他集成,请参见集成部分。