Ryeで入れたPythonがreticulateから使えない問題

ryeでインストールしたPythonがreticulateで使えなかった問題の解決法
bug
rye
reticulate
R
Python
Published

August 8, 2024

Pythonの環境管理ツールであるryeでインストールしたPythonを、 RからPythonを使うためのパッケージreticulateで使えなかった問題の解決について。

発端

ryeでインストールしたPythonをreticulateから利用しようとすると --enable-sharedを有効化しろというエラーメッセージがでて、 使うことが出来なかった。 これはlibpythonという他の言語からPythonを利用するための共有ライブラリが見つからないことに起因するエラーらしい。

原因

ryeのGitHubページのIssueを探してみると、関連するものがあった。

Patch build info at install time · Issue #646 · astral-sh/rye

Today sysconfig and all the files in lib/pkgconfig have incorrect paths. These paths should be fixed up when the interpreter is installed or maybe later at runtime when possible. lib/pkgconfig/pyth...

https://github.com/astral-sh/rye/issues/646

ryeでインストールされるPythonは事前にコンパイルされたバイナリを下のリンク先からとってきている。

GitHub - indygreg/python-build-standalone: Produce redistributable builds of Python

Produce redistributable builds of Python. Contribute to indygreg/python-build-standalone development by creating an account on GitHub.

https://github.com/indygreg/python-build-standalone

そしてこのPythonはビルド時にちゃんと--enable-sharedフラグをつけてビルドされているのだが、 共有ライブラリのパスが正しく設定されておらず、結果として上述のエラーにつながっているらしい。

参考

Pythonをどこから入手しているか

Philosophy - Rye

https://rye.astral.sh/philosophy/

パスの設定を修正するPythonのプログラム

GitHub - bluss/sysconfigpatcher: Patch sysconfigdata and pkgconfig files in a python installation from indygreg's python builds.

Patch sysconfigdata and pkgconfig files in a python installation from indygreg's python builds. - bluss/sysconfigpatcher

https://github.com/bluss/sysconfigpatcher

解決

上記のIssueのところで紹介されていた修正用のプログラム(sysconfigpatcher)を使うことで、 インストールしたPythonの共有ライブラリのパスを書き換えて、エラーを解決することが出来た。

まずは、ryeをつかってsysconfigpatcherをインストールする。

rye tools install --git 'https://github.com/bluss/sysconfigpatcher' sysconfigpatcher

次に、ryeでインストールした共有ライブラリのパスが間違っているかを確認する。 設定されている共有ライブラリのパスは/install/libだが、このディレクトリは自分のPC上に存在しない。

python -m sysconfig | grep LIBDIR
#>     LIBDIR = "/install/lib"
#>     PLATLIBDIR = "lib"

ls /install/lib
#> ls: /install/lib: No such file or directory

.venv内のPythonはシンボリックリンクなので、実体があるファイルパスを探す。 この場合は/Users/t_arae/.rye/py/cpython@3.12.2/install/bin/python3.12にある。

ls -l `which python`
#> lrwxr-xr-x  1 t_arae  staff  59 Jul 21 22:52 /Users/t_arae/blog/.venv/bin/python -> /Users/t_arae/.rye/py/cpython@3.12.2/install/bin/python3.12

sysconfigpatcherで指定するのは、/Users/t_arae/.rye/py/cpython@3.12.2の部分らしい。 書き換える前に--dry-runフラグで動作を確認できる。

sysconfigpatcher --dry-run /Users/t_arae/.rye/py/cpython@3.12.2
#> INFO: Would patch /Users/t_arae/.rye/py/cpython@3.12.2/install/lib/python3.12/_sysconfigdata__darwin_darwin.py
#> INFO: Would patch /Users/t_arae/.rye/py/cpython@3.12.2/install/lib/pkgconfig/python-3.12-embed.pc
#> INFO: Would patch /Users/t_arae/.rye/py/cpython@3.12.2/install/lib/pkgconfig/python-3.12.pc

書き換え実行。

sysconfigpatcher /Users/t_arae/.rye/py/cpython@3.12.2
#> INFO: Patched /Users/t_arae/.rye/py/cpython@3.12.2/install/lib/python3.12/_sysconfigdata__darwin_darwin.py
#> INFO: Patched /Users/t_arae/.rye/py/cpython@3.12.2/install/lib/pkgconfig/python-3.12-embed.pc
#> INFO: Patched /Users/t_arae/.rye/py/cpython@3.12.2/install/lib/pkgconfig/python-3.12.pc

共有ライブラリのパスが書き換わったか確認。 ちゃんと、libpython3.12.dylibがあるディレクトリが指定できている。

python -m sysconfig | grep LIBDIR
#>     LIBDIR = "/Users/t_arae/.rye/py/cpython@3.12.2/install/lib"
#>     PLATLIBDIR = "lib"

ls /Users/t_arae/.rye/py/cpython@3.12.2/install/lib
#> itcl4.2.2               pkgconfig               tcl8.6
#> libpython3.12.a         python3.12              thread2.8.7
#> libpython3.12.dylib     tcl8                    tk8.6

reticulateパッケージできちんとPythonが使えるか確認。

reticulate::py_config()
#> python:         /Users/t_arae/blog/.venv/bin/python
#> libpython:      /Users/t_arae/.rye/py/cpython@3.12.2/install/lib/libpython3.12.dylib
#> pythonhome:     /Users/t_arae/blog/.venv:/Users/t_arae/blog/.venv
#> virtualenv:     /Users/t_arae/blog/.venv/bin/activate_this.py
#> version:        3.12.2 (main, Feb 25 2024, 03:55:42) [Clang 17.0.6 ]
#> numpy:          /Users/t_arae/blog/.venv/lib/python3.12/site-packages/numpy
#> numpy_version:  2.0.1
#> 
#> NOTE: Python version was forced by VIRTUAL_ENV

reticulate::py_eval("1 + 1")
#> [1] 2