Pythonにおける静的解析とコード整形について

# はじめに
Pythonのスタイルガイドの話からLinterとFormatterのツール紹介、vscodeへの導入までを簡単にまとめています。
本稿で対象となるツールは下記の通りです([他にもいくつかツールは存在します](https://qiita.com/kannkyo/items/0bcc8264009921e560ba#linter))。

- flake8
- mypy
- isort
- black


# スタイルガイド( コーディング規約 )
コードの保守性と品質を高めるために定義されたコードの書き方です。基本的に同じ開発チーム内で決定するものですが、スタイルガイドに則ったものを利用しているところが多いのではないでしょうか？
これをプロダクトに導入することで得られる効果はさまざまあるかと思いますが、個人的に感じている大きなメリットは下記2点です。

- 可読性が向上し、プログラムが理解しやすくなる
- 複数人開発において、統一されたコードが作成できるようになる

同じ言語に複数のスタイルガイドがあったりします。
[google style guide for python](https://google.github.io/styleguide/pyguide.html)
[PEP 8 Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/)

## Pythonにおけるコーディング規約
Pythonには `PEP8` と呼ばれるコーディング規約が存在します。 `Python Enhancement Proposals` の略であり、[PEPの8番目の文章がコーディング規約を表している](https://www.python.org/dev/peps/#id6)ようです。標準ライブラリもこちらの規約を利用しており、多くのPythonコードが `PEP8` を基準にしています。


## ツールの紹介
ここからはコーディング規約に沿ったコードを書くためのツールであるLinter(静的解析)とFormatter(コード整形)を紹介してきます。

### Linter
LinterはPythonコードを解析し規約に沿っていない箇所やバグになり得る記述に対して警告を出してくれるツールです。
ツールにより、警告を出す視点が異なるためそれぞれ紹介していきます

#### flake8
`PEP8` に基づいてコーディング規約を守っているかどうかのチェックを実施するツールです。
プラグインを導入することで、規約違反以外の警告も出してくれるようになります( ※下記の例では flake8-mypy, flake8_isortがプラグイン )。

```
pip install flake8
flake8 --version
4.0.1 (flake8-mypy: 17.8.0, flake8_isort: 4.1.1, mccabe: 0.6.1, pycodestyle: 2.8.0, pyflakes: 2.4.0) CPython 3.9.9 on Darwin
```

#### mypy
コードのアノテーションや型情報を解析して誤った型に対して警告を出してくれるツールです。
型ヒントと合わせて利用することで、想定していない型の代入等や演算を防ぎ、バグを減らすことができます。

```
pip install mypy
mypy --version
mypy 0.930
```

#### isort
`PEP8` にはライブラリのimport順に関して、以下のような記述がされています。

> Imports should be grouped in the following order:
1. Standard library imports.
2. Related third party imports.
3. Local application/library specific imports.

isortは上記の規則に沿ってimport順序を修正してくれるツールになります。

```
pip install isort
isort --version
                 _                 _
                (_) ___  ___  _ __| |_
                | |/ _/ / _ \/ '__  _/
                | |\__ \/\_\/| |  | |_
                |_|\___/\___/\_/   \_/
      isort your imports, so you don't have to.
                    VERSION 5.10.1
```


###Formatter
上記で紹介したLinterはあくまで警告を出して開発者にコードの不備を知らせてくれるものです。実際にはそれらの警告に基づいてコードを修正していく必要があります。
ここでは、実際にコードを整形してくれるツールについて紹介します。

#### black
`PEP8` に基づいてコードを整形してくれるツールです。改行等の書き方も統一してくれます。また、他のFormatterと比較して変更できる設定がかなり少ないため、
設定について悩む必要がなくなるかもしれません。

```
pip install black
black --version
black, 21.12b0 (compiled: no)
```

## vscodeへの導入
上記で紹介したツールは対象ディレクトリを指定するなどコマンドとして実行する必要があります。そのためLintやFormatをし忘れたり、そもそもコマンドを打つこと自体が手間に感じるようになるかもしれません。そこで実装中にリアルタイムで静的解析を実施して警告を出したり、ソースコード保存時に自動的にコード整形が実施されるようにvscode側の設定を行います。


```json:settings.json
{
    "python.linting.flake8Enabled": true,
    "python.linting.enabled": true,
    "python.linting.flake8Args": [
        "--max-line-length=120"
    ],
    "python.linting.mypyEnabled": true,
    "editor.formatOnSave": true,
    "python.formatting.blackArgs": [
        "--line-length=120"
    ],
}
```

# おわりに
今回はpythonのスタイルガイドやコードの保守性や品質を保つためのLinter, Formatterの紹介し、vscode上で確認する設定をしました。
(正直今までは)あまりスタイルガイド等意識したコーディングを実施してきておらず、書き捨てになるようなpythonコードばかり生産していました。
実際にツールを導入することで実装中のコードの可読性が向上し、品質の高いコードを書く準備ができたように思えます。

また、開発者自身が書き方に気をつけるだけでは、抜け漏れ等発生してしまう恐れがあります。
自動的に検知する枠組みを用意し利用することで、そういったミスをなくし保守性や品質の高いコードを **継続的に** 記述できるようにしていきたいです。

# 参考文献
https://zenn.dev/ganariya/articles/intermediate-python
https://qiita.com/genbu-jp/items/723b619013dc86008acc
https://qiita.com/tsu_0514/items/2d52c7bf79cd62d4af4a