閉じる

【初心者向け】Python×pre-commitの使い方とおすすめフック集

Pythonでの開発を始めると、コードスタイルのバラつきやうっかりミスによるバグ、テスト漏れなどが気になり始めます。

そこで役立つのが「pre-commit」という仕組みです。

この記事では、Python初心者でも導入できるように、pre-commitの基礎からインストール方法、おすすめフック集、チーム開発での活用、さらにCI連携までを段階的に解説します。

Python開発にpre-commitを導入するメリット

pre-commitとは何か

pre-commitとは、Gitのcommit時に自動で実行されるチェックや整形処理をまとめて管理するフレームワークです。

Gitにはもともと「フック(hook)」と呼ばれる仕組みがあり、コミット前(pre-commit)など特定のタイミングでスクリプトを実行できますが、素のGitフックは管理が大変で、プロジェクトごとにスクリプトを配布するのも面倒です。

pre-commitは、このGitフックを扱いやすくするために作られており、以下のような特徴があります。

  • 設定ファイル(.pre-commit-config.yaml)でフックを一元管理できる
  • BlackやFlake8、isort、mypyなど既存の有名ツールを簡単に連携できる
  • コミットするファイルだけに処理をかけるため、実行が高速
  • 設定をリポジトリにコミットするだけでチーム全員同じルールを共有できる

つまり「コミット前にうっかりミスを自動で防いでくれる守護神」のような存在だと考えてください。

Python初心者こそpre-commitを使うべき理由

Python初心者の段階では、コーディング規約やベストプラクティスをすべて覚えるのは難しいです。

そこでpre-commitを導入しておくと、ツールがリアルタイムに「ここは直した方がいいよ」と教えてくれる環境を作れます。

具体的には、次のようなメリットがあります。

初心者が迷いやすい「どこまで気にすべきか」という境界を、ツールが自動でライン引きしてくれるため、最初から“そこそこ良い品質”のコードを書く習慣が身につきます。

レビューでも「スタイルの指摘」より「設計やロジックの議論」に時間を使えるようになり、成長スピードが上がります。

チーム開発でのpre-commit活用メリット

チーム開発では、開発者ごとにコードの書き方やフォーマットがバラバラだと、次第にレビューが「ルール確認作業」と化してしまいます。

pre-commitを導入しておけば、リポジトリにコミットされた.pre-commit-config.yamlを全員が共有することで、「機械がチェックできる部分」はすべてツールに任せることができます。

この結果、次のような効果が得られます。

  • コードスタイルの統一により、どのファイルを開いても読みやすくなる
  • レビューコメントから「スペース1個足りない」「import順が違う」といった指摘が減る
  • テストや静的解析をコミット前に実施することで、CIの失敗率が下がる
  • プロジェクトに新しく参加する人も、設定ファイルを引き継ぐだけで同じ品質基準をすぐ適用できる

このように、pre-commitは個人開発だけでなく、チーム開発の品質や生産性を底上げする重要な仕組みです。

Pythonプロジェクトへのpre-commit導入手順

前提環境

pre-commitを使うためには、まず以下の環境が整っている必要があります。

  • Gitがインストールされていること
  • Python環境があること(概ねPython 3.8以上推奨)
  • すでにGitリポジトリ(git init済み)になっているプロジェクトであること

次のようにバージョン確認をしておくと安心です。

Shell
git --version
python --version

特にチーム開発では、Pythonバージョンをpyenvvenvなどで揃えておくと、pre-commitの動作も安定します。

pre-commitのインストール方法

pre-commit自体はPython製のツールなので、通常はpipでインストールします。

グローバルインストールの例

Shell
pip install pre-commit

プロジェクトの仮想環境で使う場合

プロジェクトごとに仮想環境を切っている場合は、仮想環境をアクティベートしたうえでインストールします。

Shell
# 仮想環境の作成
python -m venv .venv

# 仮想環境の有効化(Windows PowerShell)
.venv\Scripts\Activate.ps1

# 仮想環境の有効化(macOS / Linux)
source .venv/bin/activate

# 仮想環境内にインストール
pip install pre-commit

プロジェクトの依存として管理したい場合はrequirements.txtpyproject.tomlにpre-commitを追加しておくと、環境構築時に自動でセットアップできるので便利です。

.pre-commit-config.yamlの基本構成

pre-commitの動作は、プロジェクト直下に置く.pre-commit-config.yamlという設定ファイルで定義します。

最小限のサンプルは次のような形です。

