diff --git a/news/10482.bugfix.rst b/news/10482.bugfix.rst new file mode 100644 index 00000000000..b6cf64f23c6 --- /dev/null +++ b/news/10482.bugfix.rst @@ -0,0 +1 @@ +New resolver: Fixes depth ordering of packages during resolution, e.g. a dependency 2 levels deep will be ordered before a dependecy 3 levels deep. diff --git a/src/pip/_internal/resolution/resolvelib/provider.py b/src/pip/_internal/resolution/resolvelib/provider.py index 632854d3bc5..a3250b35161 100644 --- a/src/pip/_internal/resolution/resolvelib/provider.py +++ b/src/pip/_internal/resolution/resolvelib/provider.py @@ -112,9 +112,9 @@ def get_preference( for _, parent in information[identifier] ) inferred_depth = min(d for d in parent_depths) + 1.0 - self._known_depths[identifier] = inferred_depth else: inferred_depth = 1.0 + self._known_depths[identifier] = inferred_depth requested_order = self._user_requested.get(identifier, math.inf) diff --git a/tests/unit/resolution_resolvelib/test_provider.py b/tests/unit/resolution_resolvelib/test_provider.py new file mode 100644 index 00000000000..97025428069 --- /dev/null +++ b/tests/unit/resolution_resolvelib/test_provider.py @@ -0,0 +1,65 @@ +from pip._vendor.resolvelib.resolvers import RequirementInformation + +from pip._internal.models.candidate import InstallationCandidate +from pip._internal.models.link import Link +from pip._internal.req.constructors import install_req_from_req_string +from pip._internal.resolution.resolvelib.provider import PipProvider +from pip._internal.resolution.resolvelib.requirements import SpecifierRequirement + + +def build_requirement_information(name, parent): + install_requirement = install_req_from_req_string(name) + requirement_information = RequirementInformation( + requirement=SpecifierRequirement(install_requirement), parent=parent + ) + return [requirement_information] + + +def test_provider_known_depths(factory): + # Root requirement is specified by the user + # therefore has an infered depth of 1 + root_requirement_name = "my-package" + provider = PipProvider( + factory=factory, + constraints={}, + ignore_dependencies=False, + upgrade_strategy="to-satisfy-only", + user_requested={root_requirement_name: 0}, + ) + + root_requirement_information = build_requirement_information( + name=root_requirement_name, parent=None + ) + provider.get_preference( + identifier=root_requirement_name, + resolutions={}, + candidates={}, + information={root_requirement_name: root_requirement_information}, + ) + assert provider._known_depths == {root_requirement_name: 1.0} + + # Transative requirement is a dependency of root requirement + # theforefore has an infered depth of 2 + root_package_candidate = InstallationCandidate( + root_requirement_name, + "1.0", + Link("https://{root_requirement_name}.com"), + ) + transative_requirement_name = "my-transitive-package" + + transative_package_information = build_requirement_information( + name=transative_requirement_name, parent=root_package_candidate + ) + provider.get_preference( + identifier=transative_requirement_name, + resolutions={}, + candidates={}, + information={ + root_requirement_name: root_requirement_information, + transative_requirement_name: transative_package_information, + }, + ) + assert provider._known_depths == { + transative_requirement_name: 2.0, + root_requirement_name: 1.0, + }