はじめに
Python の lint / format ツールは選択肢が多く、プロジェクトごとに Flake8 + isort + Black を組み合わせて使うケースが一般的でした。しかし設定ファイルが分散し、ツール間のルール競合に悩まされることも少なくありません。
Ruff は、これらを1つのツールに統合した Rust 製の linter / formatter です。Flake8 系プラグイン、isort、pyupgrade など多くの lint ルールをカバーし、formatter は Black 互換を強く意識した設計になっています(ただし完全一致ではなく、一部に意図的な差異があります)。
私が開発に携わっている入退室管理システム(Python / AWS CDK)では、プロジェクト立ち上げ時から Ruff を採用し、select = ["ALL"] で全ルールを有効化した上で不要なルールだけを ignore する運用をしています。pre-commit にも組み込んでおり、コミット時に ruff check --fix と ruff format が自動実行される体制です。
この記事では、Ruff の導入手順と実践的な設定例を紹介します。既存プロジェクトへの段階的な導入方法も解説するので、「ツールが多すぎて整理したい」という方はぜひ参考にしてください。
Ruff とは
- Rust 製の Python linter / formatter
- Flake8 + isort + Black + pyupgrade + pydocstyle 等、数百以上のルール を1つのツールでカバー
- 従来ツール比で 10〜100倍 高速
pyproject.tomlで設定を一元管理- VS Code 拡張あり(保存時に自動修正)
Ruff が置き換えられるツール
| 従来のツール | Ruff での対応 |
|---|---|
| Flake8 | ruff check(lint) |
| isort | ruff check --select I(import ソート) |
| Black | ruff format(フォーマット) |
| pyupgrade | ruff check --select UP(構文の近代化) |
| pydocstyle | ruff check --select D(docstring チェック) |
インストール
pip install ruff
バージョン確認:
ruff --version
プロジェクト単位で管理する場合は、requirements-dev.txt や pyproject.toml の dev dependencies に追加します。
# pip の場合
echo "ruff" >> requirements-dev.txt
# uv の場合
uv add --dev ruff
基本的な使い方
lint(コードチェック)
# チェックのみ
ruff check .
# 自動修正可能なものを修正
ruff check --fix .
format(コード整形)
# フォーマット
ruff format .
# 差分だけ確認(実際には変更しない)
ruff format --check .
pyproject.toml での設定
Ruff の設定は pyproject.toml に集約できます。以下は実務で使いやすい設定例です。
[tool.ruff]
# Python バージョン(構文チェックの基準)
target-version = "py311"
# 1行の最大文字数
line-length = 120
# チェック対象
src = ["src", "tests"]
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # Pyflakes
"I", # isort(import ソート)
"UP", # pyupgrade(古い構文の近代化)
"B", # flake8-bugbear(バグになりやすいパターン)
"SIM", # flake8-simplify(簡潔に書けるパターン)
]
ignore = [
"E501", # formatter がベストエフォートで調整するため、厳密に運用しない場合は除外
]
[tool.ruff.lint.isort]
known-first-party = ["src"]
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
設定のポイント
selectで必要なルールだけ有効化する:まずはE,W,F,Iから始めて段階的に追加するのがおすすめ。一方、新規プロジェクトならselect = ["ALL"]で全ルールを有効にし、プロジェクトに合わないルールだけをignoreで除外していくアプローチもある。既存コードがないため警告が溜まらず、最初から厳格な基準で開発を始められるE501は ignore も選択肢:E501はruff formatと併用可能だが、formatter は行長をベストエフォートでしか調整しないため、整形後でもE501が出る場合がある。厳密な行長制約を運用しないならignoreするのも手line-lengthは lint と format で共有される:[tool.ruff]に書けば両方に適用されるtarget-versionとproject.requires-python:pyproject.tomlに[project]セクションがある場合はrequires-pythonからバージョンが推定される。target-versionを明示すればそちらが優先されるが、両方書かなくても動作する
既存プロジェクトへの段階的な導入
大量の既存コードがあるプロジェクトでは、一度に全ルールを適用すると差分が膨大になります。以下の手順で段階的に導入するのがおすすめです。
ステップ 1:format だけ先に適用
ruff format .
フォーマットは意味的な変更を伴わないため、リスクが低いです。まず format だけを適用してコミットします。
ステップ 2:最小限のルールで lint を導入
[tool.ruff.lint]
select = ["E", "W", "F", "I"]
基本的なエラー検出と import ソートだけで開始します。
ステップ 3:自動修正を適用
ruff check --fix .
--fix で自動修正できるものを一括で適用します。修正内容を差分で確認してからコミットします。
なお、自動修正できない違反が大量にある場合は ruff check --add-noqa . で既存の違反行に # noqa コメントを一括付与し、一旦棚上げする方法もあります。新規コードだけをクリーンに保ちつつ、既存コードは後から段階的に対応できます。
ステップ 4:ルールを段階的に追加
UP(pyupgrade)や B(bugbear)など、プロジェクトに合ったルールを順次追加していきます。
CI での活用
GitHub Actions で lint + format チェックを実行する例です。
name: Lint
on: [push, pull_request]
jobs:
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/ruff-action@v3
with:
args: "check"
- uses: astral-sh/ruff-action@v3
with:
args: "format --check"
公式の astral-sh/ruff-action を使えば、インストール不要で高速に実行できます。
VS Code との連携
Ruff の VS Code 拡張を入れると、保存時に lint 修正 + format を自動実行できるようになります。
拡張のインストール
VS Code の拡張機能から「Ruff」(astral-sh.ruff)をインストールします。
settings.json の設定
{
"[python]": {
"editor.defaultFormatter": "astral-sh.ruff",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.ruff": "explicit",
"source.organizeImports.ruff": "explicit"
}
}
}
この設定により、保存時に以下を自動実行できます:
- import のソート(isort 相当)
- 自動修正可能な lint エラーの修正
- コードフォーマット(Black 互換)
従来ツールからの移行
Flake8 からの移行
Flake8 のルールの多くは Ruff に対応するルールコードがあります。手動で読み替えて移行します。
| Flake8 の設定 | Ruff での対応 |
|---|---|
max-line-length | [tool.ruff] の line-length |
ignore = E501,W503 | [tool.ruff.lint] の ignore |
per-file-ignores | [tool.ruff.lint.per-file-ignores] |
.flake8 や setup.cfg の設定を確認し、対応する Ruff の設定に書き換えます。Ruff のルール一覧で Flake8 ルールとの対応を確認できます。
Black からの移行
Ruff の formatter は Black 互換を強く意識しており、デフォルト設定はほぼ同じです。ただし、完全一致ではなく一部に意図的な差異があるため、Black との混在運用は推奨されていません。line-length や quote-style をカスタマイズしている場合は [tool.ruff.format] に設定を移します。
isort からの移行
[tool.ruff.lint.isort] セクションで isort と同じ設定が可能です。known-first-party や known-third-party もそのまま移行できます。
移行後は、.flake8、setup.cfg の flake8 セクション、Black / isort の設定を削除して、pyproject.toml に一本化します。
まとめ
- Ruff は Flake8 + isort + Black を *

コメント