この記事に記載されているpoetry install
コマンドは、2024/01/16(numpyの最新バージョンが1.26.3のとき)に実行しました。
環境
- Python 3.12.1
- poetry 1.7.1
やりたいこと
Python3.8~3.12で動くツールを作りたいです。依存ライブラリはnumpyを利用します。
poetryで依存ライブラリを管理したいので、以下のpyproject.toml
を定義しました。
[tool.poetry]
name = "install-test-312"
version = "0.1.0"
description = ""
authors = ["yuji38kwmt"]
readme = "README.md"
packages = [{include = "install_test_312"}]
[tool.poetry.dependencies]
python = "^3.8"
numpy = "*"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
何が起きたか
Python3.12環境でpoetry install
を実行したら、エラーが発生しました。
$ poetry install
Updating dependencies
Resolving dependencies... (0.8s)
Package operations: 1 install, 0 updates, 0 removals
• Installing numpy (1.24.4): Failed
ChefBuildError
Backend 'setuptools.build_meta:__legacy__' is not available.
Traceback (most recent call last):
File "/home/vagrant/.pyenv/versions/3.12.1/lib/python3.12/site-packages/pyproject_hooks/_in_process/_in_process.py", line 77, in _build_backend
obj = import_module(mod_path)
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/vagrant/.pyenv/versions/3.12.1/lib/python3.12/importlib/__init__.py", line 90, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
File "<frozen importlib._bootstrap>", line 1310, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 994, in exec_module
File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
File "/tmp/tmp_2lnurl6/.venv/lib/python3.12/site-packages/setuptools/__init__.py", line 10, in <module>
import distutils.core
ModuleNotFoundError: No module named 'distutils'
at ~/.pyenv/versions/3.12.1/lib/python3.12/site-packages/poetry/installation/chef.py:164 in _prepare
160│
161│ error = ChefBuildError("\n\n".join(message_parts))
162│
163│ if error is not None:
→ 164│ raise error from None
165│
166│ return path
167│
168│ def _prepare_sdist(self, archive: Path, destination: Path | None = None) -> Path:
Note: This error originates from the build backend, and is likely not a problem with poetry but with numpy (1.24.4) not supporting PEP 517 builds. You can verify this by running 'pip wheel --no-cache-dir --use-pep517 "numpy (==1.24.4)"'.
numpy 1.24.4のインストールで失敗したようです。
原因
エラーメッセージには
This error originates from the build backend, and is likely not a problem with poetry but with numpy (1.24.4) not supporting PEP 517 builds.
とあるのでpoetryではなくnumpyの問題のようです。
The Python versions supported by this release are 3.8-3.11.
と書いてありました。したがって、Python3.12に対応していないnumpy1.24.4をインストールしようとしたことがエラーの原因のようです。
ではなぜ、poetryはPython3.12に対応していないnumpy 1.24.4をインストールしようとしたのでしょうか?
numpy1.24.4のsetup.py
にはpython_requires>=3.8
と記載されています。1python_requires>=3.8,<3.12
とは記載されていません。したがって、poetryはnumpy 1.24.4がPython3.12に対応していないことが分からず、numpy 1.24.4のインストールを試みたようです。
def setup_package():
...
metadata = dict(
...
python_requires='>=3.8'
そして、numpy1.25以降はPython3.12に対応していますがPython3.8には対応していません。
poetryはnumpyの最新バージョン1.26.3から1つずつバージョンを下げていき、Python3.8以上に対応しているかを確認していきます。
Python3.8に対応している最新のnumpyバージョンが1.24.4だったので、numpy1.24.4をインストールしたようです。
poetry install
に-vvv
オプションを指定すると、バージョンを1つずつ下げる挙動を確認できました。
$ poetry install -vvv
Loading configuration file /home/vagrant/.config/pypoetry/config.toml
Loading configuration file /home/vagrant/.config/pypoetry/auth.toml
Using virtualenv: /home/vagrant/Documents/study/python3.12/install-test-3.12/.venv
Updating dependencies
Resolving dependencies...
1: fact: install-test-312 is 0.1.0
1: derived: install-test-312
1: fact: install-test-312 depends on numpy (*)
1: selecting install-test-312 (0.1.0)
1: derived: numpy
[keyring.backend] Loading KWallet
[keyring.backend] Loading SecretService
[keyring.backend] Loading Windows
[keyring.backend] Loading chainer
[keyring.backend] Loading libsecret
[keyring.backend] Loading macOS
Creating new session for pypi.org
Source (PyPI): 103 packages found for numpy *
1: fact: numpy (1.26.3) requires Python >=3.9
1: derived: not numpy (==1.26.3)
1: fact: numpy (1.26.2) requires Python >=3.9
1: derived: not numpy (==1.26.2)
1: fact: numpy (1.26.1) requires Python <3.13,>=3.9
1: derived: not numpy (==1.26.1)
1: fact: numpy (1.26.0) requires Python <3.13,>=3.9
1: derived: not numpy (==1.26.0)
1: fact: numpy (1.25.2) requires Python >=3.9
1: derived: not numpy (==1.25.2)
1: fact: numpy (1.25.1) requires Python >=3.9
1: derived: not numpy (==1.25.1)
1: fact: numpy (1.25.0) requires Python >=3.9
1: derived: not numpy (==1.25.0)
1: selecting numpy (1.24.4)
1: Version solving took 0.381 seconds.
1: Tried 1 solutions.
Finding the necessary packages for the current system
Source (PyPI): 1 packages found for numpy *
Package operations: 1 install, 0 updates, 0 removals
• Installing numpy (1.24.4): Pending...
...
ModuleNotFoundError: No module named 'distutils'
のエラーについて
poetry install
のエラーメッセージに、ModuleNotFoundError: No module named 'distutils'
というメッセージがあります。numpy 1.24.4のインストールに失敗する原因は、このエラーです。
Python 3.12からdistutilsを利用できなくなったため、このエラーが発生しました。2
解決方法
Pythonのバージョンごとに、numpyのバージョンを指定すればpoetry install
が実行できました。
numpy = [
{version = ">=1.26", python = ">=3.9"},
{version = "<1.25", python = "=3.8"}
]
$ poetry install -vvv
Loading configuration file /home/vagrant/.config/pypoetry/config.toml
Loading configuration file /home/vagrant/.config/pypoetry/auth.toml
Using virtualenv: /home/vagrant/Documents/study/20240201/312-gte38-for-numpy/.venv
Updating dependencies
Resolving dependencies...
1: fact: install-test-312 is 0.1.0
1: derived: install-test-312
0: Duplicate dependencies for numpy
0: Different requirements found for numpy (>=1.26) with markers python_version >= "3.9" and numpy (<1.25) with markers python_version == "3.8".
1: Version solving took 0.007 seconds.
1: Tried 1 solutions.
0: Retrying dependency resolution with the following overrides ({Package('install-test-312', '0.1.0'): {'numpy': <Dependency numpy (>=1.26)>}}).
1: fact: install-test-312 is 0.1.0
1: derived: install-test-312
1: fact: install-test-312 depends on numpy (>=1.26)
1: selecting install-test-312 (0.1.0)
1: derived: numpy (>=1.26)
1: selecting numpy (1.26.3)
1: Version solving took 0.451 seconds.
1: Tried 1 solutions.
0: Retrying dependency resolution with the following overrides ({Package('install-test-312', '0.1.0'): {'numpy': <Dependency numpy (<1.25)>}}).
1: fact: install-test-312 is 0.1.0
1: derived: install-test-312
1: fact: install-test-312 depends on numpy (<1.25)
1: selecting install-test-312 (0.1.0)
1: derived: numpy (<1.25)
1: selecting numpy (1.24.4)
1: Version solving took 0.015 seconds.
1: Tried 1 solutions.
0: Complete version solving took 0.473 seconds with 2 overrides
0: Resolved with overrides: ({Package('install-test-312', '0.1.0'): {'numpy': <Dependency numpy (>=1.26)>}}), ({Package('install-test-312', '0.1.0'): {'numpy': <Dependency numpy (<1.25)>}})
Finding the necessary packages for the current system
Package operations: 1 install, 0 updates, 0 removals
• Installing numpy (1.26.3)
Writing lock file
Installing the current project: install-test-312 (0.1.0)
- Building package install-test-312 in editable mode
- Adding install_test_312.pth to /home/vagrant/Documents/study/20240201/312-gte38-for-numpy/.venv/lib/python3.12/site-packages for /home/vagrant/Documents/study/20240201/312-gte38-for-numpy
- Adding the install_test_312-0.1.0.dist-info directory to /home/vagrant/Documents/study/20240201/312-gte38-for-numpy/.venv/lib/python3.12/site-packages
numpy 1.26.3がインストールされました。
ちなみに、poetry.lock
には以下のようにnumpy
の情報が複数記載されていました。
[[package]]
name = "numpy"
version = "1.24.4"
description = "Fundamental package for array computing in Python"
optional = false
python-versions = ">=3.8"
files = [...]
[[package]]
name = "numpy"
version = "1.26.3"
description = "Fundamental package for array computing in Python"
optional = false
python-versions = ">=3.9"
files = [...]
さらに補足ですが、poetry build
で生成されたwheelファイル内のMETADATA
ファイルには、以下のようにnumpyのバージョンが記載されていました。
Requires-Dist: numpy (<1.25) ; python_version == "3.8"
Requires-Dist: numpy (>=1.26) ; python_version >= "3.9"
注意:poetry1.7.1でのpoetry show numpy
の結果は正しくない
poetry install
のログにはInstalling numpy (1.26.3)
と出力されました。
しかしpoetry show
コマンドでは"numpy 1.24.4"と出力されました。
$ poetry show numpy
name : numpy
version : 1.24.4
description : Fundamental package for array computing in Python
詳細は別記事に記載しました。
-
wheelファイルに含まれる
numpy-1.24.4.dist-info/METADTA
のRequires-Python: >=3.8
に相当します。 ↩