エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

poetryのバージョンを2.0.0に上げたらinstallできなくなった

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-modefalseにする

# 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.pyhogeと同じディレクトリにあるためです。 モジュール検索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-modefalseにすることで、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を調査するエンジニアを募集しています。 下記のリンクからご応募お待ちしています!

jobs.m3.com

*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]への移行が必要になるかもしれません。