はじめに
Django プロジェクトで flake8 を回実行したところ、設定ファイルまわりで E501 のエラーが出ました。
flake8 .
./config/settings/base.py:79:80: E501 line too long (91 > 79 characters)
./config/settings/base.py:82:80: E501 line too long (81 > 79 characters)
./config/settings/base.py:85:80: E501 line too long (82 > 79 characters)
./config/settings/base.py:88:80: E501 line too long (83 > 79 characters)
行を 2 行に分けて回避しようとしても、自動整形ツール(black)が 1 行に戻してしまう 状態になり、
「flake8 的にはアウトだけど、black が直してくる」という板挟みになりました。
この記事では、
- なぜ 2 行にしても 1 行に戻されるのか
- flake8 と black の「行長ルールのズレ」
- どうやって設定を揃えたか
をまとめます。
問題
問題になっていたコードは、Django のパスワードバリデータ設定部分でした。
"NAME": "django.contrib.auth.password_validation." "MinimumLengthValidator",
本当は flake8 の E501 を避けるために、こんな感じで 2 行 にしたいイメージでした。
"NAME": "django.contrib.auth.password_validation."
"MinimumLengthValidator",
しかし実際には、
- エディタで 2 行に分けても
- black(自動整形)を走らせると
"NAME": "django.contrib.auth.password_validation." "MinimumLengthValidator",
のように 1 行に戻されてしまう という状態になっていました。
その結果、
- black「この長さなら 1 行で書けるじゃん!」→ 1 行に整形
- flake8「79文字超えてるからダメ!」→ E501 発生
という ツール同士の方針の違いで怒られる ことになっていました。
原因
この現象の原因は、flake8 と black の「許容する行の長さ」が違う ことでした。
行長ルールの違い
-
flake8 のデフォルト
→max-line-length = 79(79文字まで) -
black のデフォルト
→line-length = 88(88文字までOK)
つまり、今回のケースでは:
- 該当行の長さが 79文字は超えているが、88文字以内
- black 的には「1行でOK」
- flake8 的には「長すぎるからNG」
というズレが発生していました。
その結果:
- black が「1 行で書ける」と判断して 1 行にまとめる
- flake8 が「E501 line too long」と怒る
という、永遠に終わらないケンカ が起きていました。
解決策
今回とった解決策は
flake8 側の行長ルールを black に合わせる
という方法です。
1. .flake8 を作成/修正して max-line-length を変更
プロジェクトルートに .flake8 を作成し、以下のように設定します。
[flake8]
max-line-length = 88
extend-ignore = E203
exclude = .git,__pycache__,venv,*/migrations/*
3つの設定値の解説。
max-line-length = 88
max-line-length = 88
- black のデフォルト行長が 88文字 なので、
- flake8 も 88文字までは許容する ように揃えます。
これで、
- black が 1 行にまとめる
- かつ 88 文字以内なら
- flake8 も E501 を出さない
という状態になり、両者の方針が一致します。
extend-ignore = E203 とは?
extend-ignore = E203
これは、
「E203 だけは flake8 に無視してもらう」
という設定です。
E203 は、例えばスライスのときのスペースなどに対するルールで、
my_list[1 : 3]
のような コロンの前のスペース でのエラーを回避するためです。
一方で black はこのスタイルを採用することがある ため、
- black「こう整形するよ!」
- flake8「E203的にダメです!」
とまたケンカしがちです。
そこで extend-ignore = E203 としておくことで、
そこは black に従うから、flake8 は文句言わなくてOK!
という状態にしておきます。
exclude = .git,pycache,venv,/migrations/ とは?
exclude = .git,__pycache__,venv,*/migrations/*
これは、
「このパス配下は flake8 のチェック対象から外してください」
という除外設定です。
-
.git
→ Git の履歴フォルダ。コードチェック不要。 -
__pycache__
→ Python のキャッシュ。自動生成物なので無視してOK。 -
venv
→ 仮想環境。外部ライブラリのコードなのでチェックしない。 -
*/migrations/*
→ Django のマイグレーションファイル。
自動生成や履歴の意味が強く、スタイルより「動くこと」が重要なので、
チェック対象から外す運用が一般的。
さいごに
今回のポイントをまとめると:
-
flake8 と black で「許容行長」が違うと、同じコードでも評価がズレる
-
デフォルト値は
- flake8:79文字
- black:88文字
-
そのまま使うと
- black が 1 行に整形
- flake8 が E501 で怒る
-
.flake8でmax-line-length = 88にして、black に合わせるとケンカが止まる -
ついでに
extend-ignore = E203やexclude = ...も設定しておくと、
「人が書くべきコード」だけ、気持ちよく flake8 でチェックできる
ということがわかりました。