AI・機械学習チームの池嶋(@mski_iksm)です。AI・機械学習チームではPythonで開発しているプロダクトのパッケージ管理にpoetryを使用していますが、年明け早々こんなメッセージが出てpoetry install
ができなくなるトラブルが頻発しました。
Warning: The current project could not be installed: No file/folder found for package XXXXXXXXXX
2025年1月5日にリリースされたpoetry 2.0.0では、自パッケージのインストールに関する挙動が変更されました。その影響で、poetry installが失敗するケースが発生しています。 この記事では、この問題に対する対策を解説します。
tl;dr
pyproject.toml
の[tool.poetry]
セクションのpackage-mode
をfalse
にする
# pyproject.toml [tool.poetry] package-mode = false
詳細
poetryではpackage modeとnon-package modeの2種類があります。 package modeは自分自身をパッケージとして環境にインストールしてから使うモードで、主にパッケージ開発に使われます。 non-package modeは逆に自分自身をパッケージとして環境にインストールせずに使うモードで、依存するサードパーティのパッケージ管理にpoetryを使用する場合に選択されます*1。 デフォルトではpackage modeが選択されています。
. ├── hoge │ ├── __init__.py │ └── code.py ├── poetry.lock └── pyproject.toml
例えば上記のようなディレクトリ構造の場合、hoge
自身を環境にインストールするかどうかをモードで切り替えます。
package modeの時、poetryはpyproject.toml
に記述する[project]
セクションのname
で自分自身のパッケージ名を判断しています。*2
ここで指定した名前のディレクトリが見当たらない場合の挙動がバージョン2.0.0から変更されました。
2.0.0より前
ディレクトリに自パッケージがない場合、warningで警告しつつもスルー。自パッケージは環境へのインストールは実施されません。
2.0.0以降
ディレクトリに自分パッケージがない場合、poetry install
自体が失敗する。(警告メッセージはwarning)
自分自身をインストールするpackage modeを指定しながらそのパッケージが見当たらない、という現象は何か間違っている可能性が高いので、ここではインストールが失敗するのは自然に思われます。
自パッケージを環境にインストールしなくても使える場合ってどういうこと?
1. 単一スクリプトなど、そもそもimportをしない場合
poetryを依存パッケージ管理にだけ使っている場合です。こういう場合はpackageを作っていないので、no-package modeを選択するのが良さそうです。
2. 自パッケージがモジュール検索PATHにある場合
Pythonでは、モジュール検索PATHが通るディレクトリのコードをimportできます。
モジュール検索PATHはsys.path
で確認ができる値で、デフォルトでは依存パッケージがインストールされるsite-packages
ディレクトリや、実行するスクリプトのディレクトリが含まれています。
これまで環境に自パッケージをインストールしなくても参照できていたのは、自パッケージがモジュール検索PATHの通った場所に配置されているためです。
. ├── hoge │ ├── __init__.py │ └── code.py ├── main.py ├── poetry.lock ├── pyproject.toml └── script └── main.py
例えば、上記のようなディレクトリ構造のときに、main.py
からimport hoge
は可能です。
これはmain.py
がhoge
と同じディレクトリにあるためです。
モジュール検索PATHには、実行するスクリプトのディレクトリが含まれているためimport可能になっています。
一方、script/main.py
からimport hoge
はできません。
python script/main.py
を実行すると、モジュール検索PATHには.
ではなくscript
が追加され、hoge
が見つからないためです。
なお、「自パッケージがモジュール検索PATHにある」場合、pyproject.toml
の[project]
セクションのname
に自パッケージの名前を正しく指定してあげることで、今回の問題は回避できます。
対策
Warning: The current project could not be installed: No file/folder found for package XXXXXXXXXX
この問題の対策の方針は大きく2種類あります。
1つは、これまで通り自パッケージはインストールしないようにする方針です。pyproject.toml
の[tool.poetry]
セクションのpackage-mode
をfalse
にすることで、no-package modeを明示的に使用するようにします。
# pyproject.toml [tool.poetry] package-mode = false
なお、poetry install --no-root
をする方法もありますが、これは「package modeのまま*3自パッケージのインストールだけをスキップする」というもので、modeの指定とやっていることが捻れたままのため、no-package modeを明示的に選択する前者がいいかと考えています。
もう1つは、自パッケージをインストールするようにする方針です。
これは、[project]
セクションのname
に自パッケージ名を指定することで実現可能です。
急ぎの場合は、これまで通りの挙動をするためにno-package modeに変更するので良さそうですが、将来的にscriptディレクトリなどから自パッケージをimportしたいなど柔軟に対応したい場合は、後者のようにpackageとして環境にインストールを検討してもいいかもしれません。
他のpoetry 2.0.0での変更点
poetry shell
がpluginになった
poetryの環境内に入るためのコマンドであったpoetry shell
が、plugin経由で入れる機能になりました。今後はeval $(poetry env activate)
を使うことが推奨されています。
poetry lock
のデフォルトが--no-update
になった
poetry lock
の際に、アップデートが必須ではないパッケージは現状のままにする--no-update
オプションがデフォルトになりました。
pyproject.toml
の[project]
セクションのサポート
本記事でも度々設定している、pyproject.toml
の[project]
セクションがサポートされたのは2.0.0からです。
これまで[tool.poetry]
セクションに記述していた設定もいくつかは非推奨になり、[project]
セクションへの記述に移行しているので注意が必要です。
メジャーアップデートらしく、他にもたくさんの変更がありますので、公式解説もご参照ください。
we are hiring!
AI・機械学習チームでは、ライブラリのメジャーアップデートにも怯まずに突っ込んでwhyを調査するエンジニアを募集しています。 下記のリンクからご応募お待ちしています!
*1:non-package modeが導入されたのは2024年2月の1.8.0からと、意外と新しめの機能です。https://github.com/python-poetry/poetry/releases/tag/1.8.0
*2:[project]セクションのnameがない場合、[tool.poetry]セクションのnameを参照しますが、後者の設定は非推奨になりました。
*3:package modeではあるので、pyproject.tomlにおいて、[project.name] or [tool.poetry.name]と[project.version] or [tool.poetry.version]の指定を求められます。このうち[tool.poetry.name]は非推奨になっているので、将来的に[project.name]への移行が必要になるかもしれません。