YAML
# .pre-commit-config.yaml の最小サンプル
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks  # フックを提供するリポジトリのURL
    rev: v4.6.0                                           # 使用するバージョン(タグやコミットハッシュ)
    hooks:
      - id: trailing-whitespace                           # 末尾の空白を削除するフック
      - id: end-of-file-fixer                             # ファイル末尾の改行を調整するフック

構成要素を整理すると、以下のようになります。

項目役割
repos利用するフック群のリポジトリ一覧を定義するトップレベルキー
repoフックを配布しているGitリポジトリのURL
rev使用するタグまたはコミットハッシュ(バージョン固定)
hooks実際に有効化するフック群の一覧
id各フックに定義されたユニークなID

「どのリポジトリの、どのバージョンから、どのフックを使うか」をYAMLで宣言していくイメージです。

git hookへのpre-commit登録方法

設定ファイルを作成しただけでは、まだGitのフックとしては連携されていません。

次のコマンドで、Gitの.git/hooks/pre-commitに、pre-commitを呼び出すスクリプトを自動配置します。

Shell
pre-commit install

このコマンドを実行すると、以降はgit commitのたびに登録済みのフックが自動実行されます。

フックを無効化したい時は、次のようにアンインストールも可能です。

Shell
pre-commit uninstall

プロジェクトに参加した人は、初回だけpre-commit installを実行する必要がある点に注意してください。

pre-commitの動作確認とよくあるエラー

設定が正しく動いているか確認するために、次のコマンドで全ファイルに対してフックを試しに動かしてみます。

Shell
pre-commit run --all-files

サンプルプロジェクトでの動作例(CLI出力)

Shell
$ pre-commit run --all-files
Trim Trailing Whitespace.............................Passed
Fix End of Files.....................................Passed

フックが何も問題を検出しなければPassedと表示され、問題があればFailedとなり、コミット時も同様に失敗します。

よくあるエラーと対処法

1つ目に多いのは、フックが指定するコマンドを実行するための依存ツールが不足しているケースです。

例えばblackを使うフックを追加したのに、環境にblackが存在しない場合、次のようなエラーになります。

An error has occurred: FatalError: [Errno 2] No such file or directory: 'black'

多くの公式フックは専用の仮想環境をpre-commit側が自動構築するため、この種のエラーは少ないですが、自作フックやlanguage: system指定のフックでは発生しやすいです。

その場合は、必要なツールをグローバルまたはプロジェクトの仮想環境にインストールしてください。

他にありがちなのは、YAML構文エラーです。

タブ文字が混じっていたりインデントがずれると、次のようなエラーになります。

ERROR: Invalid config: while parsing a block mapping
  in ".pre-commit-config.yaml", line 3, column 3

YAMLはインデントとスペースに厳格なので、空白はスペース2つや4つで統一し、タブは使わないようにしましょう。

Python初心者におすすめのpre-commitフック集

コード整形系フック

コード整形系フックは、ソースコードの見た目を自動で統一してくれるフックです。

Python界隈では特にBlackがデファクトスタンダードになりつつあります。

Black(コードフォーマッタ)

YAML
repos:
  - repo: https://github.com/psf/black
    rev: 24.4.2           # 使いたいバージョンに合わせて調整
    hooks:
      - id: black
        language_version: python3

Blackは「妥協なき自動整形」を掲げるフォーマッタで、人間が細かいスタイルを悩む必要がなくなります。

コミット前にBlackが走ることで、レビュー時にフォーマットの指摘をほぼゼロにできます。

isort(import順の自動整列)

YAML
repos:
  - repo: https://github.com/pycqa/isort
    rev: 5.13.2
    hooks:
      - id: isort
        name: isort (python)

import文の順序は、手作業で整えるとミスが起きがちです。

isortは標準ライブラリ→サードパーティ→ローカルモジュールの順のようなルールに従って、自動で並び替えてくれます。

Blackとセットで導入されることが多く、Blackとisortのスタイルを合わせるための設定も用意されています。

静的解析系フック

静的解析系フックは、コードを実行せずに潜在的なバグやアンチパターンを検出してくれます。

Flake8(静的解析とスタイルチェック)

YAML
repos:
  - repo: https://github.com/pycqa/flake8
    rev: 7.1.0
    hooks:
      - id: flake8
        additional_dependencies:
          - flake8-bugbear        # 追加のバグ検出ルール

Flake8は、PEP8準拠のスタイルチェックと簡易的な静的解析を行います。

例えば未使用変数や未使用import、不要な比較などを検出できます。

初心者にとっては、「この書き方はよくない」というフィードバックを随時もらえる先生のような存在になります。

mypy(型チェック)

