Closed15

Python asdf + poetryからryeへの移行記録

Hiroya-WHiroya-W

今までasdf Python pluginでPythonインタプリタをインストールし、プロジェクトはpoetryを使って管理していた。
新しくryeというツールが出たのでこれに移行する方法を考えたい。

Hiroya-WHiroya-W

とりあえず、ドキュメント通りにmacOSにryeをインストールし、パスを通す。

curl -sSf https://rye-up.com/get | bash

fishを使っているので、パスはconfig.fishにこんな感じになっている。

fish_add_path $HOME/.rye/shims

# source asdf
source $HOMEBREW_PREFIX/opt/asdf/libexec/asdf.fish
Hiroya-WHiroya-W

この状態で、ryeでプロジェクトを作ってPythonプロジェクトを作ってみる。

rye init rye_example
cd rye_example
rye pin 3.11
rye sync

この状態でPythonからはrye_exampleライブラリが見える見えるようになる。

rye run python
>>> import rye_example
>>> 
Hiroya-WHiroya-W

さて、問題はここから。

Correctly installed, rye will automatically pick up the right Python without manually activating the virtualenv. That is enabled by having ~/.rye/shims at higher priority in your PATH. If you operate outside of a rye managed project, the regular Python is picked up automatically.

とあるので、rye runを省略してもvirtual env内のPythonインタプリタが指定されていてほしいがなっていない。

$ rye run python
Python 3.11.3 (main, May  7 2023, 17:43:38) [Clang 16.0.3 ] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> ^D

