Skip to content

Commit 0778c1c

Browse files
authored
Merge pull request #12193 from cosmicexplorer/metadata-behavior-testing
2 parents 5378a6e + 8704c7a commit 0778c1c

File tree

5 files changed

+110
-22
lines changed

5 files changed

+110
-22
lines changed

news/12183.trivial.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add test cases for some behaviors of ``install --dry-run`` and ``--use-feature=fast-deps``.

tests/functional/test_fast_deps.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
import json
33
import os
44
import pathlib
5+
import re
56
from os.path import basename
67
from typing import Iterable
78

89
from pip._vendor.packaging.utils import canonicalize_name
910
from pytest import mark
1011

12+
from pip._internal.utils.misc import hash_file
1113
from tests.lib import PipTestEnvironment, TestData, TestPipResult
1214

1315

@@ -101,3 +103,36 @@ def test_hash_mismatch(script: PipTestEnvironment, tmp_path: pathlib.Path) -> No
101103
expect_error=True,
102104
)
103105
assert "DO NOT MATCH THE HASHES" in result.stderr
106+
107+
108+
@mark.network
109+
def test_hash_mismatch_existing_download_for_metadata_only_wheel(
110+
script: PipTestEnvironment, tmp_path: pathlib.Path
111+
) -> None:
112+
"""Metadata-only wheels from PEP 658 or fast-deps check for hash matching in
113+
a separate code path than when the wheel is downloaded all at once. Make sure we
114+
still check for hash mismatches."""
115+
reqs = tmp_path / "requirements.txt"
116+
reqs.write_text("idna==2.10")
117+
dl_dir = tmp_path / "downloads"
118+
dl_dir.mkdir()
119+
idna_wheel = dl_dir / "idna-2.10-py2.py3-none-any.whl"
120+
idna_wheel.write_text("asdf")
121+
result = script.pip(
122+
"download",
123+
# Ensure that we have a metadata-only dist for idna.
124+
"--use-feature=fast-deps",
125+
"-r",
126+
str(reqs),
127+
"-d",
128+
str(dl_dir),
129+
allow_stderr_warning=True,
130+
)
131+
assert re.search(
132+
r"WARNING: Previously-downloaded file.*has bad hash", result.stderr
133+
)
134+
# This is the correct hash for idna==2.10.
135+
assert (
136+
hash_file(str(idna_wheel))[0].hexdigest()
137+
== "b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"
138+
)

tests/functional/test_install.py

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import textwrap
88
from os.path import curdir, join, pardir
99
from pathlib import Path
10-
from typing import Dict, List, Tuple
10+
from typing import Dict, Iterable, List, Optional, Tuple
1111

1212
import pytest
1313

@@ -20,6 +20,7 @@
2020
PipTestEnvironment,
2121
ResolverVariant,
2222
TestData,
23+
TestPipResult,
2324
_create_svn_repo,
2425
_create_test_package,
2526
create_basic_wheel_for_package,
@@ -2371,14 +2372,68 @@ def test_install_logs_pip_version_in_debug(
23712372
assert_re_match(pattern, result.stdout)
23722373

23732374

2374-
def test_install_dry_run(script: PipTestEnvironment, data: TestData) -> None:
2375-
"""Test that pip install --dry-run logs what it would install."""
2376-
result = script.pip(
2377-
"install", "--dry-run", "--find-links", data.find_links, "simple"
2375+
def install_find_links(
2376+
script: PipTestEnvironment,
2377+
data: TestData,
2378+
args: Iterable[str],
2379+
*,
2380+
dry_run: bool,
2381+
target_dir: Optional[Path],
2382+
) -> TestPipResult:
2383+
return script.pip(
2384+
"install",
2385+
*(
2386+
(
2387+
"--target",
2388+
str(target_dir),
2389+
)
2390+
if target_dir is not None
2391+
else ()
2392+
),
2393+
*(("--dry-run",) if dry_run else ()),
2394+
"--no-index",
2395+
"--find-links",
2396+
data.find_links,
2397+
*args,
2398+
)
2399+
2400+
2401+
@pytest.mark.parametrize(
2402+
"with_target_dir",
2403+
(True, False),
2404+
)
2405+
def test_install_dry_run_nothing_installed(
2406+
script: PipTestEnvironment,
2407+
data: TestData,
2408+
tmpdir: Path,
2409+
with_target_dir: bool,
2410+
) -> None:
2411+
"""Test that pip install --dry-run logs what it would install, but doesn't actually
2412+
install anything."""
2413+
if with_target_dir:
2414+
install_dir = tmpdir / "fake-install"
2415+
install_dir.mkdir()
2416+
else:
2417+
install_dir = None
2418+
2419+
result = install_find_links(
2420+
script, data, ["simple"], dry_run=True, target_dir=install_dir
23782421
)
23792422
assert "Would install simple-3.0" in result.stdout
23802423
assert "Successfully installed" not in result.stdout
23812424

2425+
script.assert_not_installed("simple")
2426+
if with_target_dir:
2427+
assert not os.listdir(install_dir)
2428+
2429+
# Ensure that the same install command would normally have worked if not for
2430+
# --dry-run.
2431+
install_find_links(script, data, ["simple"], dry_run=False, target_dir=install_dir)
2432+
if with_target_dir:
2433+
assert os.listdir(install_dir)
2434+
else:
2435+
script.assert_installed(simple="3.0")
2436+
23822437

23832438
@pytest.mark.skipif(
23842439
sys.version_info < (3, 11),

tests/unit/metadata/test_metadata.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,17 @@ def test_dist_found_in_zip(tmp_path: Path) -> None:
129129
dist = get_environment([location]).get_distribution("pkg")
130130
assert dist is not None and dist.location is not None
131131
assert Path(dist.location) == Path(location)
132+
133+
134+
@pytest.mark.parametrize(
135+
"path",
136+
(
137+
"/path/to/foo.egg-info".replace("/", os.path.sep),
138+
# Tests issue fixed by https://github.com/pypa/pip/pull/2530
139+
"/path/to/foo.egg-info/".replace("/", os.path.sep),
140+
),
141+
)
142+
def test_trailing_slash_directory_metadata(path: str) -> None:
143+
dist = get_directory_distribution(path)
144+
assert dist.raw_name == dist.canonical_name == "foo"
145+
assert dist.location == "/path/to".replace("/", os.path.sep)

tests/unit/test_req.py

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
PreviousBuildDirError,
2424
)
2525
from pip._internal.index.package_finder import PackageFinder
26-
from pip._internal.metadata import select_backend
2726
from pip._internal.models.direct_url import ArchiveInfo, DirectUrl, DirInfo, VcsInfo
2827
from pip._internal.models.link import Link
2928
from pip._internal.network.session import PipSession
@@ -600,22 +599,6 @@ def test_url_preserved_editable_req(self) -> None:
600599
assert req.link is not None
601600
assert req.link.url == url
602601

603-
@pytest.mark.parametrize(
604-
"path",
605-
(
606-
"/path/to/foo.egg-info".replace("/", os.path.sep),
607-
# Tests issue fixed by https://github.com/pypa/pip/pull/2530
608-
"/path/to/foo.egg-info/".replace("/", os.path.sep),
609-
),
610-
)
611-
def test_get_dist(self, path: str) -> None:
612-
req = install_req_from_line("foo")
613-
req.metadata_directory = path
614-
dist = req.get_dist()
615-
assert isinstance(dist, select_backend().Distribution)
616-
assert dist.raw_name == dist.canonical_name == "foo"
617-
assert dist.location == "/path/to".replace("/", os.path.sep)
618-
619602
def test_markers(self) -> None:
620603
for line in (
621604
# recommended syntax

0 commit comments

Comments
 (0)