Ruffでlintとformatを一本化
「Ruffとは、Pythonのlintとformatを爆速に統合するツールである。」
Ruffの位置づけ
RuffはRust製の静的解析ツールで、ruff check
(lint)とruff format
(整形)を備える。Flake8/pycodestyle/pyflakes/isortの代替になり、Black互換のフォーマットを志向する。日々の開発で「スタイル議論を終わらせつつ、明らかなミスは機械で潰す」を目標にするなら、まず候補に挙がる。
まず結論:こう使う
- プロジェクトではRuffだけで整形+lint。
- 既存でBlackが根付いている場合はBlack=整形、Ruff=lintに分担。
- Gitフックはpre-commitで
ruff
→ruff-format
の順に実行。 - IDEではRuffを保存時に実行し、差分を最小化。
類似ツールの比較(同階層で比較)
ツール | 種別 | 自動整形 | 役割の範囲 | 速さ | メモ |
---|---|---|---|---|---|
Ruff | Lint+Format | あり(ruff format ) |
ルール検出、修正、import整列 | 速い | Black互換志向、一本化しやすい |
Black | Format | あり | 整形のみ | 速い | 迷いゼロ。isortは別 |
pylint | Lint | なし | 設計臭・複雑度・命名まで詳細 | 普通 | 厳しめ。整形はしない |
isort | Import整列 | 半ば整形 | import順序・分割 | 速い | Ruffが内包可 |
Flake8系 | Lint | なし | 規則チェック中心 | 普通 | Ruffが多く代替 |
pre-commit | フック基盤 | なし | ツールを呼ぶだけ | - | 仕組み。役者ではない |
フォーマット(format)の実務ポイント
- Ruffの整形はBlack互換のレイアウトを目指す。プロジェクトでBlackから移行する場合、差分は小さい。
-
行長は
[tool.ruff] line-length
で管理。ドキュメント文字列は自動で折り返されないため、過度に詰めない。 - 文字列の引用符統一などはフォーマッタで、未使用変数の削除はlintの自動修正に任せる、と役割を分けると安定する。
- ノートブックは
ruff format
で整形不可。スクリプト化、あるいはVSCode拡張の整形を使う。
Lint(check)の実務ポイント
-
ruff check --fix
で多数の違反を自動修正。残る指摘は設計判断が必要なものが中心になる。 - 初導入では
select = ["E","F","I"]
(pycodestyle/pyflakes/import整列)から始め、徐々に拡張(B,BLE,UP,PERFなど)。 - 型の厳密性はRuffでは担わない。mypyやpyrightで補完するのが現実解。
- 警告の一時抑制は
# noqa: ルール
で可能。ただし恒久化しない。
プロジェクト設定(pyproject.toml)
[tool.ruff]
line-length = 100
target-version = "py311"
extend-exclude = ["build/", "dist/", ".venv/", "migrations/"]
[tool.ruff.lint]
select = ["E", "F", "I"]
ignore = ["E402"] # 例: import順序の一時例外
fix = true
[tool.ruff.format]
quote-style = "double" # 例: 引用符を統一
方針:最初はミニマム設定で運用し、警告のノイズが見えたらignore
を明示しつつ、PRで合意形成する。
pre-commit連携
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.0
hooks:
- id: ruff
args: [--fix]
- id: ruff-format
- コミット時にlint→自動修正→整形まで一気通貫。
- 大量変更の初回は
pre-commit run --all-files
で一括適用すると差分の山を越えやすい。
VS Codeへの導入
- 拡張「Ruff」をインストール。
-
settings.json
に以下を設定:
{
"python.formatting.provider": "none",
"ruff.organizeImports": true,
"editor.codeActionsOnSave": {
"source.fixAll.ruff": true
},
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.formatOnSave": true
}
}
- Blackを併用する場合はdefaultFormatterをBlackにし、Ruffは
fixAll.ruff
だけ有効にする。
PyCharmへの導入
- 2024以降のPyCharmはRuffプラグインに対応。
- 設定 → Plugins → 「Ruff」導入。
- 設定 → Tools → File Watchers で
ruff format
とruff check --fix
を保存時に実行、またはExternal Toolsとして登録してショートカットに割り当てる。 - Blackを併用する場合は、フォーマッタをBlackに固定し、RuffはInspectionsで有効化して「Quick-fix」を活用。
CIでの実行
ruff check .
ruff format --check .
- PRで整形漏れを落とすには
format --check
を使う。 - 速度重視のため、テスト並列と同時に走らせてもビルド時間を圧迫しにくい。
よくある落とし穴と指針
- BlackとRuff formatの二重整形:どちらかに統一する。
- isortだけ残す:Ruffがimport整列を内包。重複させない。
- 過剰なルール有効化:はじめはE/F/Iだけ。ノイズを見て段階的に広げる。
- 巨大差分の恐怖:初回に全ファイルへ一括適用し、その後はPRで小さく維持。
-
Notebook依存:開発者向けは
.py
、分析用はNotebookと住み分ける。
導入チェックリスト
-
pyproject.toml
を配置し、最小セットE/F/I
で開始 -
pre-commitで
ruff
→ruff-format
を保存 - VSCode/PyCharmで保存時実行を有効化
-
CIで
ruff check
とformat --check
を追加 - ルール拡張の判断軸(ノイズ/価値)をチームで合意
これで、Ruff中心のスタックに乗り換えつつ、Blackとの共存も選べる。迷いを減らし、レビューをロジックに集中させよう。
既存プロジェクトへの移行ミニガイド
- 専用ブランチを切り、
pyproject.toml
に最小設定(E/F/I, line-length, target-version)を追加。 -
pre-commit
導入後、pre-commit run --all-files
で一括整形し、巨大差分を解消。 - CIに
ruff check .
とruff format --check .
を追加し、以後の逸脱を自動検出。 - Blackが定着している場合は、整形=Black / lint+import整列=Ruffに統一、READMEに明文化。
運用ポリシーの雛形(要点)
- フォーマット指摘は原則禁止。ルール提案は設定PRで。
-
# noqa
は暫定。期限をIssue化し、定期棚卸し。 - 段階導入(E/F/I → UP → B → SIM)。評価軸は「違反数」「自動修正率」「レビュー時間」。
仕上げのヒント
- Monorepoはルート共通、各パッケージで局所上書き。
- 導入初回は
format --diff
で影響を見て、ディレクトリ単位で段階適用。 - 保存時実行+CI+pre-commitの三段構えで、手作業ゼロの“いつでもきれい”を維持。
継続運用が開発体験を底上げする。小さく始めて定着。