python-lint について
python-lintは、PythonパッケージでRuffをリンター兼フォーマッターとして設定するスキルです。新規設定やBlack、Flake8、isortからの移行、ルール調整、問題の修正を扱います。
主な機能
- 01pyproject.tomlでRuffのルールを明示
- 02Ruffのバージョン固定と対象Pythonの指定
- 03Black、Flake8、isortからの移行
- 04ルール調整と例外範囲の設定
- 05チェックとフォーマットの修正・検証
活用シーン
- 01新しいPythonパッケージにRuffを設定
- 02従来のチェック・フォーマットツールを置換
- 03テストやスクリプトのルールを調整
- 04チェックやフォーマットの失敗を解消
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ paldom/ python-skills --skill python-lintインストール後、Claude Code で/python-lintを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
evals/evals.jsonreferences/migration.mdrule-selection.mdscripts/check_ruff_config.py詳細
python-lint
目的
Ruff を Python パッケージの唯一のリンター兼フォーマッターとして設定します。Black、Flake8(プラグインを含む)、isort、pyupgrade を置き換え、明示的なルールセットを pyproject.toml に定義してから、ruff check と ruff format --check を正常終了する状態にします。新規セットアップ、従来のツールスタックからの移行、ルールの調整、リンターやフォーマッターの失敗の修正を扱います。以下のコマンドはすべて、ユーザーのパッケージリポジトリで実行します。
使用しない場合
- 型エラー/mypy/pyright/ty — Ruff は型推論を行いません。
ANNルールがチェックするのは型注釈の スタイル だけです。インストール済みの場合は、python-typing スキルが担当します。 - pre-commit の設定(
.pre-commit-config.yaml、フックの rev 固定、ステージ済みファイルの実行)— python-precommit スキルを使用してください。このスキルでは、Ruff が何を実行するかだけを定義します。 - CI ワークフローの YAML(GitHub Actions のジョブ、マトリックス、キャッシュ)— python-ci スキルを使用してください。このスキルでは、CI ジョブが実行すべきコマンドを提示しますが、ワークフロー自体は扱いません。
- YAML/JSON/TOML/Markdown の文章のフォーマット — Ruff がフォーマットするのは Python のみです(0.16 以降は Markdown 内の Python コードフェンスも対象)。それ以外は、メンテナーの意図的な判断により対象外です(astral-sh/ruff#10738)。Python 以外のファイルは python-precommit スキルが扱います。
- エージェントによる編集時に Ruff を自動実行すること(Claude Code のフック)— agent-guardrails スキルを使用してください。
ワークフロー
1. 変更前に確認する
ls .flake8 .isort.cfg setup.cfg tox.ini ruff.toml .ruff.toml 2>/dev/null
grep -nE '^\[tool\.(ruff|black|isort)|^\[flake8\]|^\[isort\]' pyproject.toml setup.cfg tox.ini 2>/dev/null
grep -n 'requires-python' pyproject.toml
次のいずれかを選びます。新規セットアップ(手順 2~3)、Black/Flake8/isort からの移行(手順 5)、既存設定の調整(手順 4)、または失敗しているリンターチェックの修正(手順 6)です。
2. バージョンを固定した Ruff をインストールする
uv add --dev "ruff==0.16.6" # example pin — check the latest release and pin that
# one-off, no project change:
uvx --from 'ruff==0.16.6' ruff check .
uv を使わない場合の代替手順(一度実行すれば、以下のすべてのコマンドに適用されます):python -m pip install 'ruff==0.16.6' を実行し、uv run のプレフィックスを削除します。
バージョンを固定する理由 — マイナーリリースごとにフォーマッターの出力とルールの一覧が変わります。0.15 では「2026 スタイルガイド」が導入され、ラムダ式と空行のフォーマットが変更されました(astral.sh/blog/ruff-v0.15.0)。また、0.16(2026-07-23)ではデフォルトのルールセットが 59 から 413 ルールに拡大する一方、18 個の E/F コードが対象から外れたため、設定されていないリポジトリの検出結果が一夜にして変わりました(astral.sh/blog/ruff-v0.16.0)。Ruff のバージョンを固定しないと、ローカル、チームメンバー、CI の実行結果が一致しなくなります。これは、リンターワークフローで最も多く報告される失敗です。必要に応じて [tool.ruff] の下に required-version = "0.16.6" を設定し、構成でもバージョンを固定できます。なお、uv format(uv 0.8.13 以降で実験的に提供)は同梱の Ruff を実行するため、プロジェクトで固定したバージョンと異なる場合があります。正とするバージョンは開発用依存関係の ruff で管理し、uv format は便利なラッパーとして扱ってください。
3. 設定を書く(新規セットアップ)
Ruff の設定はすべて pyproject.toml に記述します。設定ファイルは必ず1つだけにしてください。[tool.ruff] セクションと同じ場所に ruff.toml を置くと、混乱の原因になります。ひな形:
[tool.ruff]
target-version = "py311" # lowest Python you support; gates UP rewrites
line-length = 88
extend-exclude = ["migrations"] # generated code, if any
[tool.ruff.lint]
select = [
"E", "W", # pycodestyle
"F", # pyflakes
"I", # isort (import sorting)
"UP", # pyupgrade
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"SIM", # flake8-simplify
"RUF", # Ruff-specific rules
]
ignore = ["E501"] # line length is the formatter's job
[tool.ruff.lint.per-file-ignores]
"tests/**/*.py" = ["S101"] # assert is fine in tests (relevant once S is on)
"__init__.py" = ["F401"] # re-exports
[tool.ruff.lint.isort]
known-first-party = ["yourpackage"]
[tool.ruff.format]
quote-style = "double"
docstring-code-format = true # formats Python snippets inside docstrings
このブロックに含まれる、わかりにくい判断事項:
- Ruff のデフォルトルールセットに頼らないでください。 0.16 より前は
E4/E7/E9F(59 個のルールで、Flake8 とプラグインの組み合わせより少ない)でした。0.16 以降はB、UP、SIM、PLなどにまたがる 413 個のルールとなり、以前のE/Fのデフォルトルールのうち 18 個が削除されています。selectのないリポジトリでは、アップグレードのたびにチェック基準が変わります。selectはデフォルトのセットを置き換えるため、明示的なリストで固定できます。チームで以前の 0.16 未満の基準を そのまま使いたい場合は、select = ["E4", "E7", "E9", "F"]で再現できます。
- フォーマッターを有効にしている場合は、必ず
ignore = ["E501"]を設定してください。ruff formatはすでにline-lengthに合わせて折り返します。これも lint の対象にすると、フォーマッターでは改行できない行(URL や長い文字列)で 二重に報告されます。 target-versionはUP(pyupgrade)の書き換え対象を制限します。 未設定の場合、Ruff はproject.requires-pythonの値を使用します。それもない場合は py310 を想定するため、 自動修正によって、古いサポート対象のランタイムでクラッシュする構文が出力される可能性があります。select = ["ALL"]は避けてください。Ruff をアップグレードするたびに新しいルールがすべて暗黙に有効になり、 チェックが予測不能な形で失敗します。公式ガイダンスでは、範囲を絞って始め、カテゴリを一度に1つずつ増やすことが推奨されています (docs.astral.sh/ruff/linter/)。
詳しいルール一覧、段階的な適用戦略、サブテーブルのオプション(isort、pydocstyle、
bugbear)については、references/rule-selection.md を参照してください。
4. 既存の設定を調整する
- 特定の領域(テスト、スクリプト、ノートブック)で警告が多い場合 →
[tool.ruff.lint.per-file-ignores]で対象を限定します。 テストで問題が出るからといって、selectからルールを全体的に削除しないでください。よく使われる設定:"tests/**/*.py" = ["S101", "PLR2004"],"scripts/*" = ["T201"]。 - 意図的な違反が1つだけある場合 → 特定のコードと簡単な理由を添えて
# noqa: <CODE>を指定します。コードを指定しない# noqaは、その行のすべてのルールを隠してしまいます。 # noqaコメント内に Ruff 以外のツールのコード(カスタム Flake8 プラグイン)がある場合 →[tool.ruff.lint]にexternal = ["XX"]を宣言します。そうしないと、次の--fixでRUF100がそれらのコメントを削除します。- 範囲はプレフィックスを1つずつ増やします(
"S"、"PT"、"PTH"、…)。追加するたびにuv run ruff check .を実行し、さらに追加する前に修正するか、対象を限定してください。 - 結果を確認します:
python3 "${CLAUDE_SKILL_DIR}/scripts/check_ruff_config.py" --root .(読み取り専用。E501 の二重報告、ALL、フォーマッターと競合するルール、残存する旧設定、target-versionの欠落を検出します。)
5. Black / Flake8 / isort から移行する
コマンド、設定キー、Flake8 プラグイン→プレフィックスの完全な対応表と、
大規模なレガシーコードベース向けの戦略については、references/migration.md を参照してください。手順は次のとおりです。
- まず設定を変換します。
[tool.black]→[tool.ruff]+[tool.ruff.format]、[tool.isort]/.isort.cfg→[tool.ruff.lint.isort](キーはケバブケース)、.flake8→select/ignore/per-file-ignoresのように変換します。Ruff は[tool.black]や.flake8を読み込まないため、変換されなかった設定は 気付かれないまま失われます。 - プラグインとの互換性を確認します。 使用中の Flake8 プラグインごとに、
Ruff に対応するプレフィックスがあることを確認します(対応表はリファレンスを
参照)。ビジネス上重要なプラグインに同等のものがない場合は、ハイブリッド構成にして、
そのプラグインに限って Flake8 を残し、該当するコードを
external = [...]に追加します。 - 一度限りのクリーンアップを、ゲートを切り替える前に、レビュー対象となる独立したコミットとして実施します。
差分をレビューしてください。大規模なコードベースでは、Ruff のフォーマッターは Black に近いものの、 バイト単位で完全に一致するわけではありません。相違点については docs.astral.sh/ruff/formatter/black/ に記載されています。 大規模なフォーマット変更では、コミットをuv run ruff check . --fix && uv run ruff format ..git-blame-ignore-revsに記録してください。 - 同じ PR で古いツール一式を廃止します:dev 依存関係から black/flake8/isort(およびその
プラグイン)を削除し、
.flake8、.isort.cfg、[tool.black]、[tool.isort]を削除します。2 つのフォーマッターを有効にしたままにすると、 同じ行をめぐって競合します (astral-sh/ruff#1307)。 - 古いツールを呼び出していたものの参照先を変更するようユーザーに伝えます — pre-commit フック
(python-precommit スキル)と CI ジョブ(python-ci スキル)が対象です。次の
コマンドのみを案内してください:
ruff check .およびruff format --check .。
現在の Black+Flake8 の設定が問題なく動作しており、誰にも負担をかけていないなら、 移行しないのも妥当な判断です。変更にはコストがかかります。流行ではなく、 摩擦(速度、設定の肥大化、プラグインの放棄)が生じたときに移行してください。
6. lint / format の失敗を修正する
uv run ruff check . --fix # 1. autofix what's safe
uv run ruff format . # 2. THEN format — fixes can leave code needing reformat
uv run ruff check . # 3. see what's left; --fix exiting clean != zero violations
実行順が重要です。--fix はインポートや内包表記を書き換えるため、その後に再フォーマットが必要になります。
残った問題については、次のように対応します。
- コードを修正します。違反が意図的な場合に限り、抑制を検討し、その場合も最も範囲の狭いものを使います。
具体的な
# noqa: <CODE>> ファイル単位のper-file-ignores> グローバルなignoreの順です。selectからルールを削除して、失敗しているゲートを成功扱いにしてはいけません。 - 動作を変更する可能性があるため、安全ではないものとして意図的に保留されている修正もあります。適用する前に
uv run ruff check . --fix --unsafe-fixes --diffで明示的に確認してください。 - GitHub Actions のログでは、
uv run ruff check . --output-format=githubにより、 PR にファイル/行の注釈が出力されます(ワークフロー YAML 自体は python-ci の担当範囲です)。
7. 完了を確認する
uv run ruff check . && uv run ruff format --check . && echo LINT-OK
python3 "${CLAUDE_SKILL_DIR}/scripts/check_ruff_config.py" --root .
出力仕様
以下をすべて満たした状態を完了とします。
pyproject.tomlに、明示的なselect、フォーマッターの使用中に無視されるE501、および解決済みのtarget-version(またはrequires-python)を含む[tool.ruff]がある。- dev 依存関係で Ruff のバージョンが固定されている(設定で
required-versionを指定するのも任意です)。 uv run ruff check .とuv run ruff format --check .の両方が終了コード 0 で終了する。.flake8/.isort.cfg/[tool.black]/[tool.isort]が残っておらず、 dev 依存関係に black/flake8/isort が含まれていない(文書化されたハイブリッド構成の場合を除く)。- 移行では、機械的なフォーマット変更が独立したコミットに分離されている。抑制には ルールコードと理由が記載されている。
scripts/check_ruff_config.pyがエラー 0 件を報告する。
失敗モードと注意点
| 症状 | 原因 | 対処法 |
|---|---|---|
| Ruff はインストールされているのに検出数が少なすぎる(0.16 より前)、またはアップグレード後に CI で大量のエラーが出る(0.16 以降) | デフォルトのルールセットで実行しているためです。0.16 で E+F から 413 個のルールに変更されました | 明示的に select を記述します(手順 3)。デフォルト設定を置き換えるため、アップグレードによってゲートの基準が変わらなくなります |
| フォーマッターが修正しない E501 違反 | リンターとフォーマッターの両方が行の長さを管理しています | ignore = ["E501"] を指定します。フォーマッターが可能な範囲で折り返します |
| 通常の Ruff アップグレードで突然チェックに失敗する | select = ["ALL"] によって新しいルールが自動的に有効になります | select を明示し、Ruff のバージョンを固定します |
| フォーマッターとリンターが競合する(カンマ、引用符、インデント) | COM812/COM819、Q000–Q004、D203/D206/D300、W191、E111/E114/E117(および ISC001 なしで allow-multiline = false を指定した場合の ISC002)が ruff format と競合します | select から削除するか、ignore に追加します。競合するルール を参照してください |
--fix によって # noqa: XY123 コメントが削除される | RUF100 が不明なコードを未使用の抑制として扱います | [tool.ruff.lint] に external = ["XY"] を指定します |
| 自動修正によって、サポート対象の最も古い Python で動かない構文が出力される | target-version / requires-python がなく、py310 が前提とされます | 実際の最小バージョンを target-version に指定します |
| パスを1つずつ渡すと、除外したファイルもリンターで検査される | ファイルを明示的に指定すると exclude が無視されます(ruff#9585) | 必ず適用するルールには per-file-ignores を使用します。フック層の設定は python-precommit の担当です |
ruff check --fix は正常終了するのに、CI は依然として失敗する | 自動適用されるのは 安全な 修正のみで、それ以外は引き続き報告されます | 通常の check を再実行し、手動で修正するか、--unsafe-fixes --diff を確認します |
| ファイルのフォーマットが何度も切り替わる | Ruff と併せて Black(または IDE の Black プラグイン)がまだ有効です | フォーマッターは1つだけにします。Black を削除し、エディターの設定を更新します |
古い .flake8 / [tool.black] の設定が「機能しなくなった」 | Ruff はそれらを読み込みません | [tool.ruff] に移行してから、元の設定を削除します |
| ローカルでは通るのに、別の環境では失敗する | 開発環境/CI/フック間でバージョンが異なります | どの環境でも同じバージョンに固定します。required-version を指定すると、不一致がハードエラーになります |
| Ruff が YAML/Markdown/TOML もフォーマットすると想定していた | 設計上、Python のみが対象です。0.16 以降は Markdown 内の Python の コードフェンス がデフォルトでフォーマットされます(fmt: off コメントまたは extend-exclude で無効化できます) | Python 以外のフォーマットについては python-precommit スキルを参照してください。Prettier/mdformat の対象範囲を設定し、フェンス内の Python をめぐって Ruff と競合しないようにします |
| Ruff を追加して初めて CI を実行したときに、大きな失敗が起きる | ゲートを設定する前に、ローカルでクリーンアップを実行していません | ローカルで手順 6 を実行してコミットしてから、ゲートを設定します |
ruff check は通るのに、差分を見るとフォーマットされていないように見える | リントとフォーマットは別の処理です。check はフォーマットを検証しません | 必ず両方のゲートを実行します(手順 7) |
同梱リソース
references/rule-selection.md— ルールプレフィックスと由来の対応表、段階的な導入戦略、selectとextend-selectとALLのトレードオフ、per-file-ignore の規約、isort/pydocstyle/bugbear のサブテーブル、修正の安全性に関する設定。references/migration.md— 旧コマンドから Ruff への対応、Black/isort/Flake8 の設定キーの移行、Flake8 プラグインとプレフィックスの対応表、カスタムプラグインとの併用、大規模なレガシーコードベースへの段階的な導入。scripts/check_ruff_config.py— 読み取り専用の設定チェックツール。問題が見つかるとゼロ以外の終了コードを返します。python3 "${CLAUDE_SKILL_DIR}/scripts/check_ruff_config.py" --root <repo>を実行します(警告でも失敗させるには--strictを指定します)。