Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dependencies with python restrictions without an upper bound have been broken on poetry 2.1.0 #10185

Closed
joein opened this issue Feb 15, 2025 · 1 comment
Labels
area/core Related to the poetry-core library kind/bug Something isn't working as expected status/duplicate Duplicate issues

Comments

@joein
Copy link

joein commented Feb 15, 2025

Description

We have a pyproject.toml generated with poetry 1.x.x, which works with poetry 2.0.1, but does not work with poetry 2.1.0
I've tried tracking down the issue, and figured out that it is bound to the following dependency

numpy = [
    { version = ">=1.21,<2.1.0", python = "<3.10" },
    { version = ">=1.21", python = ">=3.10,<3.12" },
    { version = ">=1.26", python = ">=3.12,<3.13" },
    { version = ">=2.1.0", python = ">=3.13" },
]

However, it only causes the issue when there is a dependency going after it, if it is the sole dependency, it works.
Moreover, I was able to determine that it crashes only in the case, where the last dependency does not have an upper bound
If I change the python version to the capped one like { version = ">=2.1.0", python = ">=3.13,4" },, it works.

If I put a dependency with an upper bound as the last dependency in the list, it also works. E.g., the following works:

numpy = [
    { version = ">=1.21", python = ">=3.10,<3.12" },
    { version = ">=1.26", python = ">=3.12,<3.13" },
    { version = ">=2.1.0", python = ">=3.13" },
    { version = ">=1.21,<2.1.0", python = "<3.10" },
]

Workarounds

If one has a list of dependencies finishing with an uncapped python version, try either capping the version or sort the list of dependencies so the last dependency in the list has an upper bound.

Poetry Installation Method

pip

Operating System

Mac os

Poetry Version

Poetry (version 2.1.0)

Poetry Configuration

cache-dir = "/Users/user/Library/Caches/pypoetry"
data-dir = "/Users/user/Library/Application Support/pypoetry"
installer.max-workers = null
installer.no-binary = null
installer.only-binary = null
installer.parallel = true
installer.re-resolve = true
keyring.enabled = true
python.installation-dir = "{data-dir}/python"  # /Users/user/Library/Application Support/pypoetry/python
requests.max-retries = 0
solver.lazy-wheel = true
system-git-client = false
virtualenvs.create = true
virtualenvs.in-project = null
virtualenvs.options.always-copy = false
virtualenvs.options.no-pip = false
virtualenvs.options.system-site-packages = false
virtualenvs.path = "{cache-dir}/virtualenvs"  # /Users/user/Library/Caches/pypoetry/virtualenvs
virtualenvs.prompt = "{project_name}-py{python_version}"
virtualenvs.use-poetry-python = false

Python Sysconfig

Example pyproject.toml

[tool.poetry]
name = "check-poetry"
version = "1.0.0"
description = "descr"
authors = ["User User <user@users.com>"]
packages = [
    {include = "check_poetry"}
]
license = "Apache-2.0"
readme = "README.md"

[tool.poetry.dependencies]
python = ">=3.9"
numpy = [
    { version = ">=1.21,<2.1.0", python = "<3.10" },
    { version = ">=1.21", python = ">=3.10,<3.12" },
    { version = ">=1.26", python = ">=3.12,<3.13" },
    { version = ">=2.1.0", python = ">=3.13" },
]
tqdm = "^4.67.1"


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

Poetry Runtime Logs

poetry-runtime.log
Loading configuration file /Users/user/Library/Application Support/pypoetry/config.toml
Using virtualenv: /Users/user/work/proj/check-poetry/venv
Checking keyring availability: Checking if keyring is available
[keyring:keyring.backend] Loading KWallet
[keyring:keyring.backend] Loading SecretService
[keyring:keyring.backend] Loading Windows
[keyring:keyring.backend] Loading chainer
[keyring:keyring.backend] Loading libsecret
[keyring:keyring.backend] Loading macOS
Using keyring backend 'macOS Keyring'
Available
Updating dependencies
Resolving dependencies...
 1: fact: check-poetry is 1.0.0
 1: derived: check-poetry
 0: Duplicate dependencies for numpy
 0: Different requirements found for numpy (>=1.21,<2.1.0) with markers python_version < "3.10", numpy (>=1.21) with markers python_version >= "3.10" and python_version < "3.12", numpy (>=1.26) with markers python_version == "3.12" and numpy (>=2.1.0) with markers python_version >= "3.13".
 1: Version solving took 0.002 seconds.
 1: Tried 1 solutions.
 0: Retrying dependency resolution with the following overrides ({Package('check-poetry', '1.0.0'): {'numpy': <Dependency numpy (>=1.21,<2.1.0)>}}).
 1: fact: check-poetry is 1.0.0
 1: derived: check-poetry
 1: fact: check-poetry depends on numpy (>=1.21,<2.1.0)
 1: fact: check-poetry depends on tqdm (^4.67.1)
 1: selecting check-poetry (1.0.0)
 1: derived: tqdm (>=4.67.1,<5.0.0)
 1: derived: numpy (>=1.21,<2.1.0)
