Pythonが公式に推薦しているという、PythonのパッケージングソフトであるPipenvを試してみました。Pipenvは、Requestsの開発者としても有名なKenneth Reitz氏が中心となり開発されています。
例えばPythonでアプリケーションを開発するとき、複数の開発者がそれぞれ自分の手元で独立にpipでパッケージをインストールすると、そのタイミングによって異なるバージョンのパッケージが得られてしまう恐れがあります。このPipenvはその問題を解決し、開発者間で必ず同じバージョンのパッケージが使われるようにするためのツールだと自分は理解しています。
このPipenvは、pipとvirtualenvのラッパーとして働くので、pipとvirtualenvを直接さわることはなくなります。
Pipenvのインストール
GitHub - pypa/pipenv: Python Development Workflow for Humans. を参照。
使い方
まず使ってみる
以下はUbuntu 16.04 LTS on Windowsで試しました。PythonにはAnaconda 3を使うよう設定しています。
まず作業用のディレクトリを作成します。
$ mkdir myproject $ cd myproject
次に、このプロジェクトで使うパッケージをインストールします。ここではrequests
パッケージを入れてみます。
$ pipenv install requests Creating a virtualenv for this project… Using /home/minus9d/anaconda3/bin/python (3.6.3) to create virtualenv… ...(略)... Installing collected packages: idna, chardet, certifi, urllib3, requests Successfully installed certifi-2018.4.16 chardet-3.0.4 idna-2.6 requests-2.18.4 urllib3-1.22 Adding requests to Pipfile's [packages]… Pipfile.lock not found, creating… Locking [dev-packages] dependencies… Locking [packages] dependencies… Updated Pipfile.lock (b14837)! Installing dependencies from Pipfile.lock (b14837)… 🐍 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 5/5 — 00:00:06 To activate this project's virtualenv, run the following: $ pipenv shell
このコマンドにより2つのことが行われました。
1つ目は、仮想環境の生成です。Pipenvが裏でvirtualenvを使って、このプロジェクトのための仮想環境が生成されました。
2つ目は、Pipfile
, Pipfile.lock
という2つのファイルの生成です。生成場所はmyprojectディレクトリの直下です。これらのファイルは、このプロジェクトが依存する他のパッケージの取得元やそのバージョンに関する情報を格納します。ファイルの内容に関する詳細は GitHub - pypa/pipfile にあります。
従来、プロジェクトが依存するパッケージの管理には、requirements.txt
というのが使われていました。例えばpip install -r requirements.txt
などとすると、requirements.txt
に記述された依存パッケージをインストールできました。今回生成されたPipfile
, Pipfile.lock
は、従来のrequirements.txt
にとってかわるものになるようです。これら2ファイルはいずれも構成管理ツールの対象になります(参考)。
Pipfile
は以下のようになります。requests
のバージョン指定をしなかったので"*"
になっています。
[[source]] url = "https://pypi.org/simple" verify_ssl = true name = "pypi" [packages] requests = "*" [dev-packages] [requires] python_version = "3.6"
Pipfile.lock
は以下のようになります。こちらには実際にインストールされたバージョンが記述されています。
$ cat Pipfile.lock { "_meta": { "hash": { "sha256": "8739d581819011fea34feca8cc077062d6bdfee39c7b37a8ed48c5e0a8b14837" }, "pipfile-spec": 6, "requires": { "python_version": "3.6" }, "sources": [ { "name": "pypi", "url": "https://pypi.org/simple", "verify_ssl": true } ] }, "default": { "certifi": { "hashes": [ "sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7", "sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0" ], "version": "==2018.4.16" }, "chardet": { "hashes": [ "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" ], "version": "==3.0.4" }, ...(略)... "requests": { "hashes": [ "sha256:6a1b267aa90cac58ac3a765d067950e7dbbf75b1da07e895d1f594193a40a38b", "sha256:9c443e7324ba5b85070c4a818ade28bfabedf16ea10206da1132edaa6dda237e" ], "index": "pypi", "version": "==2.18.4" }, "urllib3": { "hashes": [ "sha256:06330f386d6e4b195fbfc736b297f58c5a892e4440e54d294d7004e3a9bbea1b", "sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f" ], "version": "==1.22" } }, "develop": {} }
依存関係の可視化
pipenv graph
とすると、これまでに入れたパッケージの依存関係が可視化されて表示されます。具体的には、requests
が要求するパッケージ、そのパッケージのインストール条件、実際にインストールされたパッケージのバージョンが表示されます。
$ pipenv graph requests==2.18.4 - certifi [required: >=2017.4.17, installed: 2018.4.16] - chardet [required: <3.1.0,>=3.0.2, installed: 3.0.4] - idna [required: <2.7,>=2.5, installed: 2.6] - urllib3 [required: >=1.21.1,<1.23, installed: 1.22]
仮想環境に入る
pipenv shell
とすると、自分で入れたパッケージだけが使える仮想環境に入れます。出るときはexit
です。
$ pipenv shell Spawning environment shell (/bin/zsh). Use 'exit' to leave. . /home/minus9d/.local/share/virtualenvs/myproject-yAY6_O7R/bin/activate ...(略)... $ pip list Package Version ---------- --------- certifi 2018.4.16 chardet 3.0.4 idna 2.6 pip 10.0.1 requests 2.18.4 setuptools 39.1.0 urllib3 1.22 wheel 0.31.0
上でもちょっと出てますが、インストールされたパッケージの場所はpipenv --venv
によりわかります。
$ pipenv --venv /home/minus9d/.local/share/virtualenvs/myproject-yAY6_O7R
デフォルトで ~/.local/share/virtualenvs
の下に格納されるようです。知らない間に肥大化させないよう注意したいです。
他人が作ったPipfile
, PipFile.lock
に従いパッケージをインストール
Githubなどからレポジトリをcloneしてきて、そのレポジトリにPipfile
, Pipfile.lock
があるような場合を考えます。この場合、pipenv install
とすることで、レポジトリ製作者が使っているのと同じバージョンの依存パッケージをインストールできます。
$ git clone https://(somewhere)/myproject.git $ cd myproject $ pipenv install
仮想環境の削除
仮想環境を削除するときは、対象のディレクトリ(ここではmyproject
)内で pipenv --rm
とします(参考)。
$ pipenv --rm
これにより~/.local/shareに保存されていたパッケージファイルが削除されます。
requirements.txt の出力
pipenv lock -r
とすると、requirements.txt
と同形式の出力を得られます。
$ pipenv lock -r -i https://pypi.org/simple certifi==2018.4.16 chardet==3.0.4 idna==2.6 requests==2.18.4 urllib3==1.22
Anaconda Pythonのcondaとの接続
私は普段Pythonの環境構築にはAnaconda Pythonを使っています。その大きな理由の一つが、NumPyなどとくにWindowsでビルドするのが大変なパッケージについて、conda install numpy
などとconda install
コマンドを使うことでビルド済バイナリを取得できることです。
今回紹介したPipenvでinstall
コマンドを使うと、デフォルトではPyPIからパッケージが入手されるため、手元でパッケージのビルドが走ってしまうはずです。Pipenvの進んだ使い方 — pipenv 11.10.1 ドキュメント によると--site-packages
フラグを使えばcondaで入手したパッケージを再利用できるそうなのですが、私の手元ではうまくいきませんでした。
個人的には、ここが解決できない限り、Pipenvには移行できなさそうです。
[2018/05/24追記] 実は最近のNumPyなど多くのパッケージはwheel形式で配布されているためビルドなしでインストールできることが多いようです。なので実はPipenvを使う障壁は少ないのかもしれません。
参考URL
- Pipenv: Python Dev Workflow for Humans — pipenv 11.10.1 documentation
- Pipenvの公式。トップに埋め込まれたScreencastを見るとよい
- Pipenv: 人間のためのPython開発ワークフロー — pipenv 11.10.1 ドキュメント
- その日本語版
- GitHub - pypa/pipfile
- Pipenvが生成するPipfileに関する公式情報
- A Better Pip Workflow™ — Kenneth Reitz
- pipenvの作者が、pipenv開発前に書いたエッセイ