😎

Python環境およびPython製アプリ

2024/04/19に公開

これは,システム管理者と,一般ユーザの戦いである.

ユーザはシステムを使うことはできるが,いじれない.管理者のみがいじれる.

ユーザは,そんなシステムに入っているPythonのパッケージに不満がある.

  • 使いたいパッケージが無い
  • 使いたいパッケージのバージョンが無い

ユーザは,そんなときどうするか?管理者にパッケージを入れろと言ってくる.
パッケージの依存関係などお構いなしに.管理者としては到底受け付けられない.

ユーザは,仕方ないので自分のホームにパッケージを入れる.
pipは,--userをつければよい.ホームにsite-packagesが用意され,以降,pythonはホームのsite-packages,システムのsite-packagesのどちらも探索する.

$ pip install --user foo

fooを入れようとすると,依存関係で芋づる式にbarhogeも入れようとする.
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. pyenvmiseなどで新たな環境

  • ホームのpython_{u} : pyenvmiseなどでシステムと別個に新たに用意
  • ホームのsite-packages_{u} : python_{u} の探索範囲
$ mise install python@latest # @以下はバージョン
$ mise use -g python@latest

ちなみに,

ちなみに,@system というバージョンは特別であり,python_{u}として,「環境変数PATHによって見つけたpython」を設定する.

これは,systemではあるが,必ずしもシステム側のpython_{s}ではない.
あくまで「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_uが使われるが,あとで競合するぜ.

[recommended] (pkg1) python -m pip install foo

先と同様に,ホームのpython_uやシステムのpython_sを使うのではなく,python_{pkg1}を使うとよい.

case3. python_{u}またはpython_{s} で作る仮想環境

$ python -m venv pkg1 # このpythonはホームまたはシステムのもの
$ source pkg1/bin/activate
(pkg1) $ python -m pip install foo

case4. poetryryeなどを使う

結局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を持つpythonsite-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型.pipxvenvで入れるのがいいかもね.

まとめ

  • 普段使いも,開発でも,アプリインストールでも,独自のpythonを使う.
  • それぞれに独自pythonを用意するアプリがある.
    • 普段使い:pyenv, mise
    • 開発:poetry, rye
    • アプリインストール:pipx
  • 呼び出すpythonsite-packagesがどれなのか意識する.
GitHubで編集を提案

Discussion