From 92ad71761266b1164b8733415fd6f93c58b68822 Mon Sep 17 00:00:00 2001 From: Tzu-ping Chung Date: Tue, 15 Dec 2020 16:07:07 +0800 Subject: [PATCH] New resolver incorrectly tries unneeded candidates When the new resolver needs to upgrade a package, it puts the already-installed package in the middle of the candidate list obtained from indexes. But when doing it, the candidate list is eagerly consumed, causing pip to download all candidates. --- tests/functional/test_new_resolver.py | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/functional/test_new_resolver.py b/tests/functional/test_new_resolver.py index 66493a777c2..f3850c208c6 100644 --- a/tests/functional/test_new_resolver.py +++ b/tests/functional/test_new_resolver.py @@ -1235,3 +1235,45 @@ def test_new_resolver_skip_inconsistent_metadata(script): assert " different version in metadata: '2'" in result.stderr, str(result) assert_installed(script, a="1") + + +@pytest.mark.parametrize( + "upgrade", + [True, False], + ids=["upgrade", "no-upgrade"], +) +def test_new_resolver_lazy_fetch_candidates(script, upgrade): + create_basic_wheel_for_package(script, "myuberpkg", "1") + create_basic_wheel_for_package(script, "myuberpkg", "2") + create_basic_wheel_for_package(script, "myuberpkg", "3") + + # Install an old version first. + script.pip( + "install", + "--no-cache-dir", "--no-index", + "--find-links", script.scratch_path, + "myuberpkg==1", + ) + + # Now install the same package again, maybe with the upgrade flag. + if upgrade: + pip_upgrade_args = ["--upgrade"] + else: + pip_upgrade_args = [] + result = script.pip( + "install", + "--no-cache-dir", "--no-index", + "--find-links", script.scratch_path, + "myuberpkg", + *pip_upgrade_args # Trailing comma fails on Python 2. + ) + + # pip should install the version preferred by the strategy... + if upgrade: + assert_installed(script, myuberpkg="3") + else: + assert_installed(script, myuberpkg="1") + + # But should reach there in the best route possible, without trying + # candidates it does not need to. + assert "myuberpkg-2" not in result.stdout, str(result)