pythonのパッケージマネージャ&仮想環境マネージャの一覧というより歴史
色々出てきて解らんとか林立してるとか言ってるひとがいたので大雑把にまとめた。
より詳しくは、他の誰かさんが書いた資料が山ほどあるので参照されたい。
仮想環境
python本体には、OSの環境変数を参照して環境を切り替える機構がもともと入っている。
ここでいう”環境”とは、ライブラリ構成、python本体のバージョン等の組み合わせを示す。
適当なディレクトリに必要なファイル群を全て集めて、環境変数を適切に設定すればpythonがそこのファイルを優先して参照してくれる。
かくしてホストOSに極力影響をあたえず、python固有の環境を切り替えることができるというわけだ。
virtualenv : 2007
これを実装したもので、もっとも古い世代のものがvirtualenvである。
これらのツールは、厳密な意味では「”仮想環境”の構築」しかしてないことに注意してほしい。
$ virtualenv $ENV_DIR
source ほにゃららをよくやってるが、あれは、シェルに仮想環境用の環境変数を取り込むための御呪いである。これでようやく、”仮想環境”の切り替えをしたことになる。
$ source $ENV_DIR/bin/activate
シェル環境変数の更新方法は、こうする以外にも幾つか方法はあるのだが、「トレードオフ的にsourceを使ってる」と解釈することをお勧めする。
PEP405 : 2011 標準化の提案
virtualenvにより仮想環境の理由が定着したが、さらに標準化が提案された。 PEP405である。
やろうとしてることはvirtualenvと変わらない。
venv : 2012 python3.3本体への同梱
このPEP405準拠の、python.org標準の仮想環境マネージャがvenvである。
$ python3 -m venv $ENV_DIR
これにより、2023年現代において、わざわざ virutalenv を使う意義はほぼない。
pyenv : python本体バージョンの使い分け
どうもvirutalenv等と一緒に紹介されてることが多いようなので扱わざるをえないのだが、これだけ毛色が違う。
パッケージマネージャでは少なくともないし、仮想環境マネージャというのには語弊がある。
シェルスクリプトによるpython本体の切り替えツール。 rubyのrbenvに影響を受けたと言ってる。
venvではあくまで環境構築をするだけで、シェルへの環境変数のとりこみは手動である。
それをpyenvでは隠蔽している。
venvも含めて、本来はシェルおよび環境変数に関する深い理解が必要な行為である。
pyenvのドキュメントに、PATHについての説明も書かれている。
故に、virtualenv/venvとの組み合わせでは失敗例も散見する。
あくまで小生の個人的な意見を言わせてもらえば、
python以外の環境に影響を与えないように控えめなvenv/virutalenvに対して
動的にPATHを変更しまくるpyenvのほうが「やりすぎ」ている。
故に、pyenv側からvenvへの帳尻を合わせる方法が存在している。
パッケージマネージャ
第3者の作成したpythonパッケージについての、python.org標準リポジトリとしては PyPI · The Python Package Index があり、大抵のパッケージマネージャはこれを想定している。
ただ肝心の”パッケージマネージャ”本体については、昨今ではかなり欲張りなコマンドラインツールが増えたため、たんに”パッケージマネージャ”と呼ぶだけでは不明確な場合が出てきている。
またさらに話をややこしくしているのが、これらの”パッケージマネージャ”が、前述の仮想環境をサポートしていることだ。(仮想環境の作成機能はもたない場合もある)
pip : 15years ago
日本語の記事ではパッケージマネージャ/パッケージ管理ツールです。と紹介されることが多いが、正しくは package installer である。
PyPA Projects の成果物であり、オフィシャルでもそう書いてある。
よくある requirements.txt を使うのはこいつである。
本質的には”インストーラ”であり、さらに大昔のソースを毎回ビルドしてた頃の easy_install を代替するためとある。
githubで辿れる最古バージョン 0.3 のドキュメントに書いてある。
また virtualenv にも対応してるとこの時点で明記してる。
昔は単独コマンドラインだが、python3.4以降では同梱パッケージになっている。
python3 -m pip で使うのが御作法。
なぜ "pip" なのか?と思ったが、あちこちに "PIP install package"だと書いてある。
こういう再起的命名はオープンソースだとよくある。例えば GNUがそうなのだが、pipについてのオフィシャルでは見当たらない。
いちおう 前出の 0.3 のドキュメントをみたが見当たらず。
pipのサイトでは、"package installer for Python."であると書いてるから、もうこっちで良いではないだろうか。
全部入り
前述のpipは複数パッケージの依存解決はもっており、実用には十分である。
ただ事実上venvと組み合わせて使われることが多く、煩雑になってきたという需要がある。特に pipenv では「もう別々に使わなくて良いのです」と言ってる。
pipenv 2017
PyPAによる事実上オフィシャル。
You no longer need to use pip and virtualenv separately: they work together.
単純に、pip+virtualenvを内包してますというだけと言えなくもない。
Pidfileなるtomlファイルを記述する。
[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true
name = "pypi"
[packages]
requests = "*"
[dev-packages]
pytest = "*"
非オフィシャル poetry
poetryは非オフィシャルのパッケージ関連ツールだが、パッケージビルダーをも内蔵してるため、非常に複雑なものである。
故にこれを「パッケージマネージャです」と紹介するのは語弊がある。
前述のライブラリ&パッケージ類は全て単一のgithubリポジトリであった。だがpoetryには複数のリポジトリで構成されているのがわかるだろう。
むしろ「pythonパッケージ開発の第3者SDK」ぐらいに思ってた方が語弊が少ないかもしれない。
pipenvと同じくtomlだが、poetryはより記述が複雑化しており、互換性は全くない。
[tool.poetry]
name = "my-package"
version = "0.1.0"
description = "The description of the package"
license = "MIT"
authors = [
"Sébastien Eustace <sebastien@eustace.io>"
]
repository = "https://github.com/python-poetry/poetry"
homepage = "https://python-poetry.org"
# README file(s) are used as the package description
readme = ["README.md", "LICENSE"]
# Keywords (translated to tags on the package index)
keywords = ["packaging", "poetry"]
[tool.poetry.dependencies]
# Compatible Python versions
python = ">=3.8"
# Standard dependency with semver constraints
aiohttp = "^3.8.1"
# Dependency with extras
requests = { version = "^2.28", extras = ["security"] }
# Version-specific dependencies with prereleases allowed
tomli = { version = "^2.0.1", python = "<3.11", allow-prereleases = true }
# Git dependencies
cleo = { git = "https://github.com/python-poetry/cleo.git", branch = "master" }
# Optional dependencies (installed by extras)
pendulum = { version = "^2.1.2", optional = true }
# Dependency groups are supported for organizing your dependencies
[tool.poetry.group.dev.dependencies]
pytest = "^7.1.2"
pytest-cov = "^3.0"
# ...and can be installed only when explicitly requested
[tool.poetry.group.docs]
optional = true
[tool.poetry.group.docs.dependencies]
Sphinx = "^5.1.1"
# Python-style entrypoints and scripts are easily expressed
[tool.poetry.scripts]
my-script = "my_package:main"
お勧めは
2023の現代では、pipenvで十分だろう。
python パッケージを利用するだけのひとが poetry を使っても”メリット”は少ない
林立してるように見えるのは、venvがでてobosleteになったはずの virtualenvをいまだに使ってる記事が多いからだろう。
ちなみにlinux歴20年の小生は、生のpipを使っていて全く不自由してないことを強調しておく。
参考 IDEの仮想環境サポート
例えば jetbrain pycharmでは、venv仮想環境を直接サポートしているので、直接前述のコマンドラインを使うことはあまりないと思われる。
Discussion