Tutorial#
このチュートリアルでは、Ruff のリンタとフォーマッタをプロジェクトに統合するプロセスについて説明します。より詳細な概要については、Configuring Ruffを参照してください。
Getting Started#
まず、PyPI 経由で Ruff をインストールします(または、referred package managerを使用します)。:
次に、プロジェクト構造が次のようになっていると仮定します。:
ここで、numberspy
には次のコードが含まれます。:
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 linter を実行するには、ruff check
を使用します。:
$ ruff check
numbers/numbers.py:3:8: F401 [*] `os` imported but unused
Found 1 error.
[*] 1 fixable with the `--fix` option.
Ruff は、Python コードの一般的なエラーである未使用のインポートを特定しました。Ruff はこれを"修正可能な"エラーと見なしているため、ruff check --fix
を実行することで問題を自動的に解決できます。:
git diff
を実行すると、次のように表示されます。:
--- a/numbers/numbers.py
+++ b/numbers/numbers.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/numbers.py
+++ b/numbers.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 の動作のカスタマイズ方法を見てみましょう。
Configuration#
各 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 であることがわかります。:
サポートされている設定の完全な一覧については、Settingsを参照してください。特にこのプロジェクトでは、サポートされている Python の最小バージョンをメモしておきます。:
Rule Selection#
Ruff は、50 以上の組み込みプラグインに分割されたover 800 lint rulesをサポートしていますが、適切なルールのセットを決定することは、プロジェクトのニーズに依存します。ルールには厳しすぎるものもあれば、フレームワーク固有のものもあります。
デフォルトでは、Ruff は Flake8 の"F"ルールを"E"ルールのサブセットとともに有効にし、"ruff format"やBlackのようなフォーマッタの使用と重複するスタイルのルールを省略します。
リンターを初めて導入する場合は、デフォルトのルール・セットから始めるのが最適です。つまり、構成なしでさまざまな一般的なエラー(未使用のインポートなど)をキャッチしながら、ルール・セットは狭く焦点を絞っています。
別のリンターから Ruff に移行する場合は、以前の構成で適用されていたルールと同等のルールを有効にすることができます。たとえば、pyupgraderules を適用したい場合は、構成ファイルを次のように設定できます。:
Ruff を再度実行すると、pyupgrade ルールが適用されていることがわかります。特に、Ruff はcollections.abc.Iterable
の代わりに非推奨のtyping.Iterable
を使用していることにフラグを立てています。:
$ ruff check
numbers/numbers.py:1:1: UP035 [*] Import from `collections.abc` instead: `Iterable`
Found 1 error.
[*] 1 fixable with the `--fix` option.
時間の経過とともに、追加のルールを適用することを選択する場合があります。たとえば、すべての関数に docstring があることを適用する場合があります。:
Ruff を再度実行すると、pydocstyle のルールが適用されていることがわかります。:
$ ruff check
numbers/__init__.py:1:1: D104 Missing docstring in public package
numbers/numbers.py:1:1: UP035 [*] Import from `collections.abc` instead: `Iterable`
numbers/numbers.py:1:1: D100 Missing docstring in public module
Found 3 errors.
[*] 1 fixable with the `--fix` option.
Ignoring Errors#
リントルールは、問題の行に# noqa
コメントを追加することで無視できます。たとえば、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
インポートにフラグが立っていないことがわかります。:
$ ruff check
numbers/__init__.py:1:1: D104 Missing docstring in public package
numbers/numbers.py:1:1: D100 Missing docstring in public module
Found 3 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)
エラーを無視する方法の詳細については、Error suppressionを参照してください。
Adding Rules#
既存のコードベースで新しいルールを有効にする場合、そのルールのすべての既存の違反を無視し、今後はそれを強制することに重点を置くことができます。
Ruff は、--add-noqa
フラグを介してこのワークフローを有効にします。これにより、既存の違反に基づいて各ラインに# noqa
ディレクティブが追加されます。--add-noqa
と--select
コマンドラインフラグを組み合わせると、既存のすべてのUP035
違反に# noqa
ディレクティブを追加できます。:
git diff
を実行すると、次のように表示されます。:
diff --git a/tutorial/src/main.py b/tutorial/src/main.py
index b9291c5ca..b9f15b8c1 100644
--- a/numbers/numbers.py
+++ b/numbers/numbers.py
@@ -1,4 +1,4 @@
-from typing import Iterable
+from typing import Iterable # noqa: UP035
def sum_even_numbers(numbers: Iterable[int]) -> int:
Integrations#
このチュートリアルでは Ruff のコマンドラインインターフェイスに焦点を当てていますが、Ruff はruff-pre-commit
を介してpre-commitフックとしても使用できます。:
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.1.4
hooks:
# Run the linter.
- id: ruff
# Run the formatter.
- id: ruff-format
Ruff は、任意のエディタに統合することもできます。詳細については、Editorsセクションを参照してください。
その他の統合については、Integrationsセクションを参照してください。