Commit d1dbdefc by David Hotham Committed by GitHub

Fix an infinite loop in the solver (#6178)

parent 77003f15
...@@ -513,11 +513,9 @@ class VersionSolver: ...@@ -513,11 +513,9 @@ class VersionSolver:
locked = self._locked.get(dependency.name, []) locked = self._locked.get(dependency.name, [])
for dependency_package in locked: for dependency_package in locked:
package = dependency_package.package package = dependency_package.package
if (allow_similar or dependency.is_same_package_as(package)) and ( if (
dependency.constraint.allows(package.version) allow_similar or dependency.is_same_package_as(package)
or package.is_prerelease() ) and dependency.constraint.allows(package.version):
and dependency.constraint.allows(package.version.next_patch())
):
return DependencyPackage(dependency, package) return DependencyPackage(dependency, package)
return None return None
......
...@@ -46,7 +46,6 @@ if TYPE_CHECKING: ...@@ -46,7 +46,6 @@ if TYPE_CHECKING:
from poetry.core.packages.directory_dependency import DirectoryDependency from poetry.core.packages.directory_dependency import DirectoryDependency
from poetry.core.packages.file_dependency import FileDependency from poetry.core.packages.file_dependency import FileDependency
from poetry.core.packages.package import Package from poetry.core.packages.package import Package
from poetry.core.packages.specification import PackageSpecification
from poetry.core.packages.url_dependency import URLDependency from poetry.core.packages.url_dependency import URLDependency
from poetry.core.packages.vcs_dependency import VCSDependency from poetry.core.packages.vcs_dependency import VCSDependency
from poetry.core.semver.version_constraint import VersionConstraint from poetry.core.semver.version_constraint import VersionConstraint
...@@ -193,11 +192,11 @@ class Provider: ...@@ -193,11 +192,11 @@ class Provider:
def search_for_installed_packages( def search_for_installed_packages(
self, self,
specification: PackageSpecification, dependency: Dependency,
) -> list[Package]: ) -> list[Package]:
""" """
Search for installed packages, when available, that provides the given Search for installed packages, when available, that satisfy the given
specification. dependency.
This is useful when dealing with packages that are under development, not This is useful when dealing with packages that are under development, not
published on package sources and/or only available via system installations. published on package sources and/or only available via system installations.
...@@ -207,17 +206,17 @@ class Provider: ...@@ -207,17 +206,17 @@ class Provider:
logger.debug( logger.debug(
"Falling back to installed packages to discover metadata for <c2>%s</>", "Falling back to installed packages to discover metadata for <c2>%s</>",
specification.complete_name, dependency.complete_name,
) )
packages = [ packages = [
package package
for package in self._installed_packages for package in self._installed_packages
if package.provides(specification) if package.satisfies(dependency, ignore_source_type=True)
] ]
logger.debug( logger.debug(
"Found <c2>%d</> compatible packages for <c2>%s</>", "Found <c2>%d</> compatible packages for <c2>%s</>",
len(packages), len(packages),
specification.complete_name, dependency.complete_name,
) )
return packages return packages
......
...@@ -3648,3 +3648,36 @@ def test_solver_incompatible_dependency_with_and_without_extras( ...@@ -3648,3 +3648,36 @@ def test_solver_incompatible_dependency_with_and_without_extras(
{"job": "install", "package": foo}, {"job": "install", "package": foo},
], ],
) )
def test_update_with_prerelease_and_no_solution(
solver: Solver,
repo: Repository,
installed: InstalledRepository,
package: ProjectPackage,
locked: Repository,
):
# Locked and installed: cleo which depends on an old version of crashtest.
cleo = get_package("cleo", "1.0.0a5")
crashtest = get_package("crashtest", "0.3.0")
cleo.add_dependency(Factory.create_dependency("crashtest", {"version": "<0.4.0"}))
locked.add_package(cleo)
locked.add_package(crashtest)
installed.add_package(cleo)
installed.add_package(crashtest)
# Try to upgrade to a new version of crashtest, this will be disallowed by the
# dependency from cleo.
package.add_dependency(Factory.create_dependency("cleo", "^1.0.0a5"))
package.add_dependency(Factory.create_dependency("crashtest", "^0.4.0"))
newer_crashtest = get_package("crashtest", "0.4.0")
even_newer_crashtest = get_package("crashtest", "0.4.1")
repo.add_package(cleo)
repo.add_package(crashtest)
repo.add_package(newer_crashtest)
repo.add_package(even_newer_crashtest)
with pytest.raises(SolverProblemError):
solver.solve()
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