YAML
repos:
  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: v1.13.0
    hooks:
      - id: mypy
        additional_dependencies:
          - types-requests

mypyは型ヒント(typing)を用いて、関数の引数や戻り値の整合性などを検証するツールです。

最初から厳しく適用するのは大変な場合もありますが、型を少しずつ整えていくことで、関数の使い方ミスなどを早めに検出できます。

セキュリティチェック系フック

セキュリティ系フックは、パスワードやAPIキーの誤コミットなど重大な事故を防ぐのに役立ちます。

detect-secrets(シークレット検出)

YAML
repos:
  - repo: https://github.com/Yelp/detect-secrets
    rev: v1.5.0
    hooks:
      - id: detect-secrets

このフックは、コミットされようとしているファイルから、パスワード・トークン・秘密鍵のような文字列を検出します。

誤ってAWSキーやデータベースのパスワードをGitHubに公開してしまう事故は後を絶ちませんが、detect-secretsを入れておけば多くの事故を事前に防げます

bandit(Pythonコードの脆弱性チェック)

YAML
repos:
  - repo: https://github.com/PyCQA/bandit
    rev: 1.7.10
    hooks:
      - id: bandit
        args: ["-ll"]   # ログレベル(詳細度)を上げる

banditは、Pythonコード内に潜むセキュリティ上の問題(危険な関数の使用、不適切な乱数生成など)を検出します。

WebアプリケーションやAPIサーバーなど、外部とやり取りするコードでは特に導入を検討すると良いです。

フォーマット・品質系フック

ここでは、フォーマットやファイル品質を保つための軽量なフックを紹介します。

どの言語のプロジェクトでも使われることが多く、Pythonプロジェクトにもそのまま導入できます。

pre-commit-hooks公式パッケージ

YAML
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.6.0
    hooks:
      - id: trailing-whitespace      # 行末の余計なスペースを削除
      - id: end-of-file-fixer        # ファイル末尾に改行を1つだけ残す
      - id: check-yaml               # YAMLファイルの構文チェック
      - id: check-added-large-files  # 巨大なファイルの誤コミットを防止
      - id: check-merge-conflict     # マージコンフリクトの印を残したままのコミットを防ぐ

これらは非常に軽量で、導入コストがほぼゼロなわりに効果が大きいフックです。

特にtrailing-whitespaceend-of-file-fixerは、ほとんどのプロジェクトで標準装備のように使われています。

コミットメッセージ関連フック

コミットメッセージにもルールを適用することで、履歴が読みやすくなります。

例えばConventional Commits規約を適用したい場合は、次のようなフックが利用できます。

commitlint風のチェック(例)

Conventional Commits向けにはcommitizencommitlintなどのエコシステムがありますが、pre-commit連携にはcommitizenを使う例が比較的シンプルです。

YAML
repos:
  - repo: https://github.com/commitizen-tools/commitizen
    rev: v3.27.0
    hooks:
      - id: commitizen
        stages: [commit-msg]   # コミットメッセージフックとして動作

これはgit commit時にコミットメッセージが規約を満たしているか確認し、不適切なメッセージの場合はコミットを失敗させてくれます。

履歴をきれいに保ちたいチームや、後から自動リリースツールを導入したいチームに向いています。

Pythonプロジェクト向けのおすすめフック構成例

ここまで紹介したフックを組み合わせて、Python初心者〜小規模チームで使いやすい構成例を示します。

YAML
# .pre-commit-config.yaml の例: Pythonプロジェクト向け基本セット
repos:
  # 軽量な共通フック群
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.6.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
      - id: check-merge-conflict

  # import整列
  - repo: https://github.com/pycqa/isort
    rev: 5.13.2
    hooks:
      - id: isort

  # コードフォーマット
  - repo: https://github.com/psf/black
    rev: 24.4.2
    hooks:
      - id: black

  # 静的解析
  - repo: https://github.com/pycqa/flake8
    rev: 7.1.0
    hooks:
      - id: flake8

  # セキュリティチェック(軽めのセット)
  - repo: https://github.com/Yelp/detect-secrets
    rev: v1.5.0
    hooks:
      - id: detect-secrets

この構成だけでも、フォーマット・スタイル・軽い静的解析・簡易セキュリティチェックまで自動化できます。

必要に応じてmypyやbandit、コミットメッセージチェックなどを追加していくと良いでしょう。

pre-commitフックの運用とカスタマイズ

pre-commitフックの追加・削除・バージョン固定

pre-commitの設定を更新するには、基本的に.pre-commit-config.yamlを編集するだけです。

