Python 3.9で`poetry install`を実行したら、numpy 2.1.0をインストールしようとしてエラーが発生した

:::note
この記事は2024/08/20に動作を確認しました。
2024/08/20時点では、最新バージョンは以下の通りです。
* numpy 2.1.0
* pandas 2.2.2 
:::

# 環境
* Python 3.9.19
* poetry 1.8.3


# やりたいこと
Python3.9以上で動作するツールを作っています。
ツールはpandasとnumpyを利用しています。

依存ライブラリはpoetryで管理しています。設定ファイルは以下の通りです。

```toml:pyproject.toml
[tool.poetry]
name = "awesome"
package-mode = false

[tool.poetry.dependencies]
python = "^3.9"
pandas = "^2"

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

ツールはnumpyを利用していますが、pandasをインストールすると一緒にnumpyもインストールされるため、`pyproject.toml`に`numpy="*"`と記載しませんでした。

Python 3.9で`poetry install`を実行したあとの結果です。

```
$ poetry show
numpy           2.0.1       Fundamental package for array computing in Python
pandas          2.2.2       Powerful data structures for data analysis, time series, and statistics
python-dateutil 2.9.0.post0 Extensions to the standard Python datetime module
pytz            2024.1      World timezone definitions, modern and historical
six             1.16.0      Python 2 and 3 compatibility utilities
tzdata          2024.1      Provider of IANA time zone data
```

以下は`numpy`に関する部分のみ抽出した`poetry.lock`です。

```toml:poetry.lock
[[package]]
name = "numpy"
version = "2.0.1"
description = "Fundamental package for array computing in Python"
optional = false
python-versions = ">=3.9"
files = [...]


[[package]]
name = "numpy"
version = "2.1.0"
description = "Fundamental package for array computing in Python"
optional = false
python-versions = ">=3.10"
files = [...]
    

[[package]]
name = "pandas"
version = "2.2.2"
description = "Powerful data structures for data analysis, time series, and statistics"
optional = false
python-versions = ">=3.9"
files = [...]

[package.dependencies]
numpy = [
    {version = ">=1.22.4", markers = "python_version < \"3.11\""},
    {version = ">=1.23.2", markers = "python_version == \"3.11\""},
    {version = ">=1.26.0", markers = "python_version >= \"3.12\""},
]
python-dateutil = ">=2.8.2"
pytz = ">=2020.1"
tzdata = ">=2022.7"

[package.extras]
...

```

# `poetry install`でエラー発生
開発するときのPythonバージョンは3.12です。開発時では最新のnumpyバージョンを利用したかったので、`pyproject.toml`に以下の設定を追加しました。[^1]
[^1]: 2024/08/20時点では、この設定がなくてもPython 3.12では最新のnumpyバージョン 2.1.0を利用できます。
最新のnumpyバージョンを使いたい理由は、最新のバージョンを利用することでnumpyの新しい機能や`FutureWarning`などに気づけるからです。


```toml
[tool.poetry.group.dev-only.dependencies]
# 開発時のみ使用したいライブラリのバージョンを記載する
numpy = [{version=">=2.1", python=">=3.12"}]
```

Pythonの仮想環境と`poetry.lock`を削除してから、Python3.9で`poetry install`を実行すると以下のエラーが発生しました。


```
$ poetry install
Creating virtualenv awesome-sAvcARp--py3.9 in /home/yuji/.cache/pypoetry/virtualenvs
Updating dependencies
Resolving dependencies... (0.3s)

The current project's supported Python range (3.9.19) is not compatible with some of the required packages Python requirement:
  - numpy requires Python >=3.10, so it will not be satisfied for Python 3.9.19

Because no versions of pandas match >=2,<2.2.2 || >2.2.2,<3
 and pandas (2.2.2) depends on numpy (>=1.22.4), pandas (>=2,<3) requires numpy (>=1.22.4).
Because numpy (2.1.0) requires Python >=3.10
 and no versions of numpy match >=1.22.4,<2.1.0 || >2.1.0, numpy is forbidden.
Thus, pandas is forbidden.
So, because awesome depends on pandas (^2), version solving failed.

  • Check your dependencies Python requirement: The Python requirement can be specified via the `python` or `markers` properties

    For numpy, a possible solution would be to set the `python` property to "<empty>"

    https://python-poetry.org/docs/dependency-specification/#python-restricted-dependencies,
    https://python-poetry.org/docs/dependency-specification/#using-environment-markers
```


「Python 3.12のときにnumpy 2.1以上、Python 3.9のときは依存関係を満たす最新のnumpyバージョン（2.0.1）」がインストールされることを期待していていました。しかし、実際はPython 3.9のときもnumpy 2.1.0をインストールしようとして、エラーが起きているようです。


`pyproject.toml`に`numpy = [{version=">=2.1", python=">=3.12"}]`を指定すると、pandasで定義されている以下のnumpyの依存関係は無視されているようにみえます。

```
numpy = [
    {version = ">=1.22.4", markers = "python_version < \"3.11\""},
    {version = ">=1.23.2", markers = "python_version == \"3.11\""},
    {version = ">=1.26.0", markers = "python_version >= \"3.12\""},
]
```

# 対策
`[tool.poetry.dependencies]`配下に、`numpy = "*"`を追記しました。このツールはnumpyを利用しているので、本来`numpy = "*"`は記載した方がよいです。

```toml:pyproject.toml
[tool.poetry]
name = "awesome"
package-mode = false

[tool.poetry.dependencies]
python = "^3.9"
pandas = "^2"
numpy = "*"

[tool.poetry.group.dev-only.dependencies]
# 開発時のみバージョンを指定したライブラリを記載する
numpy = [
    {version=">=2.1", python=">=3.12"}
]

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

```