Why can't I install a Python package with the Python requirement ">=3.8,<3.11" into a Poetry project with the Python version "^3.9"?

I’m having an issue installing dependencies into my Poetry project. If I run poetry new (as described in https://python-poetry.org/docs/basic-usage/), I can create a new project:

$ poetry new scipy-test
Created package scipy_test in scipy-test

My project structure looks like this after I delete a few files not needed for this reproduction:

$ tree .
.
├── pyproject.toml
└── scipy_test
    └── __init__.py

1 directory, 2 files

My pyproject.toml file looks like this:

[tool.poetry]
name = "scipy-test"
version = "0.1.0"
description = ""
authors = ["Your Name <you@example.com>"]

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

[tool.poetry.dev-dependencies]
pytest = "^5.2"

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

When I run poetry add scipy, it tries to install the latest version of SciPy, which right now is 1.8.1. I get the following error:

$ poetry add scipy
Creating virtualenv scipy-test-4EDXm154-py3.9 in /home/mattwelke/.cache/pypoetry/virtualenvs
Using version ^1.8.1 for scipy

Updating dependencies
Resolving dependencies... (0.1s)

  SolverProblemError

  The current project's Python requirement (>=3.9,<4.0) is not compatible with some of the required packages Python requirement:
    - scipy requires Python >=3.8,<3.11, so it will not be satisfied for Python >=3.11,<4.0
  
  Because no versions of scipy match >1.8.1,<2.0.0
   and scipy (1.8.1) requires Python >=3.8,<3.11, scipy is forbidden.
  So, because scipy-test depends on scipy (^1.8.1), version solving failed.

  at ~/.local/share/pypoetry/venv/lib/python3.9/site-packages/poetry/puzzle/solver.py:241 in _solve
      237│             packages = result.packages
      238│         except OverrideNeeded as e:
      239│             return self.solve_in_compatibility_mode(e.overrides, use_latest=use_latest)
      240│         except SolveFailure as e:
    → 241│             raise SolverProblemError(e)
      242│ 
      243│         results = dict(
      244│             depth_first_search(
      245│                 PackageNode(self._package, packages), aggregate_package_nodes

  • Check your dependencies Python requirement: The Python requirement can be specified via the `python` or `markers` properties
    
    For scipy, a possible solution would be to set the `python` property to ">=3.9,<3.11"

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

I’m interpreting the line python = "^3.9" in my pyproject.toml file to mean "this project this meant to run with Python 3.9 (any patch version)". And I’m interpreting the package’s Python requirement of ">=3.8,<3.11" to mean "this library requires Python 3.8, 3.9, or Python 3.10 to use it". So if I put these two things together, it seems to me like they should be compatible with each other.

The error message does include a hint to help me solve it. It says:

For scipy, a possible solution would be to set the `python` property to ">=3.8,<3.11"

I agree that this would solve the issue. It would make my Poetry project’s Python version match the Python requirement of the dependency exactly. I found that if I changed my pyproject.toml file this way, I was able to install the dependency.

But I don’t want to allow my project to be executed with Python 3.8. I want to set its Python version to the latest version I’m actually using. So my preferred version is actually "^3.10" (if my understanding as described above is correct) because that should mean "you must be using any patch version of Python 3.10 to run this".

If I change the line to python = "^3.10", I get the same kind of error I got before, except the hint in the error message mentions version 3.10 instead of 3.8:

For scipy, a possible solution would be to set the `python` property to ">=3.10,<3.11"

If I use this value, it works again, allowing me to install the dependency. And this time, it looks like it restricts my project to only being compatible with 3.10, as desired. But it looks a bit verbose. I still don’t understand why setting it to "^3.9" (or "^3.10") didn’t work.

Is there something I’m missing here? If so, how would I change my pyproject.toml file to make it compatible with this dependency I want to add to my project?

>Solution :

The caret requirement you specify…

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

…means "This Python code has compatibility of 3.9 <= python_version < 4" (^ restricts differently based on how you specify the version, using semantic versioning).

This is a wider constraint than what your dependency scipy specifies, because it claims only compatibility up to 3.8 <= python_version < 3.11.

To poetry, scipy does not meet your constraints because if python3.11 were out right now, your dependency constraint claims your code supports that Python version, whereas scipy‘s constraint would say it doesn’t.

For you, you probably just want something like a range to match something like scipy‘s (or narrow your range to fit inside scipy‘s).

[tool.poetry.dependencies]
python = ">=3.10, <3.11"

Leave a Reply