python-poetry / python-poetry/poetry
Python restricted dependency not working
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 34.3k
- Forks
- 2.5k
- Avg merge
- 2d 19h
- Merged PRs (30d)
- 30
Description
-
Poetry version: 1.2.2
-
Python version: 3.9.13
-
OS version and name: macOS Catalina, Version 0.15.7
-
I am on the latest stable Poetry version, installed using a recommended method.
-
I have searched the issues of this repo and believe that this is not a duplicate.
-
I have consulted the FAQ and blog for any relevant entries or release notes.
-
If an exception occurs when executing a command, I executed it again in debug mode (
-vvvoption) and have included the output below.
Issue
Hi, I'm currently working on a multirepo context and I have a pyproject.toml file that has some other repos between its dependencies. I tried to recreate the situation with three empty repos lib_a, lib_b, lib_c where lib_a depends on the other two.
To reproduce the error just clone this repo: https://github.com/carlotardivo/poetry-issue-6895 and execute a poetry lock -vvv from lib_a root directory.
These are the three pyproject.toml files:
lib_a:
[tool.poetry]
name = "lib_a"
version = "0.1.0"
description = ""
authors = ["Your Name <you@example.com>"]
readme = "README.md"
packages = [{include = "liba"}]
[tool.poetry.dependencies]
python = ">=3.7.13,<3.10"
lib_b={path='../lib_b'}
lib_c={path='../lib_c', optional= true, python = ">=3.9,<3.10"}
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
lib_b
[tool.poetry]
name = "lib_b"
version = "0.1.0"
description = ""
authors = ["Your Name <you@example.com>"]
readme = "README.md"
packages = [{include = "libb"}]
[tool.poetry.dependencies]
python = ">=3.7.13,<3.10"
scipy=[
{version='1.5.*', python='~3.7.13'},
{version='1.8.0', python='>=3.8'}
]
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
lib_c:
[tool.poetry]
name = "lib_c"
version = "0.1.0"
description = ""
authors = ["Your Name <you@example.com>"]
readme = "README.md"
packages = [{include = "libc"}]
[tool.poetry.dependencies]
python = ">=3.9,<3.10"
scipy = { version = "^1.7.0", python = ">=3.9,<3.10" }
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
Expected result
Basically what I'd expect, according to these docs (python restrcted dependencies) is to be able to create a lock file that allows for the creation of an environment with
lib_b(withscipy1.5.*) when python ~3.7.13lib_b(withscipy1.8.0) andlib_cinstalled only when python >=3.9,<3.10
Actual result
The lock file generation breaks with the following error, that seems related to the fact that scipy 1.5 is looked also for python >=3.9,<3.10 (while only ^1.7.0 should in this python range):
(poetry-experiment-py3.9) bash-3.2$ poetry lock -vvv
Loading configuration file /<my-user-local-path>/Library/Preferences/pypoetry/config.toml
Loading configuration file /<my-user-local-path>/Library/Preferences/pypoetry/auth.toml
Using virtualenv: /<my-user-local-path>/Library/Caches/pypoetry/virtualenvs/poetry-experiment-7exzTMzg-py3.9
Project environment contains an empty path in sys_path, ignoring.
Updating dependencies
Resolving dependencies...
1: fact: lib-a is 0.1.0
1: derived: lib-a
1: fact: lib-a depends on lib_b (0.1.0)
1: fact: lib-a depends on lib_c (0.1.0)
1: selecting lib-a (0.1.0)
1: derived: lib_c (0.1.0) @ ../lib_c
1: derived: lib_b (0.1.0) @ ../lib_b
1: fact: lib-c (0.1.0) depends on scipy (^1.7.0)
1: selecting lib-c (0.1.0 /<my-user-local-path>/Desktop/poetry_experiment/lib_c)
1: derived: scipy (>=1.7.0,<2.0.0)
[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
[urllib3.connectionpool] Starting new HTTPS connection (1): pypi.org:443
[urllib3.connectionpool] https://pypi.org:443 "GET /simple/scipy/ HTTP/1.1" 304 0
[filelock] Attempting to acquire lock 4437848368 on /<my-user-local-path>/Library/Caches/pypoetry/cache/repositories/PyPI/_http/c/d/5/d/e/cd5de44b899cbe1869765c21b55cffc53c0c0ffa9d3c6f1fd40a42a2.lock
[filelock] Lock 4437848368 acquired on /<my-user-local-path>/Library/Caches/pypoetry/cache/repositories/PyPI/_http/c/d/5/d/e/cd5de44b899cbe1869765c21b55cffc53c0c0ffa9d3c6f1fd40a42a2.lock
[filelock] Attempting to release lock 4437848368 on /<my-user-local-path>/Library/Caches/pypoetry/cache/repositories/PyPI/_http/c/d/5/d/e/cd5de44b899cbe1869765c21b55cffc53c0c0ffa9d3c6f1fd40a42a2.lock
[filelock] Lock 4437848368 released on /<my-user-local-path>/Library/Caches/pypoetry/cache/repositories/PyPI/_http/c/d/5/d/e/cd5de44b899cbe1869765c21b55cffc53c0c0ffa9d3c6f1fd40a42a2.lock
Source (PyPI): 10 packages found for scipy >=1.7.0,<2.0.0
0: Duplicate dependencies for scipy
0: Different requirements found for scipy (1.5.*) with markers python_full_version >= "3.7.13" and python_full_version < "3.8.0" and scipy (1.8.0) with markers python_version >= "3.8".
1: Version solving took 0.233 seconds.
1: Tried 1 solutions.
0: Retrying dependency resolution with the following overrides ({Package('lib-b', '0.1.0', source_type='directory', source_url='/<my-user-local-path>/Desktop/poetry_experiment/lib_b'): {'scipy': <Dependency scipy (>=1.5.0,<1.6.0)>}}).
1: fact: lib-a is 0.1.0
1: derived: lib-a
1: fact: lib-a depends on lib_b (0.1.0)
1: fact: lib-a depends on lib_c (0.1.0)
1: selecting lib-a (0.1.0)
1: derived: lib_c (0.1.0) @ ../lib_c
1: derived: lib_b (0.1.0) @ ../lib_b
1: fact: lib-c (0.1.0) depends on scipy (^1.7.0)
1: selecting lib-c (0.1.0 /<my-user-local-path>/Desktop/poetry_experiment/lib_c)
1: derived: scipy (>=1.7.0,<2.0.0)
Source (PyPI): 10 packages found for scipy >=1.7.0,<2.0.0
1: fact: lib-b (0.1.0) depends on scipy (1.5.*)
1: conflict: lib-b (0.1.0) depends on scipy (1.5.*)
1: derived: scipy (>=1.5.0,<1.6.0)
1: conflict: lib-c (0.1.0) depends on scipy (^1.7.0)
1: ! not scipy (>=1.7.0,<2.0.0) is satisfied by scipy (>=1.5.0,<1.6.0)
1: ! which is caused by "lib-b (0.1.0) @ file:///<my-user-local-path>/Desktop/poetry_experiment/lib_b depends on scipy (1.5.*)"
1: ! thus: lib-c (0.1.0) @ file:///<my-user-local-path>/Desktop/poetry_experiment/lib_c is incompatible with lib-b (0.1.0) @ file:///<my-user-local-path>/Desktop/poetry_experiment/lib_b
1: ! lib-b (0.1.0) @ file:///<my-user-local-path>/Desktop/poetry_experiment/lib_b is satisfied by lib_b (0.1.0) @ ../lib_b
1: ! which is caused by "lib-a depends on lib_b (0.1.0) @ ../lib_b"
1: ! thus: lib-c is forbidden
1: ! lib-c (0.1.0) @ file:///<my-user-local-path>/Desktop/poetry_experiment/lib_c is satisfied by lib_c (0.1.0) @ ../lib_c
1: ! which is caused by "lib-a depends on lib_c (0.1.0) @ ../lib_c"
1: ! thus: version solving failed
1: Version solving took 0.016 seconds.
1: Tried 1 solutions.
Stack trace:
4 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/puzzle/solver.py:151 in _solve
149│
150│ try:
→ 151│ result = resolve_version(
152│ self._package, self._provider, locked=locked, use_latest=use_latest
153│ )
3 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/mixology/__init__.py:24 in resolve_version
22│ solver = VersionSolver(root, provider, locked=locked, use_latest=use_latest)
23│
→ 24│ return solver.solve()
25│
2 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/mixology/version_solver.py:127 in solve
125│ while next is not None:
126│ self._propagate(next)
→ 127│ next = self._choose_package_version()
128│
129│ return self._result()
1 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/mixology/version_solver.py:446 in _choose_package_version
444│ package = locked
445│
→ 446│ package = self._provider.complete_package(package)
447│
448│ conflict = False
OverrideNeeded
({Package('lib-b', '0.1.0', source_type='directory', source_url='/<my-user-local-path>/Desktop/poetry_experiment/lib_b'): {'scipy': <Dependency scipy (>=1.5.0,<1.6.0)>}}, {Package('lib-b', '0.1.0', source_type='directory', source_url='/<my-user-local-path>/Desktop/poetry_experiment/lib_b'): {'scipy': <Dependency scipy (==1.8.0)>}})
at ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/puzzle/provider.py:764 in complete_package
760│ current_overrides.update({dependency_package: package_overrides})
761│ overrides.append(current_overrides)
762│
763│ if overrides:
→ 764│ raise OverrideNeeded(*overrides)
765│
766│ # Modifying dependencies as needed
767│ clean_dependencies = []
768│ for dep in dependencies:
The following error occurred when trying to handle this error:
Stack trace:
4 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/puzzle/solver.py:151 in _solve
149│
150│ try:
→ 151│ result = resolve_version(
152│ self._package, self._provider, locked=locked, use_latest=use_latest
153│ )
3 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/mixology/__init__.py:24 in resolve_version
22│ solver = VersionSolver(root, provider, locked=locked, use_latest=use_latest)
23│
→ 24│ return solver.solve()
25│
2 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/mixology/version_solver.py:126 in solve
124│ next: str | None = self._root.name
125│ while next is not None:
→ 126│ self._propagate(next)
127│ next = self._choose_package_version()
128│
1 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/mixology/version_solver.py:165 in _propagate
163│ # where that incompatibility will allow us to derive new assignments
164│ # that avoid the conflict.
→ 165│ root_cause = self._resolve_conflict(incompatibility)
166│
167│ # Back jumping erases all the assignments we did at the previous
SolveFailure
Because lib-c (0.1.0) @ file:///<my-user-local-path>/Desktop/poetry_experiment/lib_c depends on scipy (^1.7.0)
and lib-b (0.1.0) @ file:///<my-user-local-path>/Desktop/poetry_experiment/lib_b depends on scipy (1.5.*), lib-c (0.1.0) @ file:///<my-user-local-path>/Desktop/poetry_experiment/lib_c is incompatible with lib-b (0.1.0) @ file:///<my-user-local-path>/Desktop/poetry_experiment/lib_b.
So, because lib-a depends on both lib_b (0.1.0) @ ../lib_b and lib_c (0.1.0) @ ../lib_c, version solving failed.
at ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/mixology/version_solver.py:364 in _resolve_conflict
360│ )
361│ self._log(f'! which is caused by "{most_recent_satisfier.cause}"')
362│ self._log(f"! thus: {incompatibility}")
363│
→ 364│ raise SolveFailure(incompatibility)
365│
366│ def _choose_package_version(self) -> str | None:
367│ """
368│ Tries to select a version of a required package.
The following error occurred when trying to handle this error:
Stack trace:
13 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/cleo/application.py:329 in run
327│
328│ try:
→ 329│ exit_code = self._run(io)
330│ except Exception as e:
331│ if not self._catch_exceptions:
12 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/console/application.py:185 in _run
183│ self._load_plugins(io)
184│
→ 185│ exit_code: int = super()._run(io)
186│ return exit_code
187│
11 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/cleo/application.py:423 in _run
421│ io.input.set_stream(stream)
422│
→ 423│ exit_code = self._run_command(command, io)
424│ self._running_command = None
425│
10 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/cleo/application.py:465 in _run_command
463│
464│ if error is not None:
→ 465│ raise error
466│
467│ return event.exit_code
9 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/cleo/application.py:449 in _run_command
447│
448│ if event.command_should_run():
→ 449│ exit_code = command.run(io)
450│ else:
451│ exit_code = ConsoleCommandEvent.RETURN_CODE_DISABLED
8 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/cleo/commands/base_command.py:119 in run
117│ io.input.validate()
118│
→ 119│ status_code = self.execute(io)
120│
121│ if status_code is None:
7 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/cleo/commands/command.py:83 in execute
81│
82│ try:
→ 83│ return self.handle()
84│ except KeyboardInterrupt:
85│ return 1
6 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/console/commands/lock.py:54 in handle
52│ self.installer.lock(update=not self.option("no-update"))
53│
→ 54│ return self.installer.run()
55│
5 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/installation/installer.py:115 in run
113│ self._execute_operations = False
114│
→ 115│ return self._do_install()
116│
117│ def dry_run(self, dry_run: bool = True) -> Installer:
4 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/installation/installer.py:248 in _do_install
246│ source_root=self._env.path.joinpath("src")
247│ ):
→ 248│ ops = solver.solve(use_latest=self._whitelist).calculate_operations()
249│ else:
250│ self._io.write_line("Installing dependencies from lock file")
3 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/puzzle/solver.py:73 in solve
71│ with self._provider.progress():
72│ start = time.time()
→ 73│ packages, depths = self._solve(use_latest=use_latest)
74│ end = time.time()
75│
2 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/puzzle/solver.py:157 in _solve
155│ packages = result.packages
156│ except OverrideNeeded as e:
→ 157│ return self.solve_in_compatibility_mode(e.overrides, use_latest=use_latest)
158│ except SolveFailure as e:
159│ raise SolverProblemError(e)
1 ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/puzzle/solver.py:116 in solve_in_compatibility_mode
114│ )
115│ self._provider.set_overrides(override)
→ 116│ _packages, _depths = self._solve(use_latest=use_latest)
117│ for index, package in enumerate(_packages):
118│ if package not in packages:
SolverProblemError
Because lib-c (0.1.0) @ file:///<my-user-local-path>/Desktop/poetry_experiment/lib_c depends on scipy (^1.7.0)
and lib-b (0.1.0) @ file:///<my-user-local-path>/Desktop/poetry_experiment/lib_b depends on scipy (1.5.*), lib-c (0.1.0) @ file:///<my-user-local-path>/Desktop/poetry_experiment/lib_c is incompatible with lib-b (0.1.0) @ file:///<my-user-local-path>/Desktop/poetry_experiment/lib_b.
So, because lib-a depends on both lib_b (0.1.0) @ ../lib_b and lib_c (0.1.0) @ ../lib_c, version solving failed.
at ~/Library/Application Support/pypoetry/venv/lib/python3.9/site-packages/poetry/puzzle/solver.py:159 in _solve
155│ packages = result.packages
156│ except OverrideNeeded as e:
157│ return self.solve_in_compatibility_mode(e.overrides, use_latest=use_latest)
158│ except SolveFailure as e:
→ 159│ raise SolverProblemError(e)
160│
161│ combined_nodes = depth_first_search(PackageNode(self._package, packages))
162│ results = dict(aggregate_package_nodes(nodes) for nodes in combined_nodes)
163│
I'm I missing something?
Thank you very much.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Clone the linked reproduction repository and run poetry lock -vvv from the lib_a root to confirm the failure. Start by reading poetry/puzzle/solver.py, poetry/mixology/version_solver.py, and poetry/puzzle/provider.py around the reported stack frames and override handling. Done means the example resolves its Python-restricted dependencies and the existing failure path is covered by a regression test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- build-system, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100