Skip to content

Commit 05d2b85

Browse files
committed
Add unit tests for cache origin.json... and fix a bug
1 parent 6b18cba commit 05d2b85

File tree

2 files changed

+64
-11
lines changed

2 files changed

+64
-11
lines changed

src/pip/_internal/operations/prepare.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -505,21 +505,22 @@ def _prepare_linked_requirement(
505505
# prepare_editable_requirement).
506506
assert not req.editable
507507
req.download_info = direct_url_from_link(link, req.source_dir)
508-
509-
# For use in later processing,
510-
# preserve the file path on the requirement.
511-
if local_file:
512-
req.local_file_path = local_file.path
513508
# Make sure we have a hash in download_info. If we got it as part of the
514509
# URL, it will have been verified and we can rely on it. Otherwise we
515510
# compute it from the downloaded file.
516511
if (
517512
isinstance(req.download_info.info, ArchiveInfo)
518513
and not req.download_info.info.hash
514+
and local_file
519515
):
520516
hash = hash_file(local_file.path)[0].hexdigest()
521517
req.download_info.info.hash = f"sha256={hash}"
522518

519+
# For use in later processing,
520+
# preserve the file path on the requirement.
521+
if local_file:
522+
req.local_file_path = local_file.path
523+
523524
dist = _get_prepared_distribution(
524525
req,
525526
self.build_tracker,

tests/unit/test_req.py

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
import sys
66
import tempfile
77
from functools import partial
8-
from typing import Iterator, Tuple, cast
8+
from typing import Iterator, Optional, Tuple, cast
99
from unittest import mock
1010

1111
import pytest
1212
from pip._vendor.packaging.markers import Marker
1313
from pip._vendor.packaging.requirements import Requirement
1414

15+
from pip._internal.cache import WheelCache
1516
from pip._internal.commands import create_command
1617
from pip._internal.commands.install import InstallCommand
1718
from pip._internal.exceptions import (
@@ -22,7 +23,9 @@
2223
)
2324
from pip._internal.index.package_finder import PackageFinder
2425
from pip._internal.metadata import select_backend
25-
from pip._internal.models.direct_url import ArchiveInfo, DirInfo, VcsInfo
26+
from pip._internal.models.direct_url import ArchiveInfo, DirectUrl, DirInfo, VcsInfo
27+
from pip._internal.models.format_control import FormatControl
28+
from pip._internal.models.link import Link
2629
from pip._internal.network.session import PipSession
2730
from pip._internal.operations.build.build_tracker import get_build_tracker
2831
from pip._internal.operations.prepare import RequirementPreparer
@@ -43,7 +46,7 @@
4346
)
4447
from pip._internal.resolution.legacy.resolver import Resolver
4548
from pip._internal.utils.urls import path_to_url
46-
from tests.lib import TestData, make_test_finder, requirements_file
49+
from tests.lib import TestData, make_test_finder, requirements_file, wheel
4750
from tests.lib.path import Path
4851

4952

@@ -77,7 +80,10 @@ def teardown(self) -> None:
7780

7881
@contextlib.contextmanager
7982
def _basic_resolver(
80-
self, finder: PackageFinder, require_hashes: bool = False
83+
self,
84+
finder: PackageFinder,
85+
require_hashes: bool = False,
86+
wheel_cache: Optional[WheelCache] = None,
8187
) -> Iterator[Resolver]:
8288
make_install_req = partial(
8389
install_req_from_req_string,
@@ -106,7 +112,7 @@ def _basic_resolver(
106112
preparer=preparer,
107113
make_install_req=make_install_req,
108114
finder=finder,
109-
wheel_cache=None,
115+
wheel_cache=wheel_cache,
110116
use_user_site=False,
111117
upgrade_strategy="to-satisfy-only",
112118
ignore_dependencies=False,
@@ -366,7 +372,6 @@ def test_download_info_index_url(self) -> None:
366372
req = reqset.all_requirements[0]
367373
assert req.download_info
368374
assert isinstance(req.download_info.info, ArchiveInfo)
369-
assert req.download_info.info.hash
370375

371376
@pytest.mark.network
372377
def test_download_info_web_archive(self) -> None:
@@ -391,6 +396,53 @@ def test_download_info_web_archive(self) -> None:
391396
"ad977496000576e1b6c41f6449a9897087ce9da6db4f15b603fe8372af4bf3c6"
392397
)
393398

399+
def test_download_info_archive_legacy_cache(
400+
self, tmp_path: Path, shared_data: TestData
401+
) -> None:
402+
"""Test download_info hash is not set for an archive with legacy cache entry."""
403+
url = path_to_url(shared_data.packages / "simple-1.0.tar.gz")
404+
finder = make_test_finder()
405+
wheel_cache = WheelCache(str(tmp_path / "cache"), FormatControl())
406+
cache_entry_dir = wheel_cache.get_path_for_link(Link(url))
407+
Path(cache_entry_dir).mkdir(parents=True)
408+
wheel.make_wheel(name="simple", version="1.0").save_to_dir(cache_entry_dir)
409+
with self._basic_resolver(finder, wheel_cache=wheel_cache) as resolver:
410+
ireq = get_processed_req_from_line(f"simple @ {url}")
411+
reqset = resolver.resolve([ireq], True)
412+
assert len(reqset.all_requirements) == 1
413+
req = reqset.all_requirements[0]
414+
assert req.original_link_is_in_wheel_cache
415+
assert req.download_info
416+
assert req.download_info.url == url
417+
assert isinstance(req.download_info.info, ArchiveInfo)
418+
assert not req.download_info.info.hash
419+
420+
def test_download_info_archive_cache_with_origin(
421+
self, tmp_path: Path, shared_data: TestData
422+
) -> None:
423+
"""Test download_info hash is set for a web archive with cache entry
424+
that has origin.json."""
425+
url = path_to_url(shared_data.packages / "simple-1.0.tar.gz")
426+
hash = "sha256=ad977496000576e1b6c41f6449a9897087ce9da6db4f15b603fe8372af4bf3c6"
427+
finder = make_test_finder()
428+
wheel_cache = WheelCache(str(tmp_path / "cache"), FormatControl())
429+
cache_entry_dir = wheel_cache.get_path_for_link(Link(url))
430+
Path(cache_entry_dir).mkdir(parents=True)
431+
Path(cache_entry_dir).joinpath("origin.json").write_text(
432+
DirectUrl(url, ArchiveInfo(hash=hash)).to_json()
433+
)
434+
wheel.make_wheel(name="simple", version="1.0").save_to_dir(cache_entry_dir)
435+
with self._basic_resolver(finder, wheel_cache=wheel_cache) as resolver:
436+
ireq = get_processed_req_from_line(f"simple @ {url}")
437+
reqset = resolver.resolve([ireq], True)
438+
assert len(reqset.all_requirements) == 1
439+
req = reqset.all_requirements[0]
440+
assert req.original_link_is_in_wheel_cache
441+
assert req.download_info
442+
assert req.download_info.url == url
443+
assert isinstance(req.download_info.info, ArchiveInfo)
444+
assert req.download_info.info.hash == hash
445+
394446
def test_download_info_local_wheel(self, data: TestData) -> None:
395447
"""Test that download_info is set for requirements from a local wheel."""
396448
finder = make_test_finder()

0 commit comments

Comments
 (0)