Pipenv をやめて venv を使いだした話
Posted on 2020/10/11 in tech
tl;dr
仮想環境の作成
Python の開発には組み込みの venv で閉じた環境(仮想環境)を作成できる。
環境の自動化
direnv を入れればカレントディレクトに応じて activate/deactivate を自動化できる。
これは .envrc
に
layout python
を書けばいい。
Python バージョンを指定した仮想環境の作成
任意の Python バージョンを指定したい場合、pyenv を使う。
インストール済なら .envrc
を
layout python ~/.pyenv/versions/3.X.X/bin/python
のように Python のパスを末尾に書けば、3.X.X
のバージョンで仮想環境が作成される。1
依存ライブラリの管理
依存ライブラリのバージョン固定には pip-tools を使う。
これは仮想環境ごとにインストールする。
$ pip install pip-tools
これにより、pip-compile
, pip-sync
コマンドが利用可能になる。
requirements ファイルを生成するためには、
依存ライブラリを requirements.in
といったテンプレートファイルに
pelican
markdown
のように書いておき、
$ pip-compile requirements.in
すれば requirements.txt
に依存ライブラリが出力される。
#
# This file is autogenerated by pip-compile
# To update, run:
#
# pip-compile requirements.in
#
blinker==1.4 # via pelican
docutils==0.16 # via pelican
feedgenerator==1.9.1 # via pelican
jinja2==2.11.2 # via pelican
markdown==3.3 # via -r -
markupsafe==1.1.1 # via jinja2
pelican==4.5.0 # via -r -
pygments==2.7.1 # via pelican
python-dateutil==2.8.1 # via pelican
pytz==2020.1 # via feedgenerator, pelican
six==1.15.0 # via feedgenerator, python-dateutil
unidecode==1.1.1 # via pelican
ハッシュチェックモード を利用したければ、--generate-hashes
オプションを付与する。
$ pip-compile --generate-hashes requirements.in
出力にハッシュが追加されることがわかる。
blinker==1.4 \
--hash=sha256:471aee25f3992bd325afa3772f1063dbdbbca947a041b8b89466dc00d606f8b6 \
# via pelican
docutils==0.16 \
--hash=sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af \
--hash=sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc \
# via pelican
....
当然ながら、生成されたファイルを利用して pip install
できる。
$ pip -r install requirements.txt
pip-sync
コマンドは環境を prune にしたいときに使う。
$ pip-sync requirements.txt
これによって、requirements.txt
に記載のライブラリで足りてないものがあればインストールされ、不要なものがあれば、すべて削除される。
2, 3 年前から Pipenv を使っていた。Python はメインの業務で使っているわけではないので、こんなものかと思っていたが、いまいち馴染まなかった。
npm をむりやり Python に持ち込んだ感じというか、ゴテゴテしてるなというか。
でも「今はこっちが主流なんだよな」と思っていた。virtualenv のスターに比べ、Pipenv のスター数は圧倒的2なわけだから。
だけれどもインストールが遅いとか3 docker イメージ化が簡単にできない4 とか騙し騙しやってる自分のことをいよいよ騙せなくなっていた。
「オフィシャルで推奨されるツール」だと思っていたら違った
そんなこんなでモヤモヤしていたら決定的な記事を見つけてしまった。
Pipenv: promises a lot, delivers very little | Chris Warrick
2018 年の記事ながら、今年(2020 年)にも更新されている。
記事タイトルの直訳が
「Pipenv: 多くのことを約束し、とても僅かなものをもたらした」
となるあたりからも察するになかなか辛辣である。
下記引用部分が、すべてを語っている。
“Pipenv — the officially recommended Python packaging tool from Python.org, free (as in freedom).”
Pipenv’s README used to have a version of the above line in their README for many months: it was added on 2017-08-31 and eventually disappeared on 2018-05-19. For a short while (2018-05-16), it was clarified (managing application dependencies, and PyPA instead of Python.org), and for about 15 minutes, the tagline called Pipenv the world’s worst or something along these lines (this coming from the maintainer).
(意訳)5
“Pipenv - Python.org から公式に推奨される Python パッケージツールで、フリー(そして自由)”
Pipenv の README はかつてしばらくのバージョンにおいて、上記の言葉を README に含めていました: それは 2017-08-31 に追加され、最終的に 2018-05-19 で削除されました。僅かな期間(2018-05-16)、(アプリケーションの依存関係の管理や、Python.org に代わって PyPA がそれを行っていることが)明確化され、また約 15 分間のタグライン上で、Pipenv は 世界最悪 もしくはこ れ ら の言葉で呼称されました(これはメンテナ由来のものです)。
メンテナに 世界最悪 って書かれちゃうのってなんやねん。
上記の引用だとわかりにくいけれど、
の部分は 1 単語に 1 リンクがついていて、Pipenv ドキュメントにおける悲劇のコミットログをみることができる。
Pipenv — the tool for managing application dependencies from
PyPA
__, free (as in freedom).
→ Pipenv - Python.org から公式に推奨される Python パッケージツールで、フリー(そして自由)
Pipenv — the absolute worst available today for managing your Python application dependencies.
→ Pipenv - こんにち、Python アプリケーションの依存管理をするために利用できる絶対的最悪なもの
Pipenv — the absolute worst available today for managing your application dependencies.
→ Pipenv - こんにち、アプリケーションの依存管理をするために利用できる絶対的最悪なもの
(Python という括りが外されている)
Pipenv — the world's worst Python application dependencies workflow tool™.
→ Pipenv - 世界最悪の Python アプリケーション依存管理ワークフローツール™
右肩にある TM とは、トレードマークのことである。
Pipenv — the world's most opinionated Python application dependencies workflow tool™.
→ Pipenv - 世界でもっともこだわりのある Python アプリケーション依存管理ワークフローツール
「こだわりのある」(opinionated) にも皮肉が込められているのだろう。
記事中で触れられているのだが、これらのタグラインの変更は Reddit のやりとりに由来するものらしい。
Why is pipenv the recommended packaging tool by the community and PyPA? : Python
Python とパッケージ管理
Pipenv の気持ちはわかる。おそらくだが、Node.js の npm や PHP の composer みたいなパッケージ管理をイメージしたのだろう。
こう書くと敵をつくりそうだが、Python コミュニティは質が高いと感じる事が多い。
質が高い、という意味が何を指すかは人それぞれだろうが、少なくとも追加される機能は厳選され、スクリプト言語の手軽さ・多機能さを保ちつつシンプルであり続ける姿勢を勝手に感じている。
まぁ勘違いかもしれないが、少なくともいつも「いいな」とは思う。
個人的に Django が好きだが、Python という言語仕様以前に、Python 界で共有される思想ゆえの整然とした世界故に生まれたフレームワークだと思っている。
よって、徒に他の言語から同じ思想の仕組みを持ち込もうとしても、うまくいかないだろう。
大衆受けしているものがベストかはわからないし、Python に他言語の文化をほぼそのままの形に持ち込めるかというと、それも違うように思う。
venv: 標準の仮想環境
一度 virtualenv に戻ったけれど、どうやら venv というものが組み込み(stdlib)のライブラリ として Python 3.3 からから利用できるらしい。
Python 3.9 がリリースされたばかり7 だが、どんだけ取り残されてたんだ。。。
venv は virtualenv のサブセットらしい。 言い換えれば少なからず、virtualenv の方が認められたということだろう。違いについては、我らが Stack Overflow が参考になった。
ベストアンサー の回答者は virtualenv 推しのようだけれど、個人的には venv で十分である。バージョン切り替えなんぞは、必要になったときだけ pyenv 等その他のツールを使えばよい。
venv が virtualenv のサブセット である、ということ一つとっても、Python コミュニティかくありや、と思わずにいられない。それは 1 つのことをうまくやろうとする UNIX 哲学 に通じるものであるし、そうあるべきものだと思う。
記事執筆中に、direnv が仮想環境の作成に virtualenv を利用している、と wiki に書いてあった ので、 そんなことあるんかいな、と思ったら、issue が立っていた。
そしてよくよく読んでみると、direnv v2.21.0 以降から venv
を優先して使うコードが 2019/08/04 にマージされている。
1 年以上 wiki が古い内容のままだったということである。直そうよ…
と文句を言っても仕方ないので、直しておいた。正直英語に自信がないので、変なところあったらそっと直してほしいです。
-
事前に
pyenv install 3.X.X
のように任意の Python バージョンをインストールしておく必要がある。詳しくはREADME を参照されたし。 ↩ -
2020/10/08 現在、virtualenv のスター数 3.7k に対し Pipenv のスター数は 21k とある ↩
-
pipenv install is very slow · Issue #356 · pypa/pipenv, Lock updating is very slow · Issue #1914 · pypa/pipenv ↩
-
Generate requirements.txt from Pipfile.lock · Issue #3493 · pypa/pipenv ↩
-
意訳頑張ったけど自己流の解釈してるので、明らかに間違いな場合コメントいただけるとありがたい ↩