Commit b06658f9 by Randy Döring Committed by GitHub

Fix for "poetry lock --no-update" so that dependencies with extras are not…

Fix for "poetry lock --no-update" so that dependencies with extras are not updated unnecessarily (#4618)

* Fix for "poetry lock --no-update" so that dependencies with extras are not updated unnecessarily

* None check instead of "or"

* Simplified logic (giving up possibility of early return when no matching version is found)

* Rename local variable for clarity
parent 70e38a19
......@@ -2,6 +2,7 @@ from __future__ import annotations
import time
from contextlib import suppress
from typing import TYPE_CHECKING
from poetry.core.packages.dependency import Dependency
......@@ -365,12 +366,21 @@ class VersionSolver:
)
return dependency.complete_name
try:
version = packages[0]
except IndexError:
version = None
package = None
if dependency.name not in self._use_latest:
# prefer locked version of compatible (not exact same) dependency;
# required in order to not unnecessarily update dependencies with
# extras, e.g. "coverage" vs. "coverage[toml]"
locked = self._locked.get(dependency.name, None)
if locked is not None:
package = next(
(p for p in packages if p.version == locked.version), None
)
if package is None:
with suppress(IndexError):
package = packages[0]
if version is None:
if package is None:
# If there are no versions that satisfy the constraint,
# add an incompatibility that indicates that.
self._add_incompatibility(
......@@ -379,12 +389,12 @@ class VersionSolver:
return dependency.complete_name
else:
version = locked
package = locked
version = self._provider.complete_package(version)
package = self._provider.complete_package(package)
conflict = False
for incompatibility in self._provider.incompatibilities_for(version):
for incompatibility in self._provider.incompatibilities_for(package):
self._add_incompatibility(incompatibility)
# If an incompatibility is already satisfied, then selecting version
......@@ -399,9 +409,9 @@ class VersionSolver:
)
if not conflict:
self._solution.decide(version)
self._solution.decide(package)
self._log(
f"selecting {version.complete_name} ({version.full_pretty_version})"
f"selecting {package.complete_name} ({package.full_pretty_version})"
)
return dependency.complete_name
......
......@@ -136,3 +136,35 @@ def test_with_compatible_locked_dependencies_use_latest(
},
use_latest=["foo"],
)
def test_with_compatible_locked_dependencies_with_extras(
root: ProjectPackage, provider: Provider, repo: Repository
):
root.add_dependency(Factory.create_dependency("foo", "^1.0"))
package_foo_0 = get_package("foo", "1.0.0")
package_foo_1 = get_package("foo", "1.0.1")
bar_extra_dep = Factory.create_dependency(
"bar", {"version": "^1.0", "extras": "extra"}
)
for package_foo in (package_foo_0, package_foo_1):
package_foo.add_dependency(bar_extra_dep)
repo.add_package(package_foo)
bar_deps = {"baz": {"version": "^1.0", "extras": ["extra"]}}
add_to_repo(repo, "bar", "1.0.0", bar_deps)
add_to_repo(repo, "bar", "1.0.1", bar_deps)
add_to_repo(repo, "baz", "1.0.0")
add_to_repo(repo, "baz", "1.0.1")
check_solver_result(
root,
provider,
result={"foo": "1.0.0", "bar": "1.0.0", "baz": "1.0.0"},
locked={
"foo": get_package("foo", "1.0.0"),
"bar": get_package("bar", "1.0.0"),
"baz": get_package("baz", "1.0.0"),
},
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment