Skip to content

Commit 6328294

Browse files
authored
Merge pull request #12224 from ddelange/ddelange-patch-1
2 parents 50c49f1 + 55205b9 commit 6328294

File tree

4 files changed

+62
-0
lines changed

4 files changed

+62
-0
lines changed

docs/html/reference/installation-report.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ package with the following properties:
5656
URL reference. `false` if the requirements was provided as a name and version
5757
specifier.
5858

59+
- `is_yanked`: `true` if the requirement was yanked from the index, but was still
60+
selected by pip conform to [PEP 592](https://peps.python.org/pep-0592/#installers).
61+
5962
- `download_info`: Information about the artifact (to be) downloaded for installation,
6063
using the [direct URL data
6164
structure](https://packaging.python.org/en/latest/specifications/direct-url-data-structure/).
@@ -106,6 +109,7 @@ will produce an output similar to this (metadata abriged for brevity):
106109
}
107110
},
108111
"is_direct": false,
112+
"is_yanked": false,
109113
"requested": true,
110114
"metadata": {
111115
"name": "pydantic",
@@ -133,6 +137,7 @@ will produce an output similar to this (metadata abriged for brevity):
133137
}
134138
},
135139
"is_direct": true,
140+
"is_yanked": false,
136141
"requested": true,
137142
"metadata": {
138143
"name": "packaging",

news/12224.feature.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add ``is_yanked`` boolean entry to the installation report (``--report``) to indicate whether the requirement was yanked from the index, but was still selected by pip conform to PEP 592.

src/pip/_internal/models/installation_report.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ def _install_req_to_dict(cls, ireq: InstallRequirement) -> Dict[str, Any]:
2323
# includes editable requirements), and false if the requirement was
2424
# downloaded from a PEP 503 index or --find-links.
2525
"is_direct": ireq.is_direct,
26+
# is_yanked is true if the requirement was yanked from the index, but
27+
# was still selected by pip to conform to PEP 592.
28+
"is_yanked": ireq.link.is_yanked if ireq.link else False,
2629
# requested is true if the requirement was specified by the user (aka
2730
# top level requirement), and false if it was installed as a dependency of a
2831
# requirement. https://peps.python.org/pep-0376/#requested

tests/functional/test_install_report.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,59 @@ def test_install_report_dep(
6464
assert _install_dict(report)["simple"]["requested"] is False
6565

6666

67+
def test_yanked_version(
68+
script: PipTestEnvironment, data: TestData, tmp_path: Path
69+
) -> None:
70+
"""
71+
Test is_yanked is True when explicitly requesting a yanked package.
72+
Yanked files are always ignored, unless they are the only file that
73+
matches a version specifier that "pins" to an exact version (PEP 592).
74+
"""
75+
report_path = tmp_path / "report.json"
76+
script.pip(
77+
"install",
78+
"simple==3.0",
79+
"--index-url",
80+
data.index_url("yanked"),
81+
"--dry-run",
82+
"--report",
83+
str(report_path),
84+
allow_stderr_warning=True,
85+
)
86+
report = json.loads(report_path.read_text())
87+
simple_report = _install_dict(report)["simple"]
88+
assert simple_report["requested"] is True
89+
assert simple_report["is_direct"] is False
90+
assert simple_report["is_yanked"] is True
91+
assert simple_report["metadata"]["version"] == "3.0"
92+
93+
94+
def test_skipped_yanked_version(
95+
script: PipTestEnvironment, data: TestData, tmp_path: Path
96+
) -> None:
97+
"""
98+
Test is_yanked is False when not explicitly requesting a yanked package.
99+
Yanked files are always ignored, unless they are the only file that
100+
matches a version specifier that "pins" to an exact version (PEP 592).
101+
"""
102+
report_path = tmp_path / "report.json"
103+
script.pip(
104+
"install",
105+
"simple",
106+
"--index-url",
107+
data.index_url("yanked"),
108+
"--dry-run",
109+
"--report",
110+
str(report_path),
111+
)
112+
report = json.loads(report_path.read_text())
113+
simple_report = _install_dict(report)["simple"]
114+
assert simple_report["requested"] is True
115+
assert simple_report["is_direct"] is False
116+
assert simple_report["is_yanked"] is False
117+
assert simple_report["metadata"]["version"] == "2.0"
118+
119+
67120
@pytest.mark.network
68121
def test_install_report_index(script: PipTestEnvironment, tmp_path: Path) -> None:
69122
"""Test report for sdist obtained from index."""

0 commit comments

Comments
 (0)