はじめに
Pythonの開発現場でコード品質を保つために、一貫したコードスタイルや簡単なコードチェックを自動化することは欠かせません。
pre-commit
は、その自動化を強力にサポートしてくれるツールです。このツールを使えば、コミット前にコードをチェックし、自動でフォーマットやスタイルを統一できます。
今回はpre-commitを導入して、Pythonコードの品質管理を行う手順について解説します。
併せて、コード整形ツールblack
やisort
、静的解析ツールflake8
を使った一連の設定手順も紹介します。
pre-commitを導入している例として有名なWebフレームワークDjangoもpre-commitを導入しているようです。
pre-commitの導入手順
1. インストール
まずはPythonの環境を使用しpre-commit
をインストールします。
pip install pre-commit
2. .pre-commit-config.yaml
をリポジトリ直下に作成
pre-commit
は、設定ファイル.pre-commit-config.yaml
を通じて使用するツールやその設定を管理します。
以下の例では、コード整形ツールblack
、isort
、静的解析ツールflake8
を設定しています。
repos:
- repo: https://github.com/psf/black
rev: 24.10.0
hooks:
- id: black
- repo: https://github.com/pycqa/flake8
rev: 7.1.1
hooks:
- id: flake8
args:
- "--max-line-length=88"
- "--ignore=E203,W503"
- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
- id: isort
3. pre-commit
設定ファイルを作成したら、pre-commit
をリポジトリにインストールします。
pre-commit install
成功すると以下のようなメッセージが表示されます。
pre-commit installed at .git/hooks/pre-commit
実際にpre-commitを実行してみる
今回pre-commitの動作確認として以下のコードを作成してみました。
pre-commitを実際に実行するにはpre-commit install
を完了後、対象ファイルをGitのコミットするだけで実行してくれます。
コミットではなくコマンドから実行する場合はpre-commit run --files ファイル名
で実行可能です。
修正が必要なコードの例
以下のコードにはいくつかの問題点があります
- importが標準ライブラリと外部ライブラリ、自作モジュールで分かれていない
- importと実装コードとの改行がない
- シングルクォート(')とダブルクォート(")の統一されていない
- 使用していない不要なimport文がある
- 使用していない変数がある
import os # 標準ライブラリ
from my_module.module import SampleClass # 自作モジュール
from my_util.util import sample_method # 自作モジュール
from playwright.async_api import async_playwright # サードパーティ
import re # 標準ライブラリ
def sample(id:int, last_name: str,first_name: str,email: str, password: str, age: int, friends: list) -> None:
sample_method()
sample_data = {"sample_a": "test_a","sample_b": "test_b","sample_c": "test_c",
'sample_d': 'test_d',
'sample_e': 'test_e',
'sample_f': 'test_f',
'sample_g': 'test_g',
}
print("サンプルコード")
pre-commit適用後の結果
pre-commit
実行後、コードは次のように修正されます
import os # 標準ライブラリ
import re # 標準ライブラリ
from playwright.async_api import async_playwright # サードパーティ
from my_module.module import SampleClass # 自作モジュール
from my_util.util import sample_method # 自作モジュール
def sample(
id: int,
last_name: str,
first_name: str,
email: str,
password: str,
age: int,
friends: list,
) -> None:
sample_method()
sample_data = {
"sample_a": "test_a",
"sample_b": "test_b",
"sample_c": "test_c",
"sample_d": "test_d",
"sample_e": "test_e",
"sample_f": "test_f",
"sample_g": "test_g",
}
print("サンプルコード")
isortでimport文の順番が整頓され、blackでコードが綺麗に整形してくれます。
flake8では使用していないimport文や使用されていない変数などのエラー箇所を指摘します。
これにより、コミット時に間違ったコードが混入するリスクを軽減できます。
(venv) MacBook-Air pre-commit-sample % git commit -m "pre-commit test"
black....................................................................Failed
- hook id: black
- files were modified by this hook
reformatted sample.py
All done! ✨ 🍰 ✨
1 file reformatted.
flake8...................................................................Failed
- hook id: flake8
- exit code: 1
sample.py:1:1: F401 'os' imported but unused
sample.py:2:1: F401 'my_module.module.SampleClass' imported but unused
sample.py:4:1: F401 'playwright.async_api.async_playwright' imported but unused
sample.py:5:1: F401 're' imported but unused
sample.py:19:5: F841 local variable 'sample_data' is assigned to but never used
isort....................................................................Failed
- hook id: isort
- files were modified by this hook
Fixing /Users/name/Desktop/Qiita記事/pre-commit-sample/sample.py
pre-commitでチェックをスキップしたい箇所がある場合
時々pre-commitのチェックを避けたい箇所があります。
その時は# noqa: エラーコード
のコメントを入れるとチェックを避けることができます。
以下は使用していない不要なimportがあるときのF401
のエラーコードのチェックをスキップするケースです。
import os # noqa: F401
まとめ
pre-commitを活用することでコードの一貫性が向上しチーム全体で同じスタイルを維持できたり、レビューやバグ修正のコストを削減できることでしょう。
Pythonプロジェクトで手軽に品質管理を始めたい方は、ぜひpre-commitを導入してみてください!