5
1
記事投稿キャンペーン 「2024年!初アウトプットをしよう」

Python3.8~3.12をサポートするツールでnumpyを利用すると、`poetry install`でエラーが発生した

Last updated at Posted at 2024-01-16

この記事に記載されている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を定義しました。

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の問題のようです。

numpy 1.24.4のリリースノートには、

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のインストールを試みたようです。

setup.py
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が実行できました。

pyproject.toml
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の情報が複数記載されていました。

poetry.lock

[[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のバージョンが記載されていました。

install_test_312-0.1.0-py3-none-any.whl/install_test_312-0.1.0.dist-info/METADATA
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 

詳細は別記事に記載しました。

  1. wheelファイルに含まれるnumpy-1.24.4.dist-info/METADTARequires-Python: >=3.8に相当します。

  2. https://docs.python.org/3/whatsnew/3.12.html#distutils

5
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1