Creating new session for pypi.org
Source (PyPI): 1 packages found for tqdm >=4.67.1,<5.0.0
Source (PyPI): 34 packages found for numpy >=1.21,<2.1.0
 1: fact: tqdm (4.67.1) depends on colorama (*)
 1: selecting tqdm (4.67.1)
 1: derived: colorama
Source (PyPI): 43 packages found for colorama *
 1: selecting colorama (0.4.6)
 1: selecting numpy (2.0.2)
 1: Version solving took 0.107 seconds.
 1: Tried 1 solutions.
 0: Retrying dependency resolution with the following overrides ({Package('check-poetry', '1.0.0'): {'numpy': <Dependency numpy (>=1.21)>}}).
 1: fact: check-poetry is 1.0.0
 1: derived: check-poetry
 1: fact: check-poetry depends on numpy (>=1.21)
 1: fact: check-poetry depends on tqdm (^4.67.1)
 1: selecting check-poetry (1.0.0)
 1: derived: tqdm (>=4.67.1,<5.0.0)
 1: derived: numpy (>=1.21)
Source (PyPI): 1 packages found for tqdm >=4.67.1,<5.0.0
Source (PyPI): 42 packages found for numpy >=1.21
 1: fact: tqdm (4.67.1) depends on colorama (*)
 1: selecting tqdm (4.67.1)
 1: derived: colorama
Source (PyPI): 43 packages found for colorama *
 1: selecting colorama (0.4.6)
 1: selecting numpy (2.2.3)
 1: Version solving took 0.002 seconds.
 1: Tried 1 solutions.
 0: Retrying dependency resolution with the following overrides ({Package('check-poetry', '1.0.0'): {'numpy': <Dependency numpy (>=1.26)>}}).
 1: fact: check-poetry is 1.0.0
 1: derived: check-poetry
 1: fact: check-poetry depends on numpy (>=1.26)
 1: fact: check-poetry depends on tqdm (^4.67.1)
 1: selecting check-poetry (1.0.0)
 1: derived: tqdm (>=4.67.1,<5.0.0)
 1: derived: numpy (>=1.26)
Source (PyPI): 1 packages found for tqdm >=4.67.1,<5.0.0
Source (PyPI): 16 packages found for numpy >=1.26
 1: fact: tqdm (4.67.1) depends on colorama (*)
 1: selecting tqdm (4.67.1)
 1: derived: colorama
Source (PyPI): 43 packages found for colorama *
 1: selecting colorama (0.4.6)
 1: selecting numpy (2.2.3)
 1: Version solving took 0.002 seconds.
 1: Tried 1 solutions.
 0: Retrying dependency resolution with the following overrides ({Package('check-poetry', '1.0.0'): {'numpy': <Dependency numpy (>=2.1.0)>}}).
 1: fact: check-poetry is 1.0.0
 1: derived: check-poetry
 1: fact: check-poetry depends on numpy (>=2.1.0)
 1: fact: check-poetry depends on tqdm (^4.67.1)
 1: selecting check-poetry (1.0.0)
 1: derived: tqdm (>=4.67.1,<5.0.0)
 1: derived: numpy (>=2.1.0)
Source (PyPI): 1 packages found for tqdm >=4.67.1,<5.0.0
Source (PyPI): 8 packages found for numpy >=2.1.0
 1: fact: tqdm (4.67.1) depends on colorama (*)
 1: selecting tqdm (4.67.1)
 1: derived: colorama
Source (PyPI): 43 packages found for colorama *
 1: selecting colorama (0.4.6)
 1: selecting numpy (2.2.3)
 1: Version solving took 0.002 seconds.
 1: Tried 1 solutions.

Stack trace:

17  venv/lib/python3.9/site-packages/cleo/application.py:327 in run
     325│
     326│             try:
   → 327│                 exit_code = self._run(io)
     328│             except BrokenPipeError:
     329│                 # If we are piped to another process, it may close early and send a

16  venv/lib/python3.9/site-packages/poetry/console/application.py:260 in _run
     258│         with directory(self._working_directory):
     259│             try:
   → 260│                 exit_code = super()._run(io)
     261│             except PoetryRuntimeError as e:
     262│                 io.write_error_line("")

15  venv/lib/python3.9/site-packages/cleo/application.py:431 in _run
     429│             io.input.interactive(interactive)
     430│
   → 431│         exit_code = self._run_command(command, io)
     432│         self._running_command = None
     433│

14  venv/lib/python3.9/site-packages/cleo/application.py:473 in _run_command
     471│
     472│         if error is not None:
   → 473│             raise error
     474│
     475│         return terminate_event.exit_code

