Pipenv を使ってみたら最高だった

最近 Qiita でバズってるこの記事に影響されて Pipenv を使い始めているんだけど、 「おれたちが待ってたのはコレだ」感をスゴく感じられてオススメ。

github.com

特徴は以下の三つ。

  • pyenv + virtualenv + pip のスイートツール
  • bundler, npm ライクな依存管理
  • Python.org 推奨

プロジェクトを始めるときに pyenv, virtualenv, pip を機械的に叩かないといけなかったりだとか、 requirements.txt の依存関係管理が弱かったりだとか、 Pipenv を使うことでそういった問題をまとめて解決できる。

インストールは pip install pipenv すれば良い。 Homebrew にも対応しているので、MacOS なら brew install pipenv でもOK。

pip install pipenv

# Mac OS
brew install pipenv

pipenv をプロジェクトで始めるには、まず使用するインタプリタを決定する。 指定可能なインタプリタは pyenv install --list で確認できる。 ちなみに、新しいバージョンのインタプリタが出てこない場合は、 brew upgrade pyenv もしくは pyenv update すると、 ローカルの pyenv リポジトリが更新されて見えるようになる。

$ pipenv --python 3.6.5
Creating a virtualenv for this project…
Using /usr/local/bin/python3.6m (3.6.5) to create virtualenv…
...
Creating a Pipfile for this project…

$ pipenv run python --version
Python 3.6.5

pipenv --python <インタプリタ名> を実行すると、以下の3つの処理が内部的に行われている。

  • 利用するインタプリタのインストール(未インストールであれば):= pyenv install <インタプリタ名>
  • 利用するインタプリタの設定 := pyenv local <インタプリタ名>
  • 利用する仮想環境の作成と設定 := virtualenv <環境名> && source <環境名>/bin/activate

なので、指定するインタプリタの仮想環境が一発で作れるというわけ。 さらに、もうひとつの処理が内部的に行われている。

  • Pipfile の作成

作成される Pipfile はデフォルトでこういったものである。

[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]

[dev-packages]

[requires]
python_version = "3.6"

source は、pip install 時に参照する PyPI リポジトリの指定となっている。 公式の PyPI リポジトリ以外を使う人はあまりいないはずなので、基本的にここを触る必要はない。

requires はインタプリタの指定、packages, dev-packages は依存パッケージの指定である。 依存パッケージをインストールすると、自動的に packages, dev-packages に足される。 依存パッケージのインストールは pipenv install で行う。

$ pipenv install requests
Installing requests…
...

$ cat Pipfile
...
[packages]
requests = "*"
...

バージョンを指定していないので * になっているが、そこまで気にしなくて良い。 なぜなら、おもむろに生成されている Pipfile.lock 内でインストールされた厳密なバージョンが記録されているし、 他のマシンでおなじ環境を再現するときに参照されるのも Pipfile.lock の方だからである。

$ cat Pipfile.lock
...
        "requests": {
            "hashes": [
                "sha256:6a1b267aa90cac58ac3a765d067950e7dbbf75b1da07e895d1f594193a40a38b",
                "sha256:9c443e7324ba5b85070c4a818ade28bfabedf16ea10206da1132edaa6dda237e"
            ],
            "index": "pypi",
            "version": "==2.18.4"
        },
...

そして、他のマシン上で同じ環境を再現するために、Pipfile と Pipfile.lock はバージョン管理しておく。 他のマシン上で同じ環境を再現するには、リポジトリを clone した上で pipenv sync を実行する。

$ pipenv sync
Creating a virtualenv for this project…
...

エディタの話を付け加えておくと、VisualStudio Code が既に Pipenv をサポート済みである。 VSCode は内部的に pylint や isort といったコマンドを実行するが、 アプリを立ち上げると Pipenv を自動で検出して、 こういったコマンド類を仮想環境にインストールされたものから使ってくれる。 さらに、VSCode はコマンド類が見つからなかった場合、 (ユーザに対して確認を求めた上で)インストールコマンドを実行するが、 このコマンド類のインストールについても仮想環境に対して行ってくれる。 なので、VSCode ユーザにとっては至れり尽くせりといったところである。