0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

一人アドベントカレンダー!主にPythonに関して投稿します。Advent Calendar 2024

Day 2

Python開発: コード品質を一歩前進させるpre-commit導入のすゝめ

Last updated at Posted at 2024-12-01

はじめに

Pythonの開発現場でコード品質を保つために、一貫したコードスタイル簡単なコードチェックを自動化することは欠かせません。
pre-commitは、その自動化を強力にサポートしてくれるツールです。このツールを使えば、コミット前にコードをチェックし、自動でフォーマットやスタイルを統一できます。

今回はpre-commitを導入して、Pythonコードの品質管理を行う手順について解説します。
併せて、コード整形ツールblackisort、静的解析ツール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を通じて使用するツールやその設定を管理します。
以下の例では、コード整形ツールblackisort、静的解析ツールflake8を設定しています。

.pre-commit-config.yaml
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を導入してみてください!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?