フックの追加・削除

  • 新しく使いたいフックがある場合: 対応するrepo/rev/idのブロックを追記します。
  • 不要になったフック: 対象の- id: ...行(またはそのブロック)を削除します。

設定を変更したら、以下のコマンドでpre-commitの内部環境を更新します。

Shell
pre-commit autoupdate   # revを最新安定版に自動更新(利用は任意)
pre-commit install      # 念のためフックを再インストール

バージョン固定の考え方

revで具体的なタグを指定するのは非常に重要です。

rev: stablerev: masterのように可変な参照を使うと、開発者ごとに使っているバージョンが変わってしまい、コミットのたびにフォーマットが揺れたり、チェック内容が違ったりします。

チーム開発では「常に数値付きのタグを指定する」運用を強くおすすめします。

pre-commit runでの手動実行と自動修正

フックの多くは自動修正(auto-fix)機能を備えており、コミット時に問題を検出すると、その場でファイルを修正してくれます。

ただし、フックの種類によって挙動が異なるため、以下のように手動実行を使い分けると便利です。

すべてのフックを全ファイルに対して実行する

Shell
pre-commit run --all-files

開発環境を初期構築した直後や、設定を大きく変えた時には、このコマンドで一掃することが多いです。

特定のフックだけを実行する

Shell
pre-commit run black --all-files

Blackだけを全ファイルに適用したい場合など、フック名を指定して実行できます。

失敗した時の挙動のイメージ

例えば、Blackによる整形が必要なコードを書いてコミットしようとすると、出力は次のようになります。

Shell
$ git commit -m "add sample"
black.................................................Failed
- hook id: black
- files were modified by this hook

reformatted sample.py

1 file reformatted.

この場合、Blackがsample.pyを自動修正したため、コミットは中断されます。

修正された差分を確認し、必要なら追加の変更を行ってから、再度git commitを実行します。

開発フローに合ったpre-commitルールのチューニング

pre-commitのルールは、厳しければ良いというものではありません

あまりに多くのフックを入れすぎると、コミットに時間がかかりすぎたり、常にエラーだらけでストレスになったりします。

運用上のコツとして、次のようなステップでチューニングしていくと良いです。

  1. まずは軽量で有益なもの(Black、isort、pre-commit-hooks)だけ入れる
  2. プロジェクトが育ってきたらFlake8やmypy、セキュリティ系を段階的に追加する
  3. 開発者から「これは厳しすぎてつらい」という声が出たルールは、argsexcludeで緩和したり一部ファイルを除外する
  4. 定期的に設定を見直し、プロジェクトのフェーズに合ったルールに調整する

例えばFlake8では、特定のエラーコードを無視するためにargsを指定できます。

YAML
- id: flake8
  args: ["--ignore=E203,W503"]

このように、ツール側のオプションも活用しながら、負担になりすぎない範囲で质量を高めていくことが大切です。

CI環境(GitHub Actionsなど)へのpre-commit統合方法

ローカルだけでpre-commitを使っていると、開発者がpre-commit installし忘れる場合や、CIでは別のチェックが走っているといった不整合が起きることがあります。

そこで、GitHub ActionsなどのCI上でもpre-commitを実行し、プルリクエスト時に同じチェックを走らせるのがおすすめです。

GitHub Actionsの設定例

リポジトリの.github/workflows/pre-commit.ymlに、次のようなワークフローを追加します。

YAML
name: pre-commit

on:
  pull_request:
  push:
    branches: [ main, master ]

jobs:
  pre-commit:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"

      - name: Install pre-commit
        run: |
          pip install pre-commit
          pre-commit install

      - name: Run pre-commit
        run: pre-commit run --all-files

この設定により、プルリクエストやmainブランチへのpush時に、pre-commit run --all-filesが自動で実行されます。

ローカルでpre-commitを使っていない開発者がいても、CI上で必ず同じルールでチェックされるため、品質のばらつきを抑えられます。

まとめ

pre-commitは、Python初心者からチーム開発まで幅広く活用できるコミット前自動チェックの標準ツールです。

Blackやisortによるコード整形、Flake8やmypyによる静的解析、detect-secretsやbanditによるセキュリティチェックなどを、.pre-commit-config.yamlにまとめて管理できます。

導入手順は「インストール→設定ファイル作成→pre-commit install」というシンプルな流れで、最初は基本的なフックだけを入れ、プロジェクトの成長に応じて少しずつルールを強化していくのが現実的です。

CI環境とも連携すれば、ローカルと同じチェックをPR時にも自動で走らせることができ、結果として「見るべきところ」に集中したレビューと安定した品質を実現できます。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!