はじめに
この記事は「Python + Pipenv + VSCode」の開発環境構築のための記事です。
Python歴1年のエンジニアが書いているのでPythonの文化のようなものを汲み取れていないかもしれませんが、その点はご注意ください。
モチベーション
ソースコードをチームで管理する場合にはパッケージ管理が必要となります。同じ動作環境を整えることはコミュニケーションコストを下げます。
そんな当たり前のことを。。と思いますよね。
ほぼアプリ開発しかやったことがないので私にとって、パッケージ管理は当たり前なのですが、Pythonの用途はアプリ開発に限定されずデータサイエンスやちょっとした作業の自動化にも使われるため、パッケージ管理についての必要性の認識が開発者ごとに違うことに気がつきました。
また、定番のパッケージマネージャーがPython界には存在しない(と私には思える)ことも、開発者ごとにパッケージ管理のイメージのばらつきの原因になっていると思います。
javascriptの場合はnpmやyarnがあり、パッケージ管理を前提としてコードを書き始めることはjavascriptの文化になっていると思います。一方Pythonには有名なパッケージマネージャーとしてpipが存在ますが、npmを使ってきた私にはpipではとても貧弱に感じます。
私は最近、pipenvをチームに導入したところ上手く機能することが分かったので、pipenvを使ったPythonプロジェクトの環境構築方法を書きます。
この記事で紹介するプロジェクト構成のソース
すぐにpipenv構成のベースプロジェクトが欲しい人はこちらgithubに置いています。
グローバルなpipへのPipenvのインストールが完了されている方は、上記リポジトリのクローンから単体テストの実行までをすぐに試せます。導入方法は次の通りです。
git clone https://github.com/michiharu/PythonProjectStarterKit.git
cd PythonProjectStarterKit
pipenv install --dev --pre
pipenv run test
Pythonについて
Vanilla vs Anaconda
標準インストーラーのPythonを"Vanilla Python"というらしいです。Pythonは公式ページのインストーラーを使ってインストールすることを前提に話を進めます。
Anacondaは便利なのですが、便利さゆえに実行環境についての理解が進まないというのが私の意見です。アプリ開発者であればPythonの実行環境の最小構成を理解しておく必要があると思います。
アプリ開発にはVanilla、データサイエンスにはAnacondaと心得ておくと良さそうです。Pythonの環境構築については以下の記事が大変参考になりました。
この記事を読んでPython環境の再構築をする場合には、一旦これまで使ってきたライブラリーをテキストファイルに出力しておくことをお勧めします。
pip freeze > requirememts.txt
Python環境構築
標準インストーラーのダウンロード
Python公式ページ から、「Files > Windows x86-64 web-based installer」を選んで、
インストーラーをダウンロードしてください。
インストール
インストーラーを実行すると最初に「システム環境変数にpythonへのPathを追加するか?」というチェックボックスがあるので、
必ずチェックしてからインストールしましょう。
確認
コマンドプロンプトを開いて以下を実行します。
python --version
pipenvの環境構築
以下、pipenvを使うための手順を説明します。
インストール
次のコマンドで使えるようにします。
pip install pipenv
インストールが完了したらpipenv
とコマンドを叩くと、pipenvで実行可能なコマンド一覧が紹介されます。
※ユーザー権限でインストールする--user
オプションを紹介している記事があります。オプションを付けてユーザー環境変数にPathを通すことで使えるようになる、という記事を見かけるのですが、何度か試しても--user
オプションでインストールした場合はシステム環境変数にPathを通さないとpipenvコマンドを使えるようになりませんでした。Python自体がデフォルトでユーザー権限でインストールされているので、pip install pipenvもユーザー権限でインストールされていると理解しています。つまり、--user
オプションはPythonをシステム全体で使えるようインストールしているケースで有効なオプションではないか、と推測しています。正しい知識をお持ちの方はコメント下さい。
システム環境変数の設定
pipenvのデフォルトの挙動は、プロジェクトディレクトリとは別の、USERディレクトリの.virtualenvs
に仮想環境リソースを作成します。
これは仮想環境のLibの確認の際などですぐアクセスできず不便なので、システム環境変数の設定にてプロジェクト内に仮想環境を作成する設定を有効化します。
PIPENV_VENV_IN_PROJECT=true
以上がプロジェクトを作る準備としての環境構築でした。
新規プロジェクト作成方法
.vscodeの設定
注意
.vscode
の設定を行うとVSCodeから「~をインストールしますか?」というダイアログが表示されることがあります。このダイアログからインストールすることはお勧めしません。
理由は後述するパッケージ追加方法でなければ、自動で実行されるスクリプトはpipenvではなくpipを使用してグローバルにインストールされるため、Pipfileが更新されません。LinterやFormatterはpipenvでインストールしましょう。
settings.json
ファイルの記述
vscodeでLinterやFormatterの設定を共有するため、.vscode/settings.json
に次の設定が必要です。
{
"python.venvPath": ".venv",
"python.pythonPath": ".venv\\Scripts\\python.exe",
"python.envFile": "${workspaceFolder}/.env",
"python.linting.enabled": true,
"python.linting.pylintEnabled": false,
"python.linting.flake8Enabled": true,
"python.linting.mypyEnabled": true,
"python.formatting.provider": "black",
"python.linting.flake8Args": ["--ignore=E501,W503"],
"editor.formatOnSave": true
}
上記の設定で可能になることは以下の通りです。
- pythonをプロジェクトごとの仮想環境で実行すること
- .envファイルを配置することで、python実行時の環境変数を追加することが出来る
- プロジェクトごとのLinterやFormatterの適用
.env
ファイルについて
python実行時の環境変数を追加するため、.envファイルには以下を記述します。
配置場所はプロジェクト直下です。
PYTHONPATH=".\src;"
PYTHONPATHは、python実行時にモジュールを探す場所を追加するものです。セミコロン区切りで複数記述することが出来ます。
blackについて
Formatterはblackを選択しました。
blackは、自ら「妥協のないPython Formatterです。」(Black is the uncompromising Python code formatter.)と謳っています。
曰く、
フォーマットについての議論を尽くした設定になっているので、そのまま使ってね。
もうフォーマットで悩むのやめよう?その方が時間の節約になるし、もっと大切なことにエネルギーが注げるよ。
とのことです。
そのためflake8とルールが競合する場合はblackを優先させることとします。つまりflake8に競合するルールを無視させます。
python.linting.flake8Args
にはblackとのルール競合を避けるため、flake8の一部のルールを無視する設定を行っています。
例えば、--ignore=E501
は、flake8の1行最大79文字ルールを無視するための設定です(blackは1行最大88文字)。ここでサンプルとして設定した他にもblackと競合してしまうルールがいくつかあったと思いますが、フォーマット関連でflake8のエラーが出たら都度追加していってください。
pipenvの導入
以下のコマンドを実行します。Pythonのバージョンはより細かく設定できます。該当バージョンのPythonがインストールされていない場合はエラーになりますので、その場合は標準インストーラーからインストールをお願いします。
pipenv --python 3
コマンドを実行するとプロジェクトのディレクトリに以下のファイルが追加されます。
- .venv
- Pipfile
- Pipfile.lock
パッケージ追加
実行時に使用されるパーッケージの場合
pipenv install [package]
Linterやテストツールなど開発時に使用されるパッケージの場合
pipenv install --dev [package]
pipenv install --dev mypy flake8 black isort --pre
--dev
は開発用パッケージとして管理するためのオプションです。--pre
はプレリリースされているパッケージのインストールを許可するオプションです。blackは"NOTE: This is a beta product"と公式ページに記述していて、preオプションがないとPipfile.lockの更新に失敗した旨のエラーとなります。
Clone したプロジェクト
CloneしてきたプロジェクトにPipfile
がある場合は以下のコマンドで、.venv
を生成し、そこ必要モジュールをインストールします。
// Pipfileの[packages]に記述されたパッケージを追加
pipenv install
// Pipfileの[dev-packages]に記述されたパッケージを追加
pipenv install --dev --pre
requirements.txtで管理していたプロジェクトでpipenvを有効化
引数rを使うとrequirements.txt
からパッケージをインストールできます。
pipenv install -r ./requirements.txt
Pythonプロジェクトの標準的なディレクトリ構成
ソースコードをsrc
ディレクトリに配置するのは言語を問わない文化だと思います。
src以下のディレクトリ構成は以下のようにします。
src
├── package
│ ├── foo_module.py
│ ├── :
│ └── xxx.py
└── tests
├── __init__.py
├── test_foo_module.py
├── :
└── test_xxx.py
test_foo_modules.pyからfoo_module.pyをインポートするには以下のように記述します。
※srcにPythonのpathが通っている前提です。
import package.foo_module
実行・スクリプト登録
テストは以下のコマンドで実行できます。
// 一括実行の場合
pipenv run python -m unittest discover src -v
testsディレクトリには__init__.py
を配置しないと上記コマンドではunittestからテストコードが探せないためエラーが発生します。
また、よく使うコマンドはスクリプト登録することが可能です。Pipfileに以下の項目を追加します。
[scripts]
test = "python -m unittest discover tests -v"
isort = "python -m isort -m 3 ."
この設定により、以下のコマンドでテストが可能になります。
pipenv run test
2つ目に追加したisortは、importに特化したフォーマッターです。これまでに紹介しているblackはimportには触れないので、importのフォーマットはisortに任せます。
pipenv run isort
Pythonプロジェクトの環境構築手順については以上です。