python-poetry / python-poetry/poetry

poetry add does not update existing dependency

Open
#10,449 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

kind/bug status/triage
Dominant language
Python
Stars
34.3k
Forks
2.5k
Avg merge
2d 19h
Merged PRs (30d)
30

Description

Description

I am trying to update pytest inside my poetry project (2.1.1) to the latest version using the commands. However, poetry does not update my dependency even when I explicitly state the version (latest). This contradicts what is stated here in the docs: https://python-poetry.org/docs/cli/#update.

I quote (emphasis mine):

Note that this will not update versions for dependencies outside their version constraints specified in the pyproject.toml file. In other terms, poetry update foo will be a no-op if the version constraint specified for foo is ~2.3 or 2.3 and 2.4 is available. In order for foo to be updated, you must update the constraint, for example ^2.3. You can do this using the add command.

However, as shown (quoted or not, makes no difference):

$  poetry add "pytest@latest"
Using version ^8.4.1 for pytest

Updating dependencies
Resolving dependencies... (0.0s)

Incompatible constraints in requirements of ... (2.1.1):
pytest (>=8.4.1,<9.0.0)
pytest (>=6.2.5,<=8.2.0)

This is not what happens.

Workarounds

Manually change the pyproject.toml.

Poetry Installation Method

install.python-poetry.org

Operating System

macOS

Poetry Version

2.1.1

Poetry Configuration
$ poetry config --list
cache-dir = "/Users/daniel.soutar/Library/Caches/pypoetry"
data-dir = "/Users/daniel.soutar/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/daniel.soutar/Library/Application Support/pypoetry/python
repositories.google.url = "https://europe-python.pkg.dev/ki-artifact-registries-cf08/ki-pypi"
repositories.test.url = "https://test.pypi.org/simple/"
repositories.testpypi.url = "https://test.pypi.org/legacy/"
requests.max-retries = 0
solver.lazy-wheel = true
system-git-client = false
virtualenvs.create = true
virtualenvs.in-project = true
virtualenvs.options.always-copy = false
virtualenvs.options.no-pip = false
virtualenvs.options.system-site-packages = false
virtualenvs.path = "{cache-dir}/virtualenvs"  # /Users/daniel.soutar/Library/Caches/pypoetry/virtualenvs
virtualenvs.prompt = "{project_name}-py{python_version}"
virtualenvs.use-poetry-python = false
Python Sysconfig
sysconfig.log
Paste the output of 'python -m sysconfig', over this line.
Example pyproject.toml

Poetry Runtime Logs
poetry-runtime.log
Loading configuration file /Users/daniel.soutar/Library/Application Support/pypoetry/config.toml
Adding repository google (https://europe-python.pkg.dev/...) and setting it as explicit
Using virtualenv: /Users/daniel.soutar/Documents/path/to/.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
Creating new session for pypi.org
[urllib3:urllib3.connectionpool] Starting new HTTPS connection (1): pypi.org:443
[urllib3:urllib3.connectionpool] https://pypi.org:443 "GET /simple/pytest/ HTTP/1.1" 304 0
[filelock:filelock] Attempting to acquire lock 4386110576 on /Users/daniel.soutar/Library/Caches/pypoetry/cache/repositories/PyPI/_http/0/c/2/1/8/0c218d526767991766d9b365a4f3e4449ce3579fd8b0f96a707d5a52.lock
[filelock:filelock] Lock 4386110576 acquired on /Users/daniel.soutar/Library/Caches/pypoetry/cache/repositories/PyPI/_http/0/c/2/1/8/0c218d526767991766d9b365a4f3e4449ce3579fd8b0f96a707d5a52.lock
[filelock:filelock] Attempting to release lock 4386110576 on /Users/daniel.soutar/Library/Caches/pypoetry/cache/repositories/PyPI/_http/0/c/2/1/8/0c218d526767991766d9b365a4f3e4449ce3579fd8b0f96a707d5a52.lock
[filelock:filelock] Lock 4386110576 released on /Users/daniel.soutar/Library/Caches/pypoetry/cache/repositories/PyPI/_http/0/c/2/1/8/0c218d526767991766d9b365a4f3e4449ce3579fd8b0f96a707d5a52.lock
Source (PyPI): 180 packages found for pytest *
Using version ^8.4.1 for pytest

Updating dependencies
Resolving dependencies...
 1: fact: ... is 2.1.1
 1: derived: ...
 0: Duplicate dependencies for pytest
 1: Version solving took 0.002 seconds.
 1: Tried 1 solutions.

Stack trace:

17  ~/Library/Application Support/pypoetry/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  ~/Library/Application Support/pypoetry/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  ~/Library/Application Support/pypoetry/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  ~/Library/Application Support/pypoetry/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  ~/Library/Application Support/pypoetry/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  ~/Library/Application Support/pypoetry/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  ~/Library/Application Support/pypoetry/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  ~/Library/Application Support/pypoetry/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  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/console/commands/add.py:376 in handle
     374│         self.installer.whitelist([r["name"] for r in requirements])
     375│ 
   → 376│         status = self.installer.run()
     377│ 
     378│         if status == 0 and not self.option("dry-run"):

 8  ~/Library/Application Support/pypoetry/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  ~/Library/Application Support/pypoetry/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  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/puzzle/solver.py:87 in solve
      85│         with self._progress(), self._provider.use_latest_for(use_latest or []):
      86│             start = time.time()
   →  87│             packages = self._solve()
      88│             # simplify markers by removing redundant information
      89│             for transitive_info in packages.values():

 5  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/puzzle/solver.py:168 in _solve
     166│ 
     167│         try:
   → 168│             result = resolve_version(self._package, self._provider)
     169│ 
     170│             packages = result.packages

 4  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/mixology/__init__.py:18 in resolve_version
      16│     solver = VersionSolver(root, provider)
      17│ 
   →  18│     return solver.solve()
      19│ 

 3  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/mixology/version_solver.py:174 in solve
     172│             while next is not None:
     173│                 self._propagate(next)
   → 174│                 next = self._choose_package_version()
     175│ 
     176│             return self._result()

 2  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/mixology/version_solver.py:572 in _choose_package_version
     570│             package = locked
     571│ 
   → 572│         package = self._provider.complete_package(package)
     573│ 
     574│         conflict = False

 1  ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/puzzle/provider.py:620 in complete_package
      618│                     self._active_root_extras if package.is_root() else dependency.extras
      619│                 )
   →  620│                 deps = self._resolve_overlapping_markers(package, deps, active_extras)
      621│             else:
      622│                 # There are duplicates with different extras.

IncompatibleConstraintsError

Incompatible constraints in requirements of ... (2.1.1):
pytest (>=8.4.1,<9.0.0)
pytest (>=6.2.5,<=8.2.0)

at ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/puzzle/provider.py:973 in _resolve_overlapping_markers
     969│                     specific_source_dependency = dep
     970│                 constraint = constraint.intersect(dep.constraint)
     971│             if constraint.is_empty():
     972│                 # conflict in overlapping area
  →  973│                 raise IncompatibleConstraintsError(package, *used_dependencies)
     974│ 
     975│             if not any(uses):
     976│                 # This is an edge case where the dependency is not required
     977│                 # for the resulting marker. However, we have to consider it anyway

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing poetry add "pytest@latest", then trace the reported entry points in poetry/console/commands/add.py, poetry/installation/installer.py, and poetry/puzzle/provider.py. Compare how the existing pytest dependency and the requested version are combined; done means the command handles the existing dependency without producing incompatible duplicate constraints.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.