コードフォーマッター「black」を使ってPythonのコードの整形で悩むのをやめる
Pythonにもblackというgofmtみたいなコードフォーマッターがあった
Goを書いていると、gofmtコマンドを叩くとインデントやTrailing whitespaceなどを勝手に直してファイルを書き換えてくれる。
わたしがPythonを使ってきてGoを覚え始めたときにこれは便利だなぁと思った。
知らなかったことだが、最近はPythonにもblackというコードフォーマッターがあるらしい。
これを使うと以下のようなPythonのプログラムを勝手に整形してくれる。
[before]
from pathlib import Path def main(): path = Path(__file__).parent.joinpath("foo", 'bar', "baz_1234567890123456789012345678901234567890123456789012345678901234567890") print(path) # ここにプリントされる if __name__ == '__main__': main()
[after]
from pathlib import Path def main(): path = Path(__file__).parent.joinpath( "foo", "bar", "baz_1234567890123456789012345678901234567890123456789012345678901234567890", ) print(path) # ここにプリントされる if __name__ == "__main__": main()
具体的に何を整形してくれたかというと、
- トップレベルの空行は1行ではなく2行のルールなので、1行しか空けていないところを2行に増やした
- ラインコメントの"#"の前は半角スペースを二つ空けるルールなので、ひとつだったのを二つに増やした
- main()関数のコロンの後ろに存在した半角スペース(=Trailing whitespace)を消した
- シングルクォートで囲んだ文字列をダブルクォートで囲むよう変えた
- 1行が88文字に(なぜ79文字でないのかは後述)収まらない箇所を適宜改行した
- 改行区切りで関数の引数を記述する際、ケツカンマをつけた
だいたいこんな感じ。
もうpep8だのpyflakesだのflake8なんてものをいちいち叩いて自分でコードを整形する必要がなくなったのだ。
blackは1行の文字数を88文字にする慣わしらしい
pep8だと1行の文字数は79文字以内と決まっているので、flake8もこれに合わせて79文字以内かどうかチェックする。
ただし、文字数は設定で変更できるようになっている。
blackは88文字がちょうどいいとblackを作った人たちが思っているらしく、88文字以内に収まるようコードを整形する。
それが嫌な場合は.flake8に設定を書いて対処するようblackのREADMEに書いてある。
blackをインストールするときのハマりポイント
poetryで入れるときは allow-prerelease オプションをつけないと(今のところ)ダメだった
poetryを使ってblackを入れようと以下のコマンドを叩いたらエラーになった。
$ poetry add black [ValueError] Could not find a matching version of package black add [-D|--dev] [--git GIT] [--path PATH] [-E|--extras EXTRAS] [--optional] [--python PYTHON] [--platform PLATFORM] [--allow-prereleases] [--dry-run] [--] <name> (<name>)...
これは最初意味がわからずググったら以下のスレッドが見つかって、 --allow-prerelease というオプションをつけないとダメらしい。
Can not install black · Issue #649 · sdispater/poetry · GitHub
オプションをつけたら今度はうまくいった。
$ poetry add black --allow-prereleases Using version ^18.3-alpha.0 for black Updating dependencies Resolving dependencies... (1.9s) Writing lock file Package operations: 0 installs, 1 update, 0 removals - Updating black (19.3b0 -> 18.9b0) root@1d215d0967e6:/code# poetry lock Updating dependencies Resolving dependencies... (0.1s)
ちなみにpyproject.tomlを見ると以下のように「allows-prereleases = true」という記載が付いていることがわかる。
black = {version = "^18.3-alpha.0", allows-prereleases = true}
正式リリースされたらこんなオプションをつけなくても良くなるのだろう。
サンプルコード
サンプルコードはここに置いておきました。
https://github.com/oyakata/pythooooon/tree/master/blaccccck
なお、GoよりもPythonの方が実行環境作るの面倒臭いので、一応実行方法をここに書いておきます。
(dockerが入っている環境で動かしてください)
$ git clone git@github.com:oyakata/pythooooon.git $ cd pythooooon/blaccccck $ make black
Dockerfileとかdocker-compose.ymlでコンテナ立ち上げたり、コンテナの中でpoetry叩くコマンドを覚えるのも面倒なので、Makefileに手順を書いておきました。
最後までお読みくださりありとうございました。