Python環境およびPython製アプリ
これは,システム管理者と,一般ユーザの戦いである.
ユーザはシステムを使うことはできるが,いじれない.管理者のみがいじれる.
ユーザは,そんなシステムに入っているPythonのパッケージに不満がある.
- 使いたいパッケージが無い
- 使いたいパッケージのバージョンが無い
ユーザは,そんなときどうするか?管理者にパッケージを入れろと言ってくる.
パッケージの依存関係などお構いなしに.管理者としては到底受け付けられない.
ユーザは,仕方ないので自分のホームにパッケージを入れる.
pipは,--userをつければよい.ホームにsite-packagesが用意され,以降,pythonはホームのsite-packages,システムのsite-packagesのどちらも探索する.
$ pip install --user foo
fooを入れようとすると,依存関係で芋づる式にbarとhogeも入れようとする.
barはシステム側に既に存在しているが,必要なバージョンが異なるので,別のbarも入れる.
hogeもシステム側に既に存在し,こちらはそれでよいから,ホームには入れない.
あるときfooのバージョンが上がって,依存関係もアップデートされた.またシステムとホームのせめぎ合いだ.
1. python_{user} のすゝめ:ユーザは,システムに面従腹背するか,システムに不満があるならホームで完結せよ.
ということで,システムのsite-packagesを探索しないようにすることを勧められる.
いわゆる PEP668 である.
[un-recommended] python -m pip install --user foo
これをやめる事を薦められている.システムによっては許されない場合がある.強引にやるなら,さらに--break-system-packagesをつける.野蛮だ.
[recommended] ~/.local_python/bin/python -m pip install foo
ホームのsite-packagesだけを探索するようにする最もリーズナブルな方法は,独自のpython を使い,システム側のpythonを使わないということである.
case1. python_{s} で作る仮想環境
- ホームの
python : システムの_{u} python のコピーのようなもの_{s} - ホームの
site-packages :_{u} python の探索範囲_{u}
$ python -m venv ~/.local_python # このpythonはシステムのもの(venvも)
$ cat 'export PATH="~/.local_python/bin:$PATH"' >> ~/.zshrc # 以降,pythonはホームのもの
$ source ~/.zshrc
case2. pyenvやmiseなどで新たな環境
- ホームの
python :_{u} pyenvやmiseなどでシステムと別個に新たに用意 - ホームの
site-packages :_{u} python の探索範囲_{u}
$ mise install python@latest # @以下はバージョン
$ mise use -g python@latest
ちなみに,
ちなみに,@system というバージョンは特別であり,pythonpython」を設定する.
これは,systemではあるが,必ずしもシステム側のpython
あくまで「PATHで設定されたpython」,つまりは,case1のように仮想環境にpythonを作って,そのpythonがPATHから見つかるように設定されていれば,@systemは仮想環境のpythonを指す.
(PATHからpythonを見つけることができないならば,@systemは何も見つけられない.設定はできるが,実際にpythonコマンドを起動しても
mise No version is set for shimとなるだけ.)
単なるpythonコマンドがどのPythonなのかを管理するのはとても大切である.
2. python_{dev} のすゝめ:開発環境は,それぞれ自己完結に(他の誰にも依存しない)
ユーザも,プログラミング課題に取り組む際には,開発側から見て,先のシステムVSユーザの関係に同等となる.
複数のユーザに対応する管理者が如く,
課題で必要なsite-packagesは,別の課題で必要なsite-pacagesと競合し,さらにはホームのsite-packagesともせめぎ合う.
ということで,開発環境ごとに,それぞれ自己完結させたほうがいい.
[un-recommended] python -m pip install foo
やめたほうがいい.PEP668のように怒られず,すんなりsite-packages
[recommended] (pkg1) python -m pip install foo
先と同様に,ホームのpythonpythonpython
case3. python_{u} またはpython_{s} で作る仮想環境
$ python -m venv pkg1 # このpythonはホームまたはシステムのもの
$ source pkg1/bin/activate
(pkg1) $ python -m pip install foo
case4. poetryやryeなどを使う
結局case3と同じように仮想環境を作るのだけれども,case3よりパッケージ開発に向いている.
$ poetry new pkg1
$ cd pkg1
$ poetry env use ~/.local_python/bin/python # どのpythonを使うか
$ poetry add foo
$ poetry install --sync
$ poetry version major/minor/patch
3.python_{app} のすゝめ:pip install appで入れるアプリ
インストーラであるpip,引いてはそのpipを持つpythonのsite-packagesと競合する可能性がある.PEP668
なので,これもアプリ独自のpythonで入れたほうがよい.
[un-recommended] python -m pip install app
まぁ,やっちゃうけれど.
[recommended] (venv_app) python -m pip install app
case5. 仮想環境を用意する.
先と同様.
$ python -m venv ~/.local/venv_app # このpythonは,システムだったりホームだったり
$ ~/.local/venv_app/bin/python -m pip install app
$ export PATH="~/.local/venv_app/bin:$PATH"
case6. pipxを使う
venvを生で使うより,扱いやすい.
$ pipx install app --python ~/.local_python/bin/python # どのpythonを使うか
$ pipx ensurepath
ちなみに,pipx自体もpip install型.pipxはvenvで入れるのがいいかもね.
まとめ
- 普段使いも,開発でも,アプリインストールでも,独自の
pythonを使う. - それぞれに独自
pythonを用意するアプリがある.- 普段使い:
pyenv,mise - 開発:
poetry,rye,uv - アプリインストール:
pipx,uv tool
- 普段使い:
- 呼び出す
python,site-packagesがどれなのか意識する.
Discussion