• 作成:

poetry 1.2.2と1.1.12ではlockファイルに互換性が無いのでコーナケースでは注意が必要

要約

やりたいこと

foo = {git = "https://github.com/Lab/foo.git"}

みたいなPyPIに登録されてないGitHubに直接置かれているライブラリをpoetryで管理して、

poetry export -f requirements.txt --output requirements.txt

requirements.txtを出力したい。

このGitHubリポジトリはpublicであり認証情報などは不要です。

最初は本番ステージでもバージョンメタ情報とか一元管理できるメリットがあるのでpoetry使ってしまおうと思ったのですが、 AWS LambdaのDockerランタイムとpoetryというかvenvの食い合わせが悪いので、まともに取り合いたくないのでrequirements.txtをマルチステージで食わせるように方針転換。

問題

Poetry version 1.1.12では成功する。 1.2.2では失敗する。

Dependency walk failed at foo (*) @ git+https://github.com/Lab/foo.git

とエラーメッセージが表示される。

plugin使ってもダメ

issueを漁ってると、 python-poetry/poetry-plugin-export: Poetry plugin to export the dependencies to various formats を使えと促されたのでインストールしてみましたが、結果は変わりませんでした。

hashを除外してもダメ

hashが定まらないのが原因なのかと思ったので--without-hashesしてみましたが関係なし。

poetry lockを挟むと出力される

poetry exportする前にpoetry lockすると出力されることが分かりました。えーっとつまりUbuntuの古いpoetryと最新版がインストールされるpoetryの間にlockファイルの非互換性があるのでは? semverにして非互換性を示して欲しいです。

Ubuntu apt経由の古いpoetryを削除して非マネージドなインストーラーを使いました。 lockファイルには大幅な非互換性があるらしいですね。 Gentoo Portageのunstableぐらい最新版を追っているのならばOSのインストーラーでも問題ないかもしれませんが、 Ubuntuのapt経由だと古すぎるみたいですね。

それでもhashは失敗する

それでもpip install -r requirements.txtは失敗してしまいました。

ERROR: Can't verify hashes for these requirements because we don't have a way to hash version control repositories:

poetry export--without-hashesを付ける必要がありますね。このall or nothingな仕組みはやめてほしいですね。 VCS経由のやつだけhash無視するオプションがほしい。議論はされているようですけど。

ブランチ名が勝手にHEADにされる

#20 4.431   Running command git checkout -b HEAD --track origin/HEAD
#20 4.433   fatal: 'HEAD' is not a valid branch name
#20 4.436   error: subprocess-exited-with-error
#20 4.436
#20 4.436   × git checkout -b HEAD --track origin/HEAD did not run successfully.
#20 4.436   │ exit code: 128
#20 4.436   ╰─> See above for output.
#20 4.436
#20 4.436   note: This error originates from a subprocess, and is likely not a problem with pip.
#20 4.437 error: subprocess-exited-with-error
#20 4.437
#20 4.437 × git checkout -b HEAD --track origin/HEAD did not run successfully.
#20 4.437 │ exit code: 128
#20 4.437 ╰─> See above for output.
#20 4.437
#20 4.437 note: This error originates from a subprocess, and is likely not a problem with pip.
#20 4.582 WARNING: You are using pip version 22.0.4; however, version 22.3.1 is available.
#20 4.582 You should consider upgrading via the '/var/lang/bin/python3.9 -m pip install --upgrade pip' command.

のようにlockファイルに書かれているブランチ名をHEADにされます。 masterが正しい。

foo = {git = "https://github.com/Lab/foo.git", branch = "master"}

のように明示的に指定することで回避できます。

結局ライブラリとして使うことが想定されてなかった

当該のソフトウェアはライブラリとして使うことを想定されてなかったのでpipで依存関係としてインストールしても結局ちゃんと動きませんでした。 git cloneしたものをpip -e fooする必要がありました。

その運用も問題がありそうなので、自分でGitHub上でforkして、ライブラリとして使えるように修正して、そのブランチを指定しました。一応PRは出しておきましたが、リポジトリが放置気味なのでmergeされる期待は持っていません。