poetry publish コマンドで keyring の ModuleNotFoundError が起きたときの対応メモ
Poetry は依存するパッケージの管理だけでなく、PyPI に公開するのも簡単にできるのでとても便利です。
そんな中、poetry publish コマンドでエラーが発生するようになってしまいました。暫定対応により、現在は publish できています。そのときの対応メモが残っていたので、ブログに転記します。
keyring
The Python keyring library provides an easy way to access the system keyring service from python. It can be used in any application that needs safe password storage.
エラーメッセージ
poetry publish コマンドを実行したところ、以下のエラーメッセージが表示されました。
Error initializing plugin EntryPoint(name='libsecret', value='keyring.backends.libsecret', group='keyring.backends'). Traceback (most recent call last): File "/Users/tosh2230/.poetry/lib/poetry/_vendor/py3.8/keyring/backend.py", line 202, in _load_plugins init_func = ep.load() File "/Users/tosh2230/.pyenv/versions/3.8.11/lib/python3.8/importlib/metadata.py", line 77, in load module = import_module(match.group('module')) File "/Users/tosh2230/.pyenv/versions/3.8.11/lib/python3.8/importlib/__init__.py", line 127, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "<frozen importlib._bootstrap>", line 1014, in _gcd_import File "<frozen importlib._bootstrap>", line 991, in _find_and_load File "<frozen importlib._bootstrap>", line 973, in _find_and_load_unlocked ModuleNotFoundError: No module named 'keyring.backends.libsecret'
keyring リポジトリでは、keyring/backends/libsecret.py は v23.2.0 から存在しています。
環境
- macOS Monterey 12.4
- pyenv: keyring 23.5.0
- python 3.8.11
- Poetry version 1.1.13
- Poetry: keyring 22.3.0
keyring のバージョンが pyenv と Poetry で異なっています...
pyenv: keyring/backends
(記録を残すのを忘れましたが、entry_points.txt から 23.5.0 であることは確認できたので、libsecret.py はあったと思われます)
pyenv: entry_points.txt
$ cat /Users/tosh2230/.pyenv/versions/3.8.11/envs/stairlight/lib/python3.8/site-packages/keyring-23.5.0.dist-info/entry_points.txt [console_scripts] keyring = keyring.cli:main [devpi_client] keyring = keyring.devpi_client [keyring.backends] KWallet = keyring.backends.kwallet SecretService = keyring.backends.SecretService Windows = keyring.backends.Windows chainer = keyring.backends.chainer libsecret = keyring.backends.libsecret macOS = keyring.backends.macOS
poetry: keyring/backends
$ ls -l /Users/tosh2230/.poetry/lib/poetry/_vendor/py3.8/keyring/backends total 104 -rw-r--r-- 1 tosh2230 staff 222 2 11 06:31 OS_X.py -rw-r--r-- 1 tosh2230 staff 4739 2 11 06:31 SecretService.py -rw-r--r-- 1 tosh2230 staff 6514 2 11 06:31 Windows.py -rw-r--r-- 1 tosh2230 staff 9556 2 11 06:31 _OS_X_API.py -rw-r--r-- 1 tosh2230 staff 0 2 11 06:31 __init__.py drwxr-xr-x 9 tosh2230 staff 288 5 27 20:11 __pycache__ -rw-r--r-- 1 tosh2230 staff 2198 2 11 06:31 chainer.py -rw-r--r-- 1 tosh2230 staff 836 2 11 06:31 fail.py -rw-r--r-- 1 tosh2230 staff 5852 2 11 06:31 kwallet.py drwxr-xr-x 5 tosh2230 staff 160 4 23 17:46 macOS -rw-r--r-- 1 tosh2230 staff 360 2 11 06:31 null.py
libsecret.py はないですね
poetry: entry_points.txt
$ cat /Users/tosh2230/.poetry/lib/poetry/_vendor/py3.8/keyring-22.3.0.dist-info/entry_points.txt [console_scripts] keyring = keyring.cli:main [devpi_client] keyring = keyring.devpi_client [keyring.backends] KWallet = keyring.backends.kwallet SecretService = keyring.backends.SecretService Windows = keyring.backends.Windows chainer = keyring.backends.chainer macOS = keyring.backends.macOS
ここでも libsecret は設定されていないです
keyring での backend 読み込み
backend の読み込みはこのあたりに実装されていますが、環境変数か設定ファイルがない場合は entry_points にしたがって keyring.backends 以下にあるモジュールをインポートする仕様になっていました。
エラーメッセージから libsecret を探しにいっているのがわかりますので、pyenv の entry_points をもとに poetry の keyring/backends を読みにいっているように思えます。
暫定対応
開発環境の状態に左右されないように、設定ファイルを配置しました。こうすれば keyring.backends.OS_X.py
だけを読み込みますので、keyring のバージョンが異なることによるインポートエラーを回避できます。
$ cat ~/.config/python_keyring/keyringrc.cfg [backend] default-keyring=keyring.backends.OS_X.Keyring
次は、Poetry のソースコードを読んでみようと思います。