PipenvのPipfile.lockを作らない運用

2019年6月4日火曜日

前回、pipenvの簡単な使い方とvirtualenvからの改善点を紹介した後に、弱点としてPipfile.lockの作成時間をあげました。
実際、どれくらい遅いのか。

試してみました。 
$ pipenv install jupyter keras tensorflow matplotlib

Kerasを使ってディープラーニングを行うシンプルな環境ですが、手元の環境で試したところ、インストールの7分に対し、ロックには26分かかりました。
インストールもまあ長いのですが、これはこの手のものを使う際には仕方がないです。
こういうものです。
しかし、このロックにかかる時間に関してはpipenv特有のものです。
個人的にちょっと常用するには厳しい待ち時間だと感じます。
そこでPipfile.lockの作成を避ける運用を考えてみます。

pipenv installにはPipfile.lockを作成しないようにするオプション--skip-lockが存在します。
ただ、Pipfile.lockの役割である依存パッケージを含んだパッケージ群のバージョンの固定は必要なものです。
そこでこの用途にはpip freeze > requirements.txtを使うことにします。
pipenv install -r requirements.txtとすることでpipenvでもrequirements.txtからインストールすることは可能です。
なので、pipenv install時に必ず--skip-lockを付けて、インストール後に忘れずにpipenv run pip freeze > requirements.txtをすれば、ロック処理の回避とバージョンの記録という目的が果たされるわけです。

入力の手間やfreezeをやり忘れる問題が出てきますので、シェルスクリプトを書いてエイリアス登録します。

(~/bin/pipenv_install.sh)
#!/bin/sh
pipenv install --skip-lock "$@"
pipenv run pip freeze > requirements.txt 

スクリプトを実行可能にします。
$ chmod a+x ~/bin/pipenv_install.sh

.zshrcや.bashrcにエイリアス登録しましょう。
$ alias pipenv_install='~/bin/pipenv_install.sh'

これで

$ pipenv_install hogehoge 
というように使えるようになります。


githubに上げる場合はREADME.mdに次のようにでも書いておきましょう。
あくまでPipfile.lockは作成させないつもりです(^ ^)

## Install
```
$ pipenv install --skip-lock -r requirements.txt
``` 

ちなみに-rでインストールするとPipfileがrequirements.txtの内容で上書きされます。
上書きされたPipfileでは依存パッケージを含め、全パッケージがバージョン込みで並列に記載されます。
(Pipfile)
 :
[packages]
absl-py = "==0.7.1"
appnope = "==0.1.0"
astor = "==0.7.1"
attrs = "==19.1.0"
backcall = "==0.1.0"
bleach = "==3.1.0"
 :
 :

requirements.txtから作成されたPipfileを書き直す場合にはpipenv grapheを使うとよいでしょう。
$ pipenv graph
jupyter==1.0.0
  - ipykernel [required: Any, installed: 5.1.1]
    - ipython [required: >=5.0.0, installed: 7.5.0]
 :
Keras==2.2.4
  - h5py [required: Any, installed: 2.9.0]
    - numpy [required: >=1.7, installed: 1.16.3]
 :
 : 

トップレベルのパッケージだけ抜き出して、バージョン表記を書き換えます。

(Pipfile)
 :
[package]
jupyter = "*"
Keras = "*"
 :
 : 
こうするとpipenv install [package names]で作成されるPipfileに近いものに書き直すことができます。
pipenv updateでパッケージのアップデートも可能になります。
Pipfile.lockはできてしまいますが。
ロックを回避する場合は仮想環境を削除して、pipenv_install(pipenv install --skip-lock)ですね。
全パッケージが再インストールになりますが、たぶんこっちのほうが速いかも。

以上です。
pipenv使っていきましょう。