13  venv/lib/python3.9/site-packages/cleo/application.py:457 in _run_command
     455│
     456│             if command_event.command_should_run():
   → 457│                 exit_code = command.run(io)
     458│             else:
     459│                 exit_code = ConsoleCommandEvent.RETURN_CODE_DISABLED

12  venv/lib/python3.9/site-packages/cleo/commands/base_command.py:117 in run
     115│         io.input.validate()
     116│
   → 117│         return self.execute(io) or 0
     118│
     119│     def merge_application_definition(self, merge_args: bool = True) -> None:

11  venv/lib/python3.9/site-packages/poetry/console/commands/installer_command.py:39 in execute
      37│     def execute(self, io: IO) -> int:
      38│         PoetryKeyring.preflight_check(io, self.poetry.config)
   →  39│         return super().execute(io)
      40│

10  venv/lib/python3.9/site-packages/cleo/commands/command.py:61 in execute
      59│
      60│         try:
   →  61│             return self.handle()
      62│         except KeyboardInterrupt:
      63│             return 1

 9  venv/lib/python3.9/site-packages/poetry/console/commands/install.py:173 in handle
     171│         self.installer.verbose(self.io.is_verbose())
     172│
   → 173│         return_code = self.installer.run()
     174│
     175│         if return_code != 0:

 8  venv/lib/python3.9/site-packages/poetry/installation/installer.py:103 in run
     101│             self.verbose(True)
     102│
   → 103│         return self._do_install()
     104│
     105│     def dry_run(self, dry_run: bool = True) -> Installer:

 7  venv/lib/python3.9/site-packages/poetry/installation/installer.py:241 in _do_install
     239│                 source_root=self._env.path.joinpath("src")
     240│             ):
   → 241│                 solved_packages = solver.solve(
     242│                     use_latest=self._whitelist
     243│                 ).get_solved_packages()

 6  venv/lib/python3.9/site-packages/poetry/puzzle/solver.py:91 in solve
      89│             for transitive_info in packages.values():
      90│                 for group, marker in transitive_info.markers.items():
   →  91│                     transitive_info.markers[group] = simplify_marker(
      92│                         marker, self._package.python_constraint
      93│                     )

 5  venv/lib/python3.9/site-packages/poetry/puzzle/solver.py:503 in simplify_marker
     501│     Use cache because we call this function often for the same markers.
     502│     """
   → 503│     return marker.reduce_by_python_constraint(python_constraint)
     504│

 4  venv/lib/python3.9/site-packages/poetry/core/version/markers.py:464 in reduce_by_python_constraint
      462│
      463│             assert isinstance(self._constraint, VersionConstraint)
   →  464│             constraint = get_python_constraint_from_marker(self)
      465│             if constraint.allows_all(python_constraint):
      466│                 return AnyMarker()

 3  venv/lib/python3.9/site-packages/poetry/core/packages/utils/utils.py:326 in get_python_constraint_from_marker
     324│     python_version_markers = markers["python_version"]
     325│     normalized = normalize_python_version_markers(python_version_markers)
   → 326│     constraint = parse_marker_version_constraint(normalized)
     327│     return constraint
     328│

 2  venv/lib/python3.9/site-packages/poetry/core/constraints/version/parser.py:25 in parse_marker_version_constraint
      23│     constraints: str, *, pep440: bool = True
      24│ ) -> VersionConstraint:
   →  25│     return _parse_constraint(
      26│         constraints=constraints, is_marker_constraint=True, pep440=pep440
      27│     )

 1  venv/lib/python3.9/site-packages/poetry/core/constraints/version/parser.py:60 in _parse_constraint
      58│         else:
      59│             constraint_objects.append(
   →  60│                 parse_single_constraint(
      61│                     and_constraints[0],
      62│                     is_marker_constraint=is_marker_constraint,

ParseConstraintError

Could not parse version constraint: ==*

at venv/lib/python3.9/site-packages/poetry/core/constraints/version/parser.py:226 in parse_single_constraint
    222│         if op == "!=":
    223│             return VersionUnion(VersionRange(max=version), VersionRange(min=version))
    224│         return version
    225│
  → 226│     raise ParseConstraintError(f"Could not parse version constraint: {constraint}")
    227│
    228│
    229│ def _make_x_constraint_range(
    230│     version: Version, *, invert: bool = False, is_marker_constraint: bool = False


@joein joein added kind/bug Something isn't working as expected status/triage This issue needs to be triaged labels Feb 15, 2025
@joein
Copy link
Author

joein commented Feb 15, 2025

A duplicate of #10184

@joein joein closed this as completed Feb 15, 2025
@radoering radoering added area/core Related to the poetry-core library status/duplicate Duplicate issues and removed status/triage This issue needs to be triaged labels Feb 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/core Related to the poetry-core library kind/bug Something isn't working as expected status/duplicate Duplicate issues
Projects
None yet
Development

No branches or pull requests

2 participants