Pipenvの使い方がいまいちちゃんとわかっていなかったので、公式ドキュメント中心に読みながら色々動かしてみた時のメモです。
各コマンドの関連を図示したのでその流れで書いていきます。図中の番号とこの記事の段落の番号が対応しています。
Pipenv
Pythonの仮想環境は従来pipとvertualenvによって構築することが多かったですが、Pipenvはそれらを簡単にまとめて管理できるようにしたツールです。
- 内部的にはpipとvertualenvを使っている
- パッケージの依存関係まで管理し、ビルドが常に同じ結果をもたらすようになっている
- requirements.txtではなく、PipfileとPipfile.lockというファイルを活用する
- bundler、composer、npm、cargo、yarn等に近い
PipfileとPipfile.lock
Pipenvは2つのファイルを生成します。これらを直接編集することは基本的に無いですが、仮想環境がどのような根拠でどのような状態になっているかを把握するためにそれぞれの役割を抑えておきます。それぞれのファイルには下記のような役割や性質があります。
Pipfile
- 各種パッケージとそのバージョンを管理
- 開発用パッケージを分けて管理
- 自身で定義したスクリプトを管理
Pipfile.lock
- インストールしたパッケージが依存しているパッケージとそのバージョンを管理
- リモートでのパッケージの改ざんから守るためのハッシュの管理(pipのバージョン8.0から導入された機構)
それでは、各コマンドとその使い方を見ていきます。
0. 準備
Pipenvをインストールします。
$ brew install pipenv
pipでインストールすることも可能です。
$ pip install pipenv
Pythonのバージョンを指定して仮想環境の初期化を行います。もし指定したバージョンが無い場合、pyenv経由でそのバージョンをインストールしてくれます。
$ pipenv --python 3.6
仮想環境が初期化されると、Pipfileというファイルが生成されます。
1. install
installコマンドでパッケージのインストールが可能です。
既存のPipfileやPipfile.lockを利用する
コマンドを実行する同階層にPipfileやPipfile.lockファイルがある場合、それらのファイルを参照して環境が構築されます。
$ pipenv install
既存のrequirements.txtを利用する
元々Pipenvで管理していなくても、requirements.txtからPiprnvで管理された環境を構築できます。
$ pipenv install -r ./requirements.txt
新しく環境を構築する
参照元となるファイルがない場合、先程の pipenv --python <version>
同様に環境が構築されます。
$ pipenv install --python 3.6
installコマンドの場合、Pipfileに加えPipfile.lockファイルも生成されています。中身を見てみましょう。
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages] // まだパッケージをインストールしていないので空
[requires]
python_version = "3.6" // バージョン3.6が指定されている
{
"_meta": {
"hash": {
"sha256": "415dfdcb118dd9bdfef17671cb7dcd78dbd69b6ae7d4f39e8b44e71d60ca72e7"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.6"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {}, // まだパッケージをインストールしていないので空
"develop": {}
}
パッケージを追加する
試しにpandasを追加してみます。
$ pipenv install pandas
すると、それぞれ下記のように追記されます。
[packages]
pandas = "*" // バージョン指定なし
"default": {
"numpy": {
"hashes": [
"sha256:03bbde29ac8fba860bb2c53a1525b3604a9b60417855ac3119d89868ec6041c3",
(略)
"sha256:f6a7421da632fc01e8a3ecd19c3f7350258d82501a646747664bae9c6a87c731"
],
"version": "==1.18.0"
},
"pandas": {
"hashes": [
"sha256:00dff3a8e337f5ed7ad295d98a31821d3d0fe7792da82d78d7fd79b89c03ea9d",
(略)
"sha256:ee50c2142cdcf41995655d499a157d0a812fce55c97d9aad13bc1eef837ed36c"
],
"index": "pypi",
"version": "==0.25.3"
},
"python-dateutil": {
"hashes": [
"sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c",
"sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"
],
"version": "==2.8.1"
},
"pytz": {
"hashes": [
"sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d",
"sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be"
],
"version": "==2019.3"
},
"six": {
"hashes": [
"sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd",
"sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"
],
"version": "==1.13.0"
}
},
numpyやpython-dateutil等、pandasが内部的に依存しているパッケージとそのバージョンも指定されています。
また、バージョンを指定してインストールする場合は下記のようにします。
$ pipenv install pandas==0.15.0 // 特定のバージョンを指定
バージョンの指定方法は特定のバージョンだけでなく、指定のバージョン以上、特定のバージョンを除くといったことが可能です。詳しくは 公式ドキュメント をご参照ください。
パッケージを削除する
インストールしたパッケージをアンインストールする場合はuninstallコマンドを使います。
$ pipenv uninstall pandas
そうするとPipfile、Pipfile.lock共にinstallで追記された分が削除されます。
※ 仮想環境からはpandasはアンインストールされますが、pandasが依存していたその他のパッケージはそのままとなります。これらのアンインストールに後述するcleanコマンドを使います。
2. lock
Pipfileの内容からPipfile.lockファイルを更新する際はlockコマンドを使います。
$ pipenv lock
特に pipenv install
時にバージョンを指定しない場合、パッケージのバージョンアップの際にこのコマンドを使うことになります。
3. sync
syncコマンドはPipfile.lockの内容を仮想環境に適用するために利用します。
$ pipenv sync
このコマンドはlockコマンドとセットで利用することが多いと思います。
4. update
updateコマンドはlockとsyncを一度に行うものです。
$ pipenv update // 全てのパッケージに対して行う
$ pipenv update pandas // パッケージを指定することも可能
--dry-run
オブションをつけると、バージョンのアップデートができる(古くなった)パッケージがわかります。
$ pipenv update --dry-run
✔ Success!
// 古いバージョン(0.15.0)のpandasを入れたので、新しいバージョン(0.25.3)が利用可能と教えてくれる
Skipped Update of Package pandas: 0.15.0 installed, 0.25.3 available.
なお、pipenv install
時にバージョンを指定している場合、--dry-run
オプションが無くても新しいバージョンのインストールはスキップされます。その場合はpipenv install
で任意のバージョンを指定して上書きインストールをします。
5. run
仮想環境内でコマンドを実行する場合はrunコマンドを使います。試しにインストールされたパッケージ一覧を表示してみます。
$ pipenv run pip list
Package Version
--------------- -------
numpy 1.18.0
pandas 0.15.0
pip 19.3.1
python-dateutil 2.8.1
pytz 2019.3
setuptools 43.0.0
six 1.13.0
wheel 0.33.6
また、Pipfileにスクリプトを登録しておくと、そのスクリプトをrunコマンドで呼び出すことができます。
[scripts]
list = "pip list"
$ pipenv run list // pipenv run pip list と同じ結果になる
6. shell
仮想環境の中に入る時にはshellコマンドを使います。
$ pipenv shell
7. clean
仮想環境にはあるがPipfile.lockで定義されていないパッケージがある場合、cleanコマンドでそれらのパッケージを仮想環境から削除できます。
試しに先程出てきた、pipenv install pandas
の後pipenv uninstall pandas
を行い、仮想環境ではpandasが依存しているパッケージが残っている状態でcleanコマンドを実行してみます。
$ pipenv run pip list
Package Version
--------------- -------
numpy 1.18.0 // numpy等、pandasが依存しているパッケージが残っている
pip 19.3.1
python-dateutil 2.8.1
pytz 2019.3
setuptools 43.0.0
six 1.13.0
wheel 0.33.6
$ pipenv clean // cleanを実行
Uninstalling six…
Uninstalling pytz…
Uninstalling python-dateutil…
Uninstalling numpy…
$ pipenv run pip list // cleanの結果を確認
Package Version
---------- -------
pip 19.3.1
setuptools 43.0.0
wheel 0.33.6
pandasが依存していたパッケージもしっかりアンインストールされているのがわかります。
8. check
checkコマンドは、セキュリティの脆弱性をチェックし、現在の環境がPEP 508の要求仕様を満たしているかどうかを調べます。
$ pipenv check
9. graph
パッケージの依存関係を見たい場合、graphコマンドを使います。
$ pipenv graph
pandas==0.15.0 // pandasはnumpy、python-dateutil、pytzに依存していることがわかる
- numpy [required: >=1.7.0, installed: 1.18.0]
- python-dateutil [required: >=2, installed: 2.8.1]
- six [required: >=1.5, installed: 1.13.0] // python-dateutilがさらにsixに依存していることがわかる
- pytz [required: >=2011k, installed: 2019.3]
まとめ
これでPipenvの全体を俯瞰できたかなと思います。しつこいですが、冒頭の関連図を改めて貼っておきます。
その他の代替案
良い事ずくめに見えるPipenvですが、dockerと合わせると辛さがあったり、installが遅かったりと、ちらほら難点もあるようです。その他の代替案として下記ツールの名前も聞くので、近いうちに触ってみようと思います。
- Poetry
- Pyflow
- pip-tools