diff --git a/news/7490.trivial b/news/7490.trivial new file mode 100644 index 00000000000..25619f36b8e --- /dev/null +++ b/news/7490.trivial @@ -0,0 +1 @@ +Fix unrelease bug from #7319. diff --git a/src/pip/_internal/cache.py b/src/pip/_internal/cache.py index 8c2041527c1..53c3aed927e 100644 --- a/src/pip/_internal/cache.py +++ b/src/pip/_internal/cache.py @@ -138,11 +138,13 @@ def _get_candidates(self, link, canonical_package_name): candidates = [] path = self.get_path_for_link(link) if os.path.isdir(path): - candidates.extend(os.listdir(path)) + for candidate in os.listdir(path): + candidates.append((candidate, path)) # TODO remove legacy path lookup in pip>=21 legacy_path = self.get_path_for_link_legacy(link) if os.path.isdir(legacy_path): - candidates.extend(os.listdir(legacy_path)) + for candidate in os.listdir(legacy_path): + candidates.append((candidate, legacy_path)) return candidates def get_path_for_link_legacy(self, link): @@ -167,13 +169,6 @@ def get( """ raise NotImplementedError() - def _link_for_candidate(self, link, candidate): - # type: (Link, str) -> Link - root = self.get_path_for_link(link) - path = os.path.join(root, candidate) - - return Link(path_to_url(path)) - def cleanup(self): # type: () -> None pass @@ -228,7 +223,9 @@ def get( return link canonical_package_name = canonicalize_name(package_name) - for wheel_name in self._get_candidates(link, canonical_package_name): + for wheel_name, wheel_dir in self._get_candidates( + link, canonical_package_name + ): try: wheel = Wheel(wheel_name) except InvalidWheelFilename: @@ -245,13 +242,18 @@ def get( # Built for a different python/arch/etc continue candidates.append( - (wheel.support_index_min(supported_tags), wheel_name) + ( + wheel.support_index_min(supported_tags), + wheel_name, + wheel_dir, + ) ) if not candidates: return link - return self._link_for_candidate(link, min(candidates)[1]) + _, wheel_name, wheel_dir = min(candidates) + return Link(path_to_url(os.path.join(wheel_dir, wheel_name))) class EphemWheelCache(SimpleWheelCache): diff --git a/tests/unit/test_cache.py b/tests/unit/test_cache.py index 8926f3af84e..5d81fc01d14 100644 --- a/tests/unit/test_cache.py +++ b/tests/unit/test_cache.py @@ -39,7 +39,9 @@ def test_wheel_name_filter(tmpdir): with open(os.path.join(cache_path, "package-1.0-py3-none-any.whl"), "w"): pass # package matches wheel name - assert wc.get(link, "package", [("py3", "none", "any")]) is not link + cached_link = wc.get(link, "package", [("py3", "none", "any")]) + assert cached_link is not link + assert os.path.exists(cached_link.file_path) # package2 does not match wheel name assert wc.get(link, "package2", [("py3", "none", "any")]) is link @@ -56,7 +58,7 @@ def test_cache_hash(): def test_get_path_for_link_legacy(tmpdir): """ Test that an existing cache entry that was created with the legacy hashing - mechanism is used. + mechanism is returned by WheelCache._get_candidates(). """ wc = WheelCache(tmpdir, FormatControl()) link = Link("https://g.c/o/r") @@ -64,10 +66,31 @@ def test_get_path_for_link_legacy(tmpdir): legacy_path = wc.get_path_for_link_legacy(link) assert path != legacy_path ensure_dir(path) - with open(os.path.join(path, "test-pyz-none-any.whl"), "w"): + with open(os.path.join(path, "test-1.0.0-pyz-none-any.whl"), "w"): pass ensure_dir(legacy_path) - with open(os.path.join(legacy_path, "test-pyx-none-any.whl"), "w"): + with open(os.path.join(legacy_path, "test-1.0.0-pyx-none-any.whl"), "w"): pass - expected_candidates = {"test-pyx-none-any.whl", "test-pyz-none-any.whl"} - assert set(wc._get_candidates(link, "test")) == expected_candidates + expected_candidates = { + "test-1.0.0-pyx-none-any.whl", "test-1.0.0-pyz-none-any.whl" + } + candidates = {c[0] for c in wc._get_candidates(link, "test")} + assert candidates == expected_candidates + + +def test_get_with_legacy_entry_only(tmpdir): + """ + Test that an existing cache entry that was created with the legacy hashing + mechanism is actually returned in WheelCache.get(). + """ + wc = WheelCache(tmpdir, FormatControl()) + link = Link("https://g.c/o/r") + legacy_path = wc.get_path_for_link_legacy(link) + ensure_dir(legacy_path) + with open(os.path.join(legacy_path, "test-1.0.0-py3-none-any.whl"), "w"): + pass + cached_link = wc.get(link, "test", [("py3", "none", "any")]) + assert ( + os.path.normcase(os.path.dirname(cached_link.file_path)) == + os.path.normcase(legacy_path) + )