目的
品質を安定させるためにPython開発環境のツールセットを作る。
- Pythonの開発環境の整備の観点
- プロジェクト構成管理
- ディレクトリ構成
- プロジェクト構成管理ツール
- テストツール
- コーディング規約
- コードフォーマッター
- 静的コード解析ツール
- プロジェクト構成管理
開発環境
- Python 3.7系(動作確認は3.7.0を利用。現在だと3.7.6が同系だと最新)
- Poetry 1.0.5
プロジェクト構成管理
ディレクトリ構成
- APIドキュメントの自動生成を行う場合ではSphinxを利用するのが一般的のようだ。
- APIドキュメントが不要な場合はREADMEなどはMarkdownでもよいだろう。
- Java経験者などはルートモジュールの親ディレクトリとしてsrcを置く人もいるかもしれないが、Pythonでは無い方が望ましいようだ。参考
<プロジェクト ルート>
├── README.rst
├── sample_tdd # ルートモジュール(パッケージ)
│ ├── __init__.py
│ ├── __main__.py # エントリポイント
│ └── hello_world.py
├── sample_tdd.egg-info # パッケージング関連
└── tests # テスト
├── __init__.py
├── test_hello_world.py
└── test_sample_tdd.py
プロジェクト構成管理ツール
構成管理ツールを使用して主に依存ライブラリを管理する。
代表的なツールについては参考:2020 年の Python パッケージ管理ベストプラクティスを参照してもらいたい。
Poetryを採用した理由はプロジェクト構成の生成機能を利用したかったため。
それ以外はPipenvとの比較で、有意なメリット・デメリットを感じられなかった。
例えばPipenvはinstallコマンドで依存関係の解決が遅いとか、Poetry(というかpyproject.toml)はまだツールの設定ファイルとして地位を確立できていない(依然として個別の設定ファイルを使用する必要があるツールが存在する)など、割とどっちもどっちという感じ。
主に使うコマンドを以下に挙げる。
-
poetry install
- パッケージのインストールを行う。
- 仮想環境(venv)が無い場合は作成する。
-
--no-root
オプションをつけるとルートモジュール(をパッケージングしたもの)はインストールしない。
-
poetry [add/remove] <パッケージ名>
-
add
はパッケージを追加 -
remove
はパッケージ削除 -
-D
オプションをつけると開発環境のみの利用パッケージを追加/削除できる。
-
-
poetry new <プロジェクト名>
- プロジェクトを作成する。
-
--name <パッケージ名>
オプションを使用するとプロジェクト名とパッケージ(ルートモジュール)名を別にできる。
-
poetry init
-
pyproject.toml
を作成する。 - プロジェクト構成を自分で決めたい時や既存のプロジェクトで利用する時に使う。
-
参考:インストール
pip install --user poetry
poetry --version
# .venvをプロジェクトルート直下に作成する。デフォルトでは`~/.cache/pypoetry/virtualenvs/`に作られる。
poetry config virtualenvs.in-project true --local
テストツール
テスティングフレームワークは以下の3つ。
ここではパラメータ化テストの書きやすいPytestを採用。
(Poetryのプロジェクト自動生成で設定されているのもプラス材料)
pytest
プラグインを利用してカバレッジリポートとテスト結果のHTMLリポートを作成する設定を行った。
[tool.poetry.dev-dependencies]
pytest = "^5.2"
pytest-cov = "^2.8.1"
pytest-html = "^2.0.1"
coverage = {extras = ["toml"], version = "^5.0.3"}
[tool.coverage]
[tool.coverage.run]
branch = true
[tool.coverage.report]
exclude_lines = ["pragma: no cover","if __name__ == .__main__.:"]
[tool.coverage.html]
directory = "reports/test/coverage"
python -m pytest --cov=sample_tdd --cov-report=html --html=reports/test/results.html --self-contained-html
コーディング規約
Python標準コーディング規約PEP8と標準ドキュメント規約PEP257がある。
静的コード解析やフォーマッタはこれを基準に選定した。
アプリケーション開発ではAPIリファレンスドキュメントを作成しないことも多いと思うので、その場合はPEP257関連は不要。
コードフォーマッター
以下の3つがあるようだ。
今回はautopep8を採用。
理由はarray
やtuple
で末尾,
で終わる書き方を使いたいため。
Blackは末尾,
にスペースをつけないため、静的コード解析で違反のままになる。
プロジェクトで末尾,
で終わるのを禁止したい場合はBlackのほうが設定不要でいいと思う。
-
autopep8
- PEP8に準拠したフォーマッタ
- 静的コード解析ツールのflake8(pycodestyle)と相性が良い。
-
yapf
- PEP8に準拠したモードがある。
-
Black
- PEP8に準拠したフォーマッタ
- 設定項目が少ないのが良い。
- 2020/03/10現在ベータ版。
[tool.poetry.dev-dependencies]
autopep8 = "^1.5"
静的コード解析ツール
今回はhacking(flake8)を採用。Import文のチェックを行うためにflake8-import-orderプラグインを利用している。
感覚的なものだが、Pylintはうるさい使いづらかった。
また、デフォルトだと1行79文字になる(E501)ため、これだけは100に変更した。
プロジェクトによっては120くらいまでは増やしてもよいかもしれない。
flake8はプラグインもあるし、hackingが合わなくてもflake8自体を使っていけるので潰しが効く。
PEP257のチェックを利用する場合はflake8-docstringsプラグインをいれるとpydocstyleを利用できる。
E501の1行
-
hacking
- OpenStack StyleGuideに準拠しているかチェックしてくれる。
-
flake8を利用している。このツールも以下の統合ツール。
- 静的解析(pyflakes)
- スタイルチェック(pycodestyle 旧:pep8)
- 循環的複雑度(mccabe)
-
pylint
- pythonのLinter
[tool.poetry.dev-dependencies]
hacking = "^2.0.0"
flake8-import-order = "^0.18.1"
flake8-docstrings = "^1.5.0"
[flake8]
max-line-length = 100
filename = *.py
max-complexity = 10
exclude = .venv,tests/__init__.py
いじょ。