poetry --directory で参照する pyproject.toml と poetry.lock を切り替える

パッケージ管理に poetry を使っているのですが、機械学習などをしていると、GPUやCPU、時には Apple Silicon(M1, M2, M3 Macなど)ごとにインストールするパッケージやパッケージのビルドを切り替えたりする必要がしばしば発生します。

これまで下記のようなかなりアドホックな pyproject.toml を書いて対応していたのですが、そろそろ限界を感じはじめていました。

# 引用元: https://github.com/python-poetry/poetry/issues/8271#issuecomment-1827617453

[tool.poetry]
name = "tf-project"
version = "0.1.0"
description = ""
authors = ["Your Name <you@example.com>"]
readme = "README.md"
packages = [{include = "tf_project"}]

[tool.poetry.dependencies]
python = ">=3.9, <3.12"

[tool.poetry.group.dev.dependencies]
# tensorflow = ">=2.11.0, <2.12.0"
# tensorflow-io-gcs-filesystem = "^0.31.0"
opencv-python = "^4.7.0"
jupyter = "^1.0.0"
fs = "^2.4.16"

[tool.poetry.group.tensorflow.dependencies]
tensorflow = {version = "^2.13.0" }
tensorflow-macos = { version = "^2.13.0", platform = "darwin", markers = "platform_machine=='arm64'" }
tensorflow-intel = { version = "^2.13.0", platform = "win32" }
tensorflow-cpu = [
    { version = "^2.13.0", platform = "linux", markers = "platform_machine!='arm64' and platform_machine!='aarch64'" },
    { version = "^2.13.0", platform = "darwin", markers = "platform_machine!='arm64' and platform_machine!='aarch64'" },
]
tensorflow-cpu-aws = { version = "^2.13.0", platform = "linux", markers = "platform_machine=='arm64' or platform_machine=='aarch64'" }
tensorflow-io-gcs-filesystem = [
    { version = ">= 0.23.1", markers = "platform_machine!='arm64' or platform_system!='Darwin'" },
    { version = "< 0.32.0", markers = "platform_system == 'Windows'" }
]

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

なにかうまい方法はないかなと poetry のマニュアルをながめていたら、`--directory` というオプションの存在を知り、これを使えば参照する pyproject.toml と poetry.lock が含まれるディレクトリを切り替えられることを知ったので、挙動確認をしながら紹介したいと思います。

検証

下記に再現コードがあります

① 複数の poetry 環境をつくってみる

$ mkdir env1 env2
$ poetry --directory env1 init -q  # env1 に pyproject.toml と poetry.lock ができる
$ poetry --directory env2 init -q  # env2 に...

これで env1、env2 ディレクトリ直下にそれぞれ pyproject.toml と poetry.lock が作成されます。

② パッケージインストールしてみる

$ poetry --directory env1 add numpy
$ poetry --directory env2 add tqdm

env1 には numpy を、env2 には tqdm をインストールしてみました。pyproject.toml を確認すると、うまくいっていそうです。

env1/pyproject.toml:

[tool.poetry]
name = "study-devicewise-poetry-management"
version = "0.1.0"
description = ""
authors = ["TatsuyaShirakawa <lilys1204@gmail.com>"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.10"
numpy = "^1.26.4"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

env2/pyproject.toml:

[tool.poetry]
name = "study-devicewise-poetry-management"
version = "0.1.0"
description = ""
authors = ["TatsuyaShirakawa <lilys1204@gmail.com>"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.10"
tqdm = "^4.66.2"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

それぞれの環境を使い分けてみる

以下の main.py をカレントに作ります。

try:
    import numpy
    print("✅ numpy")
except:
    print("❌ numpy")


try:
    import tqdm
    print("✅ tqdm")
except:
    print("❌ tqdm")

directory 指定をして実行してみます。

$ poetry --directory env1 run python main.py
✅ numpy
❌ tqdm

$ poetry --directory env2 run python main.py
❌ numpy
✅ tqdm

うまく環境を区別できていそうですね。というわけで、--directory を指定すれば pyproject.toml と poetry.lock を分離/管理できそうです。

この方法のデメリット

環境が異なっても共通化したいパッケージも分離管理されてしまうのはデメリットです。ユースケースごとにトレードオフを検討して使い分けるのが良さそうです。

まとめ

poetry の --directory オプションの使い方を紹介しました。以前、poetry でモノレポの Python 環境を管理する記事を書いたのですが、 --directory オプションを使えばもっと明快に管理できそうな気がしました。使っていきます。


この記事が気に入ったらサポートをしてみませんか?