Skip to content

Commit

Permalink
Fix an infinite loop in the solver (#6178)
Browse files Browse the repository at this point in the history
  • Loading branch information
dimbleby authored Aug 17, 2022
1 parent 77003f1 commit d1dbdef
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 12 deletions.
8 changes: 3 additions & 5 deletions src/poetry/mixology/version_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,11 +513,9 @@ def _get_locked(
locked = self._locked.get(dependency.name, [])
for dependency_package in locked:
package = dependency_package.package
if (allow_similar or dependency.is_same_package_as(package)) and (
dependency.constraint.allows(package.version)
or package.is_prerelease()
and dependency.constraint.allows(package.version.next_patch())
):
if (
allow_similar or dependency.is_same_package_as(package)
) and dependency.constraint.allows(package.version):
return DependencyPackage(dependency, package)
return None

Expand Down
13 changes: 6 additions & 7 deletions src/poetry/puzzle/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
from poetry.core.packages.directory_dependency import DirectoryDependency
from poetry.core.packages.file_dependency import FileDependency
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.vcs_dependency import VCSDependency
from poetry.core.semver.version_constraint import VersionConstraint
Expand Down Expand Up @@ -193,11 +192,11 @@ def validate_package_for_dependency(

def search_for_installed_packages(
self,
specification: PackageSpecification,
dependency: Dependency,
) -> list[Package]:
"""
Search for installed packages, when available, that provides the given
specification.
Search for installed packages, when available, that satisfy the given
dependency.
This is useful when dealing with packages that are under development, not
published on package sources and/or only available via system installations.
Expand All @@ -207,17 +206,17 @@ def search_for_installed_packages(

logger.debug(
"Falling back to installed packages to discover metadata for <c2>%s</>",
specification.complete_name,
dependency.complete_name,
)
packages = [
package
for package in self._installed_packages
if package.provides(specification)
if package.satisfies(dependency, ignore_source_type=True)
]
logger.debug(
"Found <c2>%d</> compatible packages for <c2>%s</>",
len(packages),
specification.complete_name,
dependency.complete_name,
)
return packages

Expand Down
33 changes: 33 additions & 0 deletions tests/puzzle/test_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -3648,3 +3648,36 @@ def test_solver_incompatible_dependency_with_and_without_extras(
{"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()

0 comments on commit d1dbdef

Please sign in to comment.