$ python
Python 3.8.15 (default, Jun  2 2023, 15:25:38)
[Clang 14.0.3 (clang-1403.0.22.14.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>

現状のpythonコマンドはryeのものではなく、asdfのものを指してしまっている。

$ which python
/Users/hiroya/.asdf/shims/python

これは PATHの優先順位が良くない。

$ printenv PATH
/Users/hiroya/.asdf/shims:/opt/homebrew/opt/asdf/libexec/bin:/Users/hiroya/.rye/shims
Hiroya-WHiroya-W

config.fish でasdfより後でfish_add_pathしてみる。

# source asdf
source $HOMEBREW_PREFIX/opt/asdf/libexec/asdf.fish

fish_add_path $HOME/.rye/shims

が、優先順位が変わらない...?

$ printenv PATH
/Users/hiroya/.asdf/shims:/opt/homebrew/opt/asdf/libexec/bin:/Users/hiroya/.rye/shims
Hiroya-WHiroya-W

config.fishで読み込んでいるasdf用のfish script、この中身でPATHを追加しているが

cat $HOMEBREW_PREFIX/opt/asdf/libexec/asdf.fish

if type -q fish_add_path
  if test -n "$ASDF_DATA_DIR"
    fish_add_path --global --move "$ASDF_DATA_DIR/shims" "$ASDF_DIR/bin"
  else
    fish_add_path --global --move "$HOME/.asdf/shims" "$ASDF_DIR/bin"
  end
...

うーん、この--moveによって先頭になっているのが問題な気がする。fishのドキュメントにもあるように、

If --move is used, it may of course lead to the path swapping order, so you should be careful doing that in config.fish.

あまり積極的に使うのはよろしくないのを理解しつつ、ryeも--moveをつけることにする。

config.fish
# source asdf
source $HOMEBREW_PREFIX/opt/asdf/libexec/asdf.fish

fish_add_path --move $HOME/.rye/shims
$ printenv PATH

/Users/hiroya/.rye/shims:/Users/hiroya/.asdf/shims:/opt/homebrew/opt/asdf/libexec/bin

並びはいい感じになった。

Hiroya-WHiroya-W

これで python

$which python
/Users/hiroya/.rye/shims/python

になった。よし。これで、ryeで作ったPythonプロジェクト内だと

$ cd rye_example
$ python -V
Python 3.11.3

のように、virtualenv内のPythonを指してくれる。Pythonプロジェクト外だと

$ cd
$ python -V
Python 3.10.11

のように、グローバルに見えるPythonインタプリタを指してくれる。こっちのPythonはasdf Pythonプラグインで管理しているPythonで、

asdf global python 3.10.11

としているのでこのPythonが見えるようになっている。

Hiroya-WHiroya-W

今まで、pyenvやasdfを使ったグローバルとローカルのPythonの切り替えは、ローカルに.tool-versions.python-versionなどのファイルを置き、それを参照することで切り替える事ができていた。しかし、Pythonインタプリタのバージョン自体を切り替える事はできても、ローカルにある仮想環境のパスを参照することはできなかった。
一方、pdmは、PEP582を使って仮想環境を作らずに、環境を切り替える方法というのが模索されていた。これは、__pypackages__ という特殊なディレクトリにライブラリをインストールし、Pythonインタプリタではそのパスを動的に追加してやるというもの(だと理解している)。ただ、このライブラリへのパスを追加するのはpdmがやっていたので、VSCodeなどエディタ側で利用するPythonインタプリタを指定してPythonを切り替えるという方法が使えなかった。

ryeはこれを解決するツールと言えそう。ryeで管理しておけば、コマンドは同じpythonだけど、以下のようなシームレスなPython環境が切り替えができるのはちょっと感動する。

$ cd rye_example
$ python
>>> import numpy as np # Pythonプロジェクト内ではnumpyライブラリをimportできる
>>> ^D

$ cd
$ python
>>> import numpy as np # Pythonプロジェクト外ではnumpyは入っていないPython環境になる(== プロジェクトが隔離されている)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'numpy'
Hiroya-WHiroya-W

これ書いていて知ったけど、pdmで使っているPEP582は取り込まない方針になっていたのか。
https://pdm.fming.dev/latest/#virtualenv-and-pep-582
https://discuss.python.org/t/pep-582-python-local-packages-directory/963/430

Virtualenv and PEP 582#
PDM offers experimental support for PEP 582 as an opt-in feature, in addition to virtualenv management. Although the Python Steering Council has rejected PEP 582, you can still test it out using PDM.

To learn more about the two modes, refer to the relevant chapters on Working with virtualenv and Working with PEP 582.

Hiroya-WHiroya-W

ryeはあくまでもPythonプロジェクト内のPythonだけ管理してくれるので、グローバルで使うようなPythonはryeとは別でインストールしてやる必要がありそう。
グローバルで使うPythonはバージョンを切り替えることはあまりしないとは思うが、これは従来通りpyenvやasdfなどでPythonをインストールしておけば良いと思う。

ややこしいが、ryeで作ったPythonプロジェクト内で使うPythonインタプリタはryeがインストールしたPythonを使うので、pyenvやasdfでインストールしたPythonは使わないということだけ気にしておけばいいだろう。

atu4403atu4403

rye install {package}とすることでグローバルにインストールすることができます。
これにより~/.ryeにインストールされます。内容を見るとpyvenv.cfgというファイルが作成されており、pythonのバージョン情報もあります。
なので未検証ですが、パッケージごとに違うバージョンを指定することも可能かと思います。

black等をグローバルにインストールしてpyenvは削除しましたが、今のところ問題なく動作しています。

Hiroya-WHiroya-W

コメントありがとうございます。rye install でインストールしたツールに関しては、pyenv必要なく動作できそうですね。Pythonのバージョンとパッケージを合わせて指定が可能になりそうなのは興味深いです。

ここで疑問に思っていたのは、rye init some_projectとした時、このsome_project内ではスタンドアロンのPythonバイナリを落としてきて使う事ができますが、このプロジェクト外ではどうなるのか、ということでした。
外部パッケージを必要とせず、全てbuiltinパッケージのみのPythonスクリプトを動かす場合、わざわざryeでプロジェクトを作る必要はないはずで、単にpython main.pyとして実行したいです。ここの、
https://zenn.dev/link/comments/6f3db67be8edc9

ryeで管理しておけば、コマンドは同じpythonだけど、以下のようなシームレスなPython環境が切り替えができる

のように、ryeプロジェクト外で使うためのPythonをどのように用意すれば良いのか、でした。僕の理解では、これはシステムのPython(UbuntuならaptでインストールしたPython)、もしくはpyenv、asdfなどでインストールしたPythonが必要になりそうだ、と思っています。

atu4403atu4403

ryeでインストールしたpythonをグローバルで使用するには以下のコマンドを実行します。

rye config --set-bool behavior.global-python=true

ただし、ryeのversion0.9.0で追加された機能なのでupdateの必要があるかもしれません。

rye self update

これにより~/.rye/shimsを参照したpythonを使うことができます。

> which python
/Users/myname/.rye/shims/python

別のversionのpythonを使うには以下のようにします。

> python +3.8 --version
Python 3.8.16
> python +3.9 --version
Python 3.9.16

ここまで手探りで調べましたが、直接versionを指定してグローバルにpythonをインストールする方法はわかりませんでした。
仮想環境を作成して使用したことのあるversionに関しては使えるようです。

Hiroya-WHiroya-W

おぉ!丁寧に調べていただいた情報をありがとうございます!
まさに欲しかった機能でした!!!asdfやpyenvと組み合わせるとなると、使い分けと構成がどうなっているのかを意識させられるのが少し辛かったのですが、これがあればもうryeだけで完結できて最高です!

Hiroya-WHiroya-W

asdf + poetryからryeへの移行というよりは、asdf + ryeへの移行という感じだろうか。

  • asdfはグローバルのPythonのインストール
  • ryeはPythonプロジェクト内で使うPythonのインストール

ただし、asdfでインストールするPythonは最初の1回だけで、追加で別のPythonのバージョンをasdfでインストールすることは無いかなぁという印象。

そういえば、ryeではblack, flake8などグローバルで使えるようにしたいツールを管理出来るそう。これを使えば、asdfでグローバルに見えるようにしているPython環境にblack, flake8をインストールする必要は無い?ということになりそう

このスクラップは2023/12/31にクローズされました