Pipenv 利用ノート

Note

本記事の前提は次のとおり。

Python:

3.12.7

Shell:

Bash 5.2.21(1)-release

さらに次を加えておく:

  • Python 本体を含むパッケージ管理を Miniconda で行っている

  • 使用者は root でない

概要

Python を用いたプロジェクトに Pipenv を導入する手順と、よく用いるコマンドを記す。

Pipenvpip と仮想環境を一括して管理する道具であり、Ruby 開発における Bundler が処理するファイル群と類比するものを導入することで、pip が扱えないある種のバージョン依存関係問題を解決することを目的とする。

導入

インストール

公式文書の一般的指示とは異なる手順をとる。Miniconda を用いているので、次のようなコマンドで自分の Python 環境に Pipenv 本体を導入する:

Pipenv インストールコマンド例
conda install conda-forge::pipenv

あらかじめコマンド conda search pipenv で最新版がどこにあるかを確認しておくのもコツだ。

環境設定

Pipenv はコマンドライン補完機能も備えている。これが使えると端末上でのタイピングの手間が大幅に省けるので、早めに有効にしておきたい。

手順は公式文書の指示に従えばいい。自分の .bashrc を編集して次の行を加える(インストールした直後ならば端末で直接実行):

Pipenv コマンドライン補完を動作させるコマンド
eval "$(_PIPENV_COMPLETE=bash_source pipenv)"

コツとしては、テスト [ -x $(command -v pipenv) ] を入れるとよい。

仮想環境を作る

Python プロジェクトに対して Pipenv 仮想環境を用意する手順を述べる。仮想環境がまったくないところから建造する場合と、Python 標準モジュール venv を使用して構築された環境から Pipenv に移行する場合とが考えられる。双方とも説明する。

ゼロから創造する

Python プロジェクトのディレクトリーを $PROJECT_DIR と呼ぶ。仮想環境の初期化と同時に、必要なサードパーティー製パッケージをインストールするのが標準的だ。例えばパッケージ SOME_PACKAGE をインストールする場合にはこうする:

プロジェクトディレクトリーを Pipenv に認識させる
$ cd $PROJECT_DIR
$ pipenv install SOME_PACKAGE
Creating a virtualenv for this project
Pipfile: PROJECT_DIR/Pipfile
Using default python from /path/to/python/python3.12
3.12.7 to create virtualenv...
(略)
✔ Success!
Locking [dev-packages] dependencies...
Updated Pipfile.lock!
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
Installing dependencies from Pipfile.lock...

事後、次のようになる。

まず、$PROJECT_DIR 直下にファイル Pipfile および Pipfile.lock が出力される。これらは Ruby 開発でいう Gemfile および Gemfile.lock にそれぞれ対応する意味を有する。

そして、仮想環境を管理するディレクトリーが $PROJECT_DIR 直下ではなく、おそらく既定では $XDG_DATA_HOME/virtualenvs/PROJECT_DIR-xxxxxxxx のようなパスにある。

Tip

管理ディレクトリーのパスはコマンド pipenv --venv を実行することで確かめられる。

既存の環境から乗り換える

前の説明と同じ名前を使うが、本節では Python 標準モジュール venv を使って仮想環境が $PROJECT_DIR/.venv で管理されているところに、今から Pipenv を使うことにすることを仮定する。

普通は何らかのサードパーティー製パッケージが仮想環境にインストールしてあり、その一覧を $PROJECT_DIR/requirements.txt に記録してあるはずだ。この目録ファイルから Pipenv 仮想環境を構築することが可能だ。次のようにする:

旧環境から pipenv install を実行して新環境を造る
$ cd $PROJECT_DIR
$ deactivate
$ pipenv install -r ./requirements.txt
Creating a Pipfile for this project...
Requirements file provided! Importing into Pipfile...
Pipfile.lock not found, creating...
Locking [packages] dependencies...
Building requirements...
Resolving dependencies...
✔ Success!
Locking [dev-packages] dependencies...
Updated Pipfile.lock!
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
Installing dependencies from Pipfile.lock...

Tip

万が一ファイル requirements.txt がない場合には pip freeze を実行しろ。

紛れがないように旧環境を廃棄しておきたい:

旧環境の管理ディレクトリーを廃棄する
$ rm -rf .venv

Important

これでプロジェクトに出入りするたびにコマンド source .venv/bin/activatedeactivate を実行する習慣が廃止できた。

GitHub Actions などの CI/CD 環境が requirements.txt をまだ必要とする場合があるので、削除したいならばその点を確認してから行え。

仮想環境を作動させる

コマンド単発ならば pipenv run command を実行する。依存パッケージが備えているスクリプト実行や make などの処理をラップ実行する。

実行したいコマンドが複数続く場合には pipenv shell を実行することで仮想環境に「入る」ことになる。概念としては venvsource .venv/bin/activate に等しい。このサブシェルで依存パッケージのスクリプトや make を実行する。

PipfilePipfile.lock

ファイル Pipfile.lockpip を用いる Python プロジェクトで使われている requirements.txt を洗練させ、最後にロックされたパッケージのハッシュを追跡するという安全保障上の改良点を加えたものだ。このコマンドを含むロック動作がこのファイルを管理する。

依存パッケージを更新する

パッケージ自体とパッケージ管理ファイルを混同しないように、関連コマンドをまとめておく:

pipenv lock

