watchdogとblackでpythonの自動フォーマットをする

はじめに

pythonソースコードををセーブ時に自動でフォーマットする方法はいくつかあると思う. VScodeであればformatOnSaveを設定すればいいし,PycharmであればFile Watcherを使えばいい. ただ,これらはエディタ・IDEに依存する方法のため,共同開発においてはではなかなか使いづらい. どのような開発環境でも使えるようにターミナルで実行する自動フォーマッタがあればいいなと思った.

環境

Ubuntu 18.04LTS Desktop

時期

2021年5月現在

Watchdog とは

Python製のファイル監視ツール.ファイルの変更を検知し,スクリプトを実行できる.

Black とは

Pythonのフォーマッタ.あまり設定の自由度は高くないが,その分導入に時間がかからない. まだベータ版しかない.

導入済みであると想定してるもの

導入手順

pipenv のインストール

今回はpipenvの仮想環境を使って導入する. プロジェクトディレクトリの直下に仮想環境を作りたいので,まず,以下を~/.bashrcに追記する.

export PIPENV_VENV_IN_PROJECT=true

~/.bashrc を読み込むために以下のコマンドを実行する.

source ~/.bashrc

次に,pipenv をインストールする.

pip install pipenv

そして,仮想環境を作る.

pipenv install

blackとwatchdogとその他依存ライブラリをインストールする.

blackはベータ版しかないため,バージョンを指定する必要がある. --devをつけることで,開発環境のみにインストールすることができる.

pipenv install --dev black==20.8b1 watchdog pyyaml argh

tricks.ymlの作成

watchdogをインストールするとwatchmedoコマンドが使える. watchdogをimportして自分でスクリプトを書くこともできるのだが,watchmedoのほうが手軽なので,こっちを採用した.

tricks.ymlはwatchmedoコマンドを実行する際の設定ファイル. tricks.ymlファイルを作成し,以下のコードを書き込む.

tricks:
    - watchdog.tricks.ShellCommandTrick:
        shell_command: "black ${watch_src_path}"
        patterns: ['*.py']
        ignore_patterns: ['*/**/migrations/*.py']
        ignore_directories: true
        drop_during_process: true

shell_commandはファイルが変更され,セーブしたときに実行されるコマンド.${watch_src_path}は変更されたファイル名を示す. ignore_patternsは無視するファイル名のパターン.自分はDjangoをよく使うので,migrationsディレクトリ以下のファイルは無視するようにしている.

pyproject.tomlの作成

blackの設定ファイル.pyproject.tomlファイルを作成し,以下のコードを書き込む.

[tool.black]
line-length = 88
include = '\.pyi?$'
exclude = '''
/(
    \.git
  | \.tox
  | \.venv
  | _build
  | __pycache__
  | buck-out
  | build
  | dist
  | migrations
)/
'''

line-lengthは改行するか否かを決定する文字数.includeとexcludeはそれぞれ含むファイルと無視するファイルのパターン名.

実行

まず,pipenvの仮想環境に入る.

pipenv shell

以下のコマンドを実行することで,自動フォーマッタを起動することができる. 止めるときにはCtrl + Cで止められる.

watchmedo tricks-from tricks.yml

テスト

試しにmain.pyというファイルを作成して,自動フォーマッタを実行してみる.

f:id:ITK13201:20210503001253g:plain

Pipenv Script の設定

このままでも良いのだが,コマンドも長く実用的ではないため,Pipfileスクリプトを設定し,簡単に実行できるようにする. Pipfileに以下のコードを追記する.

[scripts]
watch = "watchmedo tricks-from tricks.yml"

これにより,以下のコマンドだけで仮想環境でフォーマッタを起動することができる.

pipenv run watch

感想

これで個々の開発環境によらず,フォーマッタを設定することができたので,共同開発がやりやすくなったのではないかと思う. 今回使ったファイル群はGithubにpushしているので,よかったら参考にしてほしい.

github.com