Ruff: 高速なPythonリンターとフォーマッター
Ruffは、Pythonプロジェクトのためのリンティングとフォーマットを行う高速なツールです。LLMをベースとしたコーディングエージェントでの利用を想定した、この自動生成ドキュメントでは、Ruffの基本的な使い方と、特にuvとの連携について詳しく説明します。
目次
- 概要
- インストール
- uvとの連携
- 基本的な使い方
- 設定
- リンター機能
- フォーマッター機能
- TDDでの活用
- プロジェクト管理での活用
- 環境管理での活用
- エディタ統合
- マイグレーションガイド
- トラブルシューティング
- パフォーマンスの最適化
- ベストプラクティス
概要
Ruffは以下の特徴を持つPythonツールです:
- 高速なリンター: Flake8(および多数のプラグイン)、isort、pydocstyle、pyupgrade、autoflakeなどの代替として機能します
- 高速なフォーマッター: Blackの代替として機能します
- Rustで実装: パフォーマンスを最大化するためにRustで書かれています
- 統合ツールチェーン: リンティングとフォーマットを一つのツールで行えます
インストール
Ruffは複数の方法でインストールできますが、uvを使用する方法が推奨されています。
uvを使ったインストール(推奨)
プロジェクトにRuffを追加する:
uv add --dev ruff
グローバルにRuffをインストールする:
uv tool install ruff@latest
uvとの連携
uvはPythonのパッケージマネージャーおよび環境マネージャーで、Ruffと同じAstralプロジェクトの一部です。uvとRuffを組み合わせることで、Pythonプロジェクトの開発ワークフローを大幅に改善できます。
uvxを使ったRuffの直接実行
uvxコマンドを使用すると、Ruffをインストールせずに直接実行できます:
uvx ruff check # カレントディレクトリ内のすべてのファイルをリント
uvx ruff format # カレントディレクトリ内のすべてのファイルをフォーマット
これは、プロジェクトごとに異なるバージョンのRuffを使用したい場合や、一時的にRuffを試したい場合に便利です。
プロジェクトへのRuffの追加
uvを使用してプロジェクトにRuffを追加する場合:
uv add --dev ruff
このコマンドは、プロジェクトのpyproject.toml
ファイルに開発依存関係としてRuffを追加します。
仮想環境の管理とRuff
uvを使用して仮想環境を作成・管理する場合、Ruffもその環境内で使用できます:
# 新しい仮想環境を作成
uv venv
# 仮想環境をアクティベート
# Windowsの場合
.venv\Scripts\activate
# macOS/Linuxの場合
source .venv/bin/activate
# 環境にRuffをインストール
uv add --dev ruff
CI/CDパイプラインでの連携
CI/CDパイプラインでuvとRuffを組み合わせて使用する例:
# GitHub Actionsの例
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install uv
run: curl -LsSf https://astral.sh/uv/install.sh | sh
- name: Run Ruff
run: |
uv add --dev ruff
uvx ruff check --output-format=github
pre-commitフックとしての設定
uvとRuffをpre-commitフックとして設定する例:
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: ruff
name: ruff
entry: uvx ruff check --fix
language: system
types: [python]
基本的な使い方
リンティング
# カレントディレクトリ内のすべてのファイルをリント
ruff check
# 特定のディレクトリやファイルをリント
ruff check path/to/code/
# 自動修正を適用
ruff check --fix
# 監視モードで実行(ファイルが変更されるたびに再実行)
ruff check --watch
フォーマット
# カレントディレクトリ内のすべてのファイルをフォーマット
ruff format
# 特定のディレクトリやファイルをフォーマット
ruff format path/to/code/
# フォーマットせずに変更が必要なファイルをチェック
ruff format --check
インポートの整理とフォーマット
現在、Ruffフォーマッターはインポートの整理を行いません。インポートを整理してからフォーマットするには:
ruff check --select I --fix # インポートを整理
ruff format # コードをフォーマット
設定
Ruffはpyproject.toml
、ruff.toml
、または.ruff.toml
ファイルで設定できます。
基本的な設定例
# pyproject.toml
[tool.ruff]
# 共通の無視ディレクトリを除外
exclude = [
".git",
".venv",
"__pycache__",
"build",
"dist",
]
# Blackと同じ
line-length = 88
indent-width = 4
# Python 3.9を想定
target-version = "py39"
[tool.ruff.lint]
# デフォルトで有効にするルール
select = ["E4", "E7", "E9", "F"]
ignore = []
# 自動修正を許可するルール
fixable = ["ALL"]
unfixable = []
[tool.ruff.format]
# 文字列にダブルクォートを使用
quote-style = "double"
# インデントにスペースを使用
indent-style = "space"
推奨設定例
より包括的な設定例:
# pyproject.toml
[tool.ruff]
line-length = 88
target-version = "py39"
[tool.ruff.lint]
select = [
# pycodestyle
"E",
# Pyflakes
"F",
# pyupgrade
"UP",
# flake8-bugbear
"B",
# flake8-simplify
"SIM",
# isort
"I",
]
# 特定のファイルパターンに対して特定のルールを無視
[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["E402"]
"**/tests/*" = ["E501"]
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
line-ending = "auto"
リンター機能
ルールの選択
Ruffのリンターは、Flake8のルールコードシステムを踏襲しています。各ルールコードは1〜3文字のプレフィックスと3桁の数字で構成されます(例:F401
)。
ルールの選択例:
[tool.ruff.lint]
# すべてのルールを有効にする
select = ["ALL"]
# 特定のルールを無視する
ignore = ["E501", "F401"]
# 特定のファイルパターンに対して特定のルールを無視
[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["E402"]
"**/tests/*" = ["E501"]
自動修正
Ruffは多くのリントエラーに対して自動修正をサポートしています:
# 自動修正を適用
ruff check --fix
# 安全でない修正も含めて適用
ruff check --fix --unsafe-fixes
エラー抑制
コード内でリントエラーを抑制する方法:
# F841を無視
x = 1 # noqa: F841
# E741とF841を無視
i = 1 # noqa: E741, F841
# すべての違反を無視
x = 1 # noqa
# ファイル全体で特定のルールを無視
# ruff: noqa: F841
フォーマッター機能
基本的なフォーマット
Ruffフォーマッターは、Blackの代替として設計されています:
# カレントディレクトリ内のすべてのファイルをフォーマット
ruff format
# 特定のディレクトリやファイルをフォーマット
ruff format path/to/code/
# フォーマットせずに変更が必要なファイルをチェック
ruff format --check
# 差分を表示
ruff format --diff
フォーマット設定
フォーマッターの設定例:
[tool.ruff.format]
# シングルクォートを使用
quote-style = "single"
# タブインデントを使用
indent-style = "tab"
# ドキュメント文字列内のコード例をフォーマット
docstring-code-format = true
# ドキュメント文字列内のコード例の行長制限
docstring-code-line-length = "dynamic"
フォーマット抑制
特定のコードブロックのフォーマットを無効にする方法:
# fmt: off
not_formatted=3
also_not_formatted=4
# fmt: on
# 特定のステートメントのフォーマットをスキップ
a = [1, 2, 3, 4, 5] # fmt: skip
TDDでの活用
Ruffはテスト駆動開発(TDD)ワークフローを改善するために活用できます。
テストファイルの自動検出と実行
uvとRuffを組み合わせたTDDワークフロー例:
# テスト環境のセットアップ
uv venv
source .venv/bin/activate # または .venv\Scripts\activate(Windows)
uv add --dev pytest ruff
# テストファイルをリントしながらテストを実行
uvx pytest && uvx ruff check tests/
# 監視モードでテストとリントを実行
uvx pytest -xvs tests/ && uvx ruff check --watch tests/
テストカバレッジの向上
Ruffを使用してコードの品質を向上させることで、テストカバレッジも向上します:
# 未使用のインポートや変数を検出して削除
ruff check --select F401,F841 --fix
# テストカバレッジを実行
uvx pytest --cov=src
CI/CDパイプラインでのテスト
GitHub Actionsなどのパイプラインでuvとruffを使用したテスト例:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install uv
run: curl -LsSf https://astral.sh/uv/install.sh | sh
- name: Setup environment
run: |
uv venv
uv add --dev pytest pytest-cov ruff
- name: Lint and test
run: |
uvx ruff check
uvx pytest --cov=src
プロジェクト管理での活用
新規プロジェクトのセットアップ
uvとRuffを使用した新規Pythonプロジェクトのセットアップ例:
# プロジェクトディレクトリの作成
mkdir my_project && cd my_project
# 仮想環境のセットアップ
uv venv
source .venv/bin/activate # または .venv\Scripts\activate(Windows)
# 基本的な依存関係のインストール
uv add --dev ruff pytest
# pyproject.tomlの作成
cat > pyproject.toml << EOF
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "my_project"
version = "0.1.0"
description = "My Python Project"
readme = "README.md"
requires-python = ">=3.9"
[tool.ruff]
line-length = 88
target-version = "py39"
[tool.ruff.lint]
select = ["E", "F", "B", "I"]
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
EOF
# 基本的なディレクトリ構造の作成
mkdir -p src/my_project tests
touch src/my_project/__init__.py tests/__init__.py
既存プロジェクトへの導入
既存のプロジェクトにRuffを導入する手順:
-
Ruffをインストール:
uv add --dev ruff
-
基本的な設定を追加:
cat >> pyproject.toml << EOF [tool.ruff] line-length = 88 target-version = "py39" [tool.ruff.lint] select = ["E", "F"] EOF
-
既存コードに自動的にnoqaコメントを追加:
ruff check --add-noqa
-
段階的にルールを追加:
# まず基本的なルールで修正 ruff check --select E,F --fix # 次にインポートを整理 ruff check --select I --fix # コードをフォーマット ruff format
依存関係管理
uvとRuffを組み合わせた依存関係管理:
# 依存関係の追加
uv add requests
uv add --dev pytest
# 依存関係のロック
uv pip compile requirements.in -o requirements.txt
uv pip compile dev-requirements.in -o dev-requirements.txt
# 依存関係のインストール
uv pip install -r requirements.txt
uv pip install -r dev-requirements.txt --dev
環境管理での活用
複数のPythonバージョンでのテスト
uvとRuffを使用して複数のPythonバージョンでテストする例:
# Python 3.9環境でテスト
uv venv --python=3.9
source .venv/bin/activate
uv add --dev pytest ruff
uvx pytest
uvx ruff check
# Python 3.10環境でテスト
uv venv --python=3.10
source .venv/bin/activate
uv add --dev pytest ruff
uvx pytest
uvx ruff check
開発環境と本番環境の分離
uvとRuffを使用した環境分離の例:
# 開発環境
uv venv --name dev
source .venv-dev/bin/activate
uv add --dev pytest ruff black mypy
# 本番環境
uv venv --name prod
source .venv-prod/bin/activate
uv add -r requirements.txt
Docker環境での使用
Dockerfileの例:
FROM python:3.9-slim
WORKDIR /app
# uvとRuffをインストール
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
ENV PATH="/root/.cargo/bin:${PATH}"
# 依存関係をコピーしてインストール
COPY requirements.txt .
RUN uv pip install -r requirements.txt
# アプリケーションコードをコピー
COPY . .
# コードをリントしてテスト
RUN uv add --dev ruff pytest
RUN uvx ruff check
RUN uvx pytest
# アプリケーションを実行
CMD ["python", "src/main.py"]
エディタ統合
Ruffは主要なコードエディタと統合できます。
Visual Studio Code
VS Codeでは、Ruff拡張機能を使用できます:
- VS Code拡張機能マーケットプレイスからRuff拡張機能をインストール
-
settings.json
に以下の設定を追加:
{
"editor.formatOnSave": true,
"python.formatting.provider": "none",
"python.linting.enabled": true,
"python.linting.lintOnSave": true,
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": true,
"source.organizeImports": true
}
}
}
マイグレーションガイド
Flake8からの移行
Flake8からRuffへの移行手順:
-
Ruffをインストール:
uv add --dev ruff
-
既存のFlake8設定を変換:
-
.flake8
またはsetup.cfg
の設定をpyproject.toml
に移行 - 例えば、Flake8の
ignore = E203, W503
は以下のようになります:[tool.ruff.lint] ignore = ["E203", "W503"]
-
-
Flake8プラグインの対応するRuffルールを有効化:
[tool.ruff.lint] select = [ "E", "F", # Flake8 "B", # flake8-bugbear "C4", # flake8-comprehensions "I", # isort "SIM", # flake8-simplify ]
-
既存のコードに自動的にnoqaコメントを追加:
ruff check --add-noqa
BlackとisortからRuffへの移行
BlackとisortからRuffへの移行手順:
-
Ruffをインストール:
uv add --dev ruff
-
既存の設定を変換:
-
Blackの設定(
pyproject.toml
の[tool.black]
セクション)をRuffの設定に移行 -
isortの設定(
pyproject.toml
の[tool.isort]
セクション)をRuffの設定に移行 -
例:
# Blackの設定 [tool.black] line-length = 88 target-version = ["py39"] # isortの設定 [tool.isort] profile = "black" line_length = 88
以下のようになります:
[tool.ruff] line-length = 88 target-version = "py39" [tool.ruff.lint] select = ["I"] # isortルールを有効化
-
-
コードをフォーマットしてインポートを整理:
ruff check --select I --fix ruff format
トラブルシューティング
一般的な問題と解決策
問題: Ruffが特定のファイルを無視する
解決策: 設定ファイルのexclude
パターンを確認し、必要に応じてextend-exclude
を調整します。
[tool.ruff]
# 除外パターンを確認
exclude = [
".git",
".venv",
]
問題: 特定のルールが適用されない
解決策: select
とignore
の設定を確認し、ルールが正しく選択されているか確認します。
# 現在の設定を確認
ruff check --show-settings
# 特定のルールを明示的に有効化
ruff check --select E501
問題: フォーマッターとリンターの競合
解決策: フォーマッターと競合する可能性のあるリンターのルールを無効化します。
[tool.ruff.lint]
# フォーマッターと競合するルールを無効化
ignore = ["E111", "E114", "E117", "D206", "W191", "Q000", "Q001", "Q002", "Q003", "COM812", "COM819"]
uvとの連携における問題
問題: uvxコマンドが見つからない
解決策: uvが正しくインストールされているか確認します。
# uvをインストール
curl -LsSf https://astral.sh/uv/install.sh | sh
# PATHを確認
echo $PATH
問題: 仮想環境内でRuffが見つからない
解決策: 仮想環境が正しくアクティベートされているか、Ruffが正しくインストールされているか確認します。
# 仮想環境を再アクティベート
source .venv/bin/activate # または .venv\Scripts\activate(Windows)
# Ruffを再インストール
uv add --dev ruff
パフォーマンスの最適化
Ruffは非常に高速ですが、さらにパフォーマンスを最適化するための方法があります。
キャッシュの活用
Ruffはデフォルトでキャッシュを使用しますが、キャッシュディレクトリを指定することもできます:
# キャッシュディレクトリを指定
ruff check --cache-dir .ruff_cache
# キャッシュを無効化(CI環境などで)
ruff check --no-cache
並列処理の最適化
大規模なプロジェクトでは、Ruffの並列処理機能が自動的に活用されます。特別な設定は必要ありません。
増分チェック
変更されたファイルのみをチェックすることで、CI/CDパイプラインを高速化できます:
# Gitの差分を使用して変更されたファイルのみをチェック
git diff --name-only main | grep '\.py$' | xargs ruff check
監視モードの活用
開発中は監視モードを使用して、変更されたファイルのみを自動的にチェックできます:
ruff check --watch
ベストプラクティス
段階的な導入
新しいプロジェクトや既存のプロジェクトにRuffを導入する際は、段階的に進めることをお勧めします:
-
基本的なルールから始める:
[tool.ruff.lint] select = ["E", "F"]
-
自動修正可能なルールを追加:
[tool.ruff.lint] select = ["E", "F", "I", "UP"]
-
より厳格なルールを追加:
[tool.ruff.lint] select = ["E", "F", "I", "UP", "B", "SIM"]
CI/CDパイプラインでの活用
CI/CDパイプラインでRuffを効果的に使用するためのベストプラクティス:
-
チェックモードでフォーマットを検証:
ruff format --check
-
厳格なリンティングを適用:
ruff check --select ALL
-
結果を構造化フォーマットで出力:
ruff check --output-format=github
コードレビューでの活用
コードレビュープロセスでRuffを活用する方法:
-
プルリクエスト前にRuffを実行:
# 変更されたファイルのみをチェック git diff --name-only origin/main | grep '\.py$' | xargs ruff check
-
コードレビューコメントの自動化:
# GitHub Actionsでコードレビューコメントを自動化 ruff check --output-format=github
-
共通のスタイルガイドとしてRuffを使用:
# チーム全体で共有するruff.toml [lint] select = ["E", "F", "B", "I"] ignore = [] [format] quote-style = "double" indent-style = "space"
まとめ
RuffとuvはPythonプロジェクトの開発ワークフローを大幅に改善する強力なツールです。Ruffの高速なリンティングとフォーマット機能と、uvの効率的なパッケージ管理・環境管理機能を組み合わせることで、より生産的なPython開発が可能になります。
このドキュメントで紹介した方法を活用して、プロジェクト管理、環境管理、TDDなどの開発プロセスを効率化してください。特に:
-
uvとRuffの連携: uvxコマンドを使用したRuffの直接実行や、uvを使用した仮想環境管理とRuffの組み合わせにより、開発ワークフローを効率化できます。
-
段階的な導入: 新しいプロジェクトや既存のプロジェクトにRuffを導入する際は、基本的なルールから始めて徐々に厳格なルールを追加することで、スムーズな移行が可能です。
-
CI/CDパイプラインでの活用: GitHub ActionsなどのCI/CDパイプラインでuvとRuffを組み合わせることで、コードの品質を継続的に確保できます。
-
エディタ統合: VS Code、PyCharm、Vim/Neovimなどのエディタと統合することで、開発中にリアルタイムでコードの品質を確保できます。
Ruffとuvを組み合わせることで、Pythonプロジェクトの開発効率と品質を大幅に向上させることができます。