はじめに
枕木の歌、いいよね... nikkieです。
flake8を触っていての気づきを書いていきます。
目次
相互に排他的な W503 と W504
静的解析ツールflake8。
PEP 8(Pythonコードのスタイルガイド)に沿っているかもチェックしてくれます。
PEP 8関連のワーニングの中に今回取り上げたいものがあります
まずは、W503!
二項演算子の後で改行しているのをよしとし、前で改行している場合はその旨を指摘します。
以下は二項演算子+
の後で改行しているのでW503的には問題なし
income = (gross_wages + taxable_interest)
続いて、W504!
二項演算子の前で改行しているのをよしとし、後で改行している場合はその旨を指摘します。
以下は二項演算子+
の前で改行しているのでW504的には問題なし
income = (gross_wages + taxable_interest)
この2つ、絶対に両立しないですね(=相互に排他的)
2つある経緯は、PEP 8の変更
PEP 8に二項演算子と改行に関する箇所があります。
https://peps.python.org/pep-0008/#should-a-line-break-before-or-after-a-binary-operator
PEP 8自体は2001年に作られたドキュメントですが、なんとこの箇所の記載は変わったようなのです!
Guido-san「PEPを変えよう!」1
(この意思決定に至った経緯はメーリングリストを追ってみたい気持ちです)
PEP 8を変えても、二項演算子の後で改行がよいとされた15年程度の期間に書かれたコードは残っています。
PEP 8はそれを排除しようとせずに、新しいコードは二項演算子の前で改行するのを勧めています2。
二項演算子の後で改行しているコードも許容しているのがいいなと思います3。
In Python code, it is permissible to break before or after a binary operator, as long as the convention is consistent locally.
大事なのは、スタイルに一貫性があること!(consistent)
顕在化するのは、--ignoreオプションと使った時
flake8は3つのライブラリをラップしており、PEP 8のチェックはpycodestyleが担っています。
ドキュメント Introductionの「Error codes」より
https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes
- W503とW504はデフォルトの設定では無視されます4
--ignore=errors
と指定すると、デフォルトの設定が上書きされます5- W503やW504を
--ignore
オプションで指定しなければ無視されなくなります
- W503やW504を
検証していきます
- Python 3.11.8
pip install flake8
- flake8 7.0.0
- pycodestyle 2.11.1
# W503を満たすが、W504に違反 income = (gross_wages + taxable_interest) # W504を満たすが、W503に違反 income = (gross_wages + taxable_interest)
--ignore
を指定せずデフォルトの設定を使うと、エラーは検出されません。
% pycodestyle script.py % echo $? 0
--ignore
を指定すると
% pycodestyle --ignore=E401 script.py script.py:2:23: W504 line break after binary operator script.py:7:11: W503 line break before binary operator % echo $? 1
検出され、コマンドとしては異常終了しました
また、flake8ではヘルプメッセージに記載されています6。
--ignore errors Comma-separated list of error codes to ignore (or skip). For example, ``--ignore=E4,E51,W234``. (Default: E121,E123,E126,E226,E24,E704,W503,W504)
ここから、pycodestyle(やflake8)で--ignore
を指定するときは、デフォルトのignore設定の上書きになることに注意し、W503かW504(か両方)を指定する必要があると理解しました。
終わりに
flake8(pycodestyle)に相互に排他的なルール(W503・W504)を見つけ、気になって調べました。
- PEP 8の二項演算子と改行のスタイルガイドは更新された
- W503もW504もデフォルトでは無視されているが、ignoreオプションの指定で上書きしてしまう
- IMO:新しいコードを書く場合は、おすすめされなくなったW503もignoreに指定しよう
本エントリの元ネタです
flake8、矛盾するルールがあるのかwhttps://t.co/4yEE0oTIyY
— nikkie / にっきー (@ftnext) 2024年3月31日
PEP 8が変わったっぽくW504がPEP8準拠。
二項演算子の**前**で改行https://t.co/MxQO1F97U0
W504に合わせたらW503(後で改行)で怒られたので無視が必要なんだな〜
P.S. Ruffでは?
エントリ執筆時点では、W503もW504も実装されていません。
https://docs.astral.sh/ruff/rules/#warning-w
pycodestyleがデフォルトで無視しているルールというのが実装していない理由とのことです7。
https://github.com/astral-sh/ruff/issues/4125#issuecomment-1524657579
- メールは Update handling of breaking around binary operators: W503 vs W504 · Issue #498 · PyCQA/pycodestyle · GitHub で知りました↩
- 「For new code Knuth’s style is suggested.」(PEP 8より)↩
- setup.pyとpyproject.tomlっぽいと思いました。↩
- 原文「(*) In the default configuration, the checks E121, E123, E126, E133, E226, E241, E242, E704, W503, W504 and W505 are ignored」↩
-
原文「Please note that if the option
--ignore=errors
is used, the default configuration will be overridden and ignore only the check(s) you skip.」↩ -
代わりに
--extend-ignore
を指定すると、これはデフォルトのignoreに追加するようです↩ - Ruffは速いのですが、未実装のルールがあるなど、完全互換ではないのですね(違いの認識が必要そう)↩