ファイル Pipfile.lock を生成する。

これはファイル Pipfile の内容に基づいて、Pipfile.lock の依存関係すべてを最新の解決済みバージョンに更新する。

pipenv sync

Pipfile.lock で指定されたパッケージすべてを(依存関係を込めて)仮想環境にインストールする。

Pipfile.lock 自体を変更しない。

pipenv update

指定された依存関係と部分依存関係に限って lock を更新する。パッケージをインストールする。

pipenv upgrade

指定された依存関係と部分依存関係に限って lock を更新する。パッケージをインストールすることはしない。

GitHub Actions などの CI/CD 環境が requirements.txt を必要とする場合、次のようにしてパッケージ一覧を更新することが可能だ(オプションは好みで):

Pipenv の情報から requirements.txt を更新する
$ cd $PROJECT_DIR
$ pipenv requirements --exclude-markers > requirements.txt

ロック

GitHub Actions などの CI/CD において、次の Pipenv コマンドが実行されないように注意しろ。これらは Pipfile.lock を再構築する:

  • lock

  • update

  • upgrade

  • uninstall

  • install; install --deploy は可

操作集

先述のもの以外のコマンド pipenv のコマンドラインでの実行例を挙げていく。以下、作業ディレクトリーパスはプロジェクトの Pipfile などが置かれているのと同じとする。

サブコマンドなしの操作集

pipenv --where

このノートでいう $PROJECT_DIR の完全パスを出力する。

pipenv --venv

仮想環境を管理するディレクトリーパスを出力する。

pipenv --envs

設定済みの Pipenv 環境変数を一覧する。環境変数については後述。

pipenv --rm

仮想環境を消す。

pipenv --man

pipenv のマニュアルを出す。なぜか man pipenv ではダメだ。

pipenv --support

GitHub Issues にバグを報告するときに添える情報を出力する。

仮想環境に依存パッケージを追加的にインストールする

PipfilePipfile.lock が生成されている仮想環境にさらなるパッケージを加えるには、インストールコマンドをパッケージを指定して実行する:

パッケージを追加的にインストールする例
$ pipenv install ANOTHER_PACKAGE
Installing ANOTHER_PACKAGE...
Resolving ANOTHER_PACKAGE...
Added ANOTHER_PACKAGE to Pipfile's [packages] ...
✔ Installation Succeeded
(略)

依存パッケージ集合の依存関係を示す

コマンド pipenv graph が基本形で、ここに出力オプションを指定する。

フラグ

出力

--bare

最小(おそらく既定)で

--json

JSON で

--json-tree

JSON を入れ子の木で

--reverse

依存関係を逆にしたグラフで

Pipfile.lock から依存パッケージのバージョン情報を直接見るのがわずらわしいので、このコマンドを利用することでそれを見るということをしがちだ。

依存パッケージのモジュールをテキストエディターで開く

コマンド pipenv open を実行すると、モジュール名を指定して Python ファイルを開く機能がある。意外に便利である可能性がある。

コマンド pipenv open 実行例
$ pipenv open sphinxcontrib.mermaid
Opening '/path/to/.venv/lib/python3.12/site-packages/sphinxcontrib/mermaid.py' in your EDITOR.

仮想環境から現在未使用のパッケージを消去する

依存パッケージのバージョン変更や追加削除を繰り返していると、なんらかのパッケージがいつの間にか不要になっている場合がある。それを片付けるにはコマンド pipenv clean を用いる:

pipenv clean 実行例
$ pipenv clean
Uninstalling UNUSED_PACKAGE...

依存パッケージをアンインストールする

依存パッケージをアンインストールするにはコマンド pipenv uninstall をパッケージ名を指定して実行する。例えば:

依存パッケージをアンインストールする例
$ pipenv uninstall SOME_PACKAGE
Removed SOME_PACKAGE from Pipfile.
Building requirements...
Resolving dependencies...
✔ Success!
Uninstalling SOME_PACKAGE...
Found existing installation: SOME_PACKAGE x.y.z
Uninstalling SOME_PACKAGE-x.y.z:
  Successfully uninstalled SOME_PACKAGEa-x.y.z

構成

Pipenv はドットファイルから既定値を読み込むような設計ではないないらしい。ただし、仮想環境に入るコマンド pip runpip shell は、プロジェクトディレクトリーにあるファイル .envsource する。

Pipfile[scripts] 区画にコマンド定義しておくという手法があるが、ここでは割愛する。

Pipenv は名前が PIPENV_ から始まる独自の環境変数群を利用する。今のところ、これを明示的に定義したいというものは見つからない(キャッシュパスも既定値が適切)。

運用

  • PipfilePipfile.lock の両方をプロジェクトのバージョン管理ファイル集合に加える。

  • 作業場では定期的に pipenv update を行い、依存パッケージを最新に保つように努める。

  • 依存パッケージを更新したことでプロジェクトのビルドが失敗する場合、 Pipfile.lock を前のバージョンに復元して pip sync することで依存パッケージ群を復元可能。

  • CI/CD のビルド工程では、ファイル Pipfile.lock を変更するようなコマンドを通常実行しない。

資料

Pipenv documentation

公式サイト。インストール方法から基本的な利用方法、応用等が文書化されている。

venv — Creation of virtual environment

Python 標準の仮想環境モジュール venv についての文書。このページの API 節の直前まで目を通せ。