blackとpylintを使った快適なPython開発

はじめに
--------

Pythonでチーム開発を快適にする以下のツールをご紹介します。

* [black]
* [pylint]

さらに、上記ツールを[PyCharm]や[IntelliJ IDEA]で連携する方法をご紹介します。
※ 本記事のキャプチャは執筆環境の都合で [IntelliJ IDEA] を使っています


本記事では触れませんが、[black]と[pylint]の両方に対応しているエディタ/IDEは他にもあります。

* Emacs
* Vim
* Visual Studio Code


### できるようになること

ファイルを保存したとき、フォーマッターと静的コード解析が自動でかかるようになります。
![2019-05-31_09h53_32.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315364/e223e711-a419-34c6-7bd1-ecf5d164f623.gif)


### 確認した環境

**Windows10**
:warning: MacやLinuxの場合はパス表記などが異なる可能性があります

ツールやIDEのバージョンは以下の通りです。

|                                   |     バージョン      |
| --------------------------------- | ------------------- |
| [black]                           | 19.3b0              |
| [pylint]                          | 2.3.1               |
| [IntelliJ IDEA]                   | 2019.1.3            |
| [IntelliJ IDEA] の Pythonプラグイン | v2019.1.191.7479.19 |
| [IntelliJ IDEA] の [File Watchers] プラグイン  | v.191.6183.20       |


[black]
----

### [black]とは

Pythonのフォーマッターです。
ソースコードに実行すると、決められたルールに従いフォーマットがかかります。

⚠️ [black]は2019-05-30現在β版のため、多少挙動が変わる可能性があります (大きな仕様変更の予定はないとのこと)

### メリット

以下のメリットがあると感じています。

* フォーマットが同じであるため、他人のコードが読みやすくなりレビュー速度が上がる
* フォーマットを整えるために使うリソースを開発に充てることができる
* どのエディタを使っても同じフォーマットになる


### 設定

[black]の設定は`pyproject.toml`に記載できます。
以下は一例です。

```toml:pyproject.toml
[tool.black]
line-length = 100
target-version = ['py36', 'py37']
include = '\.pyi?$'
exclude = '''
/(
    \.eggs
  | \.git
  | \.hg
  | \.mypy_cache
  | \.tox
  | \.venv
  | _build
  | buck-out
  | build
  | dist
)/
'''
```

#### 設定できる項目

コマンドライン引数で設定できる項目は`pyproject.toml`で上書きできます。

コマンドライン引数の一覧は`black --help`で表示させることができます。

```
$ black --help
Usage: black [OPTIONS] [SRC]...

  The uncompromising code formatter.

Options:
  -l, --line-length INTEGER       How many characters per line to allow.
                                  [default: 88]
  -t, --target-version [py27|py33|py34|py35|py36|py37|py38]
                                  Python versions that should be supported by
                                  Black's output. [default: per-file auto-
                                  detection]
  --py36                          Allow using Python 3.6-only syntax on all
.
(以下略)
```


[pylint]
------

### [pylint]とは

エラーの発見やコード品質を向上させてくれる静的コードチェッカーです。

### メリット

以下のメリットがあると感じています。

* どのエディタを使っても同じ解析ができる
* 不要な解析は無効化できる (ファイル単位、行単位も可)


### 設定

設定方法はいくつかあり、http://pylint.pycqa.org/en/latest/user_guide/run.html#command-line-options で紹介されています。

たとえば、プロジェクトで設定ファイルを管理する場合は`.pylintc`ファイルを作成します。
雛形作成用のコマンドを使います。

```
$ pylint --generate-rcfile > .pylintrc
```

#### 解析項目の無効化

不要な解析項目は無効にできます。

##### 無効範囲の指定

http://pylint.pycqa.org/en/latest/user_guide/message-control.html に紹介されています。
たとえば、以下のように書くとその行だけimportポジションが間違っている警告を無視できます。

```python
import os

a = "hoge"

import something # pylint: disable=wrong-import-position
```

##### 無効できる項目の一覧

項目一覧は `pylint --list-msgs` で確認できます。

```
$ pylint --list-msgs
:blacklisted-name (C0102): *Black listed name "%s"*
  Used when the name is listed in the black list (unauthorized names).
:invalid-name (C0103): *%s name "%s" doesn't conform to %s*
  Used when the name doesn't conform to naming rules associated to its type
  (constant, variable, class...).
:missing-docstring (C0111): *Missing %s docstring*
  Used when a module, function, class or method has no docstring.Some special
  methods like __init__ doesn't necessary require a docstring.
.
.
```

全部で1000行くらい表示されます。


[black]と[pylint]を[PyCharm]や[IntelliJ IDEA]で使う
--------------------------------------------------

[black]と[pylint]を[PyCharm]や[IntelliJ IDEA]と連携させる方法をご紹介します。

開発に集中できるよう、ファイル保存時に[black]や[pylint]を自動実行できるようにします。

### [File Watchers]プラグインのインストール

ファイル保存時に処理を実行させるためには、公式の提供している[File Watchers]プラグインが必要です。
[IntelliJ IDEA]にインストールしてください。

### [black]の設定

`Settings` > `Tools` > `File Watchers` から `<Custom>` で新規作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315364/94b6d80c-5c3d-0743-bdd1-15ed3266c4e2.png)

以下の様に設定します。

| 項目 | 値 |
|-----|---|
| File type | `Python` |
| Scope | `Current File` |
| Program | `$PyInterpreterDirectory$\black` |
| Arguments | `$FilePath$` |

また`Advanced Options`の以下チェックは外しています。

* `Auto-save edited files to trigger the watcher`
* `Trigger the watcher on external changes`

[IntelliJ IDEA]で現在編集中のファイルが保存されたときだけ[black]を実行したいからです。

全て設定すると以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315364/198da43f-9881-1dc1-4f16-a680bf1496da.png)

Pythonファイルを編集/保存してみましょう。
自動で[black]がコードをフォーマットしてくれるはずです :smile:

> :book: 【参考】https://black.readthedocs.io/en/stable/editor_integration.html


### [pylint]の設定

[black]のときと同様、`Settings` > `Tools` > `File Watchers` から `<Custom>` で新規作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315364/94b6d80c-5c3d-0743-bdd1-15ed3266c4e2.png)

以下の様に設定します。

| 項目 | 値 |
|-----|---|
| File type | `Python` |
| Scope | `Current File` |
| Program | `$PyInterpreterDirectory$\pylint` |
| Arguments | `--rcfile $ContentRoot$/.pylintrc $FilePath$` |

[black]と同様、`Advanced Options`の以下チェックは外しています。

* `Auto-save edited files to trigger the watcher`
* `Trigger the watcher on external changes`

全て設定すると以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315364/97586231-6086-854d-978a-f759fc85f706.png)

Pythonファイルを編集/保存してみましょう。
自動で[pylint]が実行され、問題がある場合だけ画面下部にViewが表示されると思います :smile: 

> :book: 【参考】http://pylint.pycqa.org/en/latest/user_guide/ide-integration.html#pylint-in-pycharm


終わりに
--------

[black]や[pylint]を使うことで、エディタやIDEによらずフォーマットやコードチェックできる方法をご紹介しました。

保存時に自動実行するため、実行を忘れる心配もありません。
チームでPython開発を行う場合は、ぜひ試してみていただければと思います :smile:

[black]: https://black.readthedocs.io/en/stable/
[pep8]: https://www.python.org/dev/peps/pep-0008/
[pylint]: http://pylint.pycqa.org/en/latest/
[IntelliJ IDEA]: https://www.jetbrains.com/idea/
[PyCharm]: https://www.jetbrains.com/pycharm/?fromMenu
[File Watchers]: https://plugins.jetbrains.com/plugin/7177-file-watchers