From 361b02bce0a7283bacd1f26bca64e3facd64aecf Mon Sep 17 00:00:00 2001 From: ddelange <14880945+ddelange@users.noreply.github.com> Date: Mon, 14 Aug 2023 19:09:50 +0200 Subject: [PATCH 1/4] Add is_yanked to installation report --- news/12224.feature.rst | 1 + .../_internal/models/installation_report.py | 3 ++ tests/functional/test_install_report.py | 53 +++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 news/12224.feature.rst diff --git a/news/12224.feature.rst b/news/12224.feature.rst new file mode 100644 index 000000000..5a6977254 --- /dev/null +++ b/news/12224.feature.rst @@ -0,0 +1 @@ +Add ``is_yanked`` boolean entry to the installation report (``--report``) to indicate whether the requirement was yanked from the index, but still was selected by pip conform PEP 592. diff --git a/src/pip/_internal/models/installation_report.py b/src/pip/_internal/models/installation_report.py index 7f001f35e..31c206751 100644 --- a/src/pip/_internal/models/installation_report.py +++ b/src/pip/_internal/models/installation_report.py @@ -23,6 +23,9 @@ class InstallationReport: # includes editable requirements), and false if the requirement was # downloaded from a PEP 503 index or --find-links. "is_direct": ireq.is_direct, + # is_yanked is true if the requirement was yanked from the index, but + # still was selected by pip conform PEP 592 + "is_yanked": ireq.link.is_yanked if ireq.link else False, # requested is true if the requirement was specified by the user (aka # top level requirement), and false if it was installed as a dependency of a # requirement. https://peps.python.org/pep-0376/#requested diff --git a/tests/functional/test_install_report.py b/tests/functional/test_install_report.py index 003b29d38..a0f855978 100644 --- a/tests/functional/test_install_report.py +++ b/tests/functional/test_install_report.py @@ -64,6 +64,59 @@ def test_install_report_dep( assert _install_dict(report)["simple"]["requested"] is False +def test_yanked_version( + script: PipTestEnvironment, data: TestData, tmp_path: Path +) -> None: + """ + Test is_yanked is True when explicitly requesting a yanked package. + Yanked files are always ignored, unless they are the only file that + matches a version specifier that "pins" to an exact version (PEP 592). + """ + report_path = tmp_path / "report.json" + script.pip( + "install", + "simple==3.0", + "--index-url", + data.index_url("yanked"), + "--dry-run", + "--report", + str(report_path), + allow_stderr_warning=True, + ) + report = json.loads(report_path.read_text()) + simple_report = _install_dict(report)["simple"] + assert simple_report["requested"] is True + assert simple_report["is_direct"] is False + assert simple_report["is_yanked"] is True + assert simple_report["metadata"]["version"] == "3.0" + + +def test_skipped_yanked_version( + script: PipTestEnvironment, data: TestData, tmp_path: Path +) -> None: + """ + Test is_yanked is False when not explicitly requesting a yanked package. + Yanked files are always ignored, unless they are the only file that + matches a version specifier that "pins" to an exact version (PEP 592). + """ + report_path = tmp_path / "report.json" + script.pip( + "install", + "simple", + "--index-url", + data.index_url("yanked"), + "--dry-run", + "--report", + str(report_path), + ) + report = json.loads(report_path.read_text()) + simple_report = _install_dict(report)["simple"] + assert simple_report["requested"] is True + assert simple_report["is_direct"] is False + assert simple_report["is_yanked"] is False + assert simple_report["metadata"]["version"] == "2.0" + + @pytest.mark.network def test_install_report_index(script: PipTestEnvironment, tmp_path: Path) -> None: """Test report for sdist obtained from index.""" From 553690b39ecb405fd3fb1504d82161e71b02da40 Mon Sep 17 00:00:00 2001 From: Tzu-ping Chung Date: Tue, 15 Aug 2023 10:49:49 +0800 Subject: [PATCH 2/4] Period --- src/pip/_internal/models/installation_report.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pip/_internal/models/installation_report.py b/src/pip/_internal/models/installation_report.py index 31c206751..2acc10d1a 100644 --- a/src/pip/_internal/models/installation_report.py +++ b/src/pip/_internal/models/installation_report.py @@ -24,7 +24,7 @@ class InstallationReport: # downloaded from a PEP 503 index or --find-links. "is_direct": ireq.is_direct, # is_yanked is true if the requirement was yanked from the index, but - # still was selected by pip conform PEP 592 + # still was selected by pip conform PEP 592. "is_yanked": ireq.link.is_yanked if ireq.link else False, # requested is true if the requirement was specified by the user (aka # top level requirement), and false if it was installed as a dependency of a From 3c5e2aed045d68ab49cf2e47bda2826659bc91cc Mon Sep 17 00:00:00 2001 From: ddelange <14880945+ddelange@users.noreply.github.com> Date: Tue, 15 Aug 2023 12:06:56 +0200 Subject: [PATCH 3/4] PR Suggestion Co-authored-by: Paul Moore --- src/pip/_internal/models/installation_report.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pip/_internal/models/installation_report.py b/src/pip/_internal/models/installation_report.py index 2acc10d1a..e38e8f1c0 100644 --- a/src/pip/_internal/models/installation_report.py +++ b/src/pip/_internal/models/installation_report.py @@ -24,7 +24,7 @@ class InstallationReport: # downloaded from a PEP 503 index or --find-links. "is_direct": ireq.is_direct, # is_yanked is true if the requirement was yanked from the index, but - # still was selected by pip conform PEP 592. + # was still selected by pip to conform to PEP 592. "is_yanked": ireq.link.is_yanked if ireq.link else False, # requested is true if the requirement was specified by the user (aka # top level requirement), and false if it was installed as a dependency of a From 55205b940d451c517f1e66279a6d5a98dd00d275 Mon Sep 17 00:00:00 2001 From: ddelange <14880945+ddelange@users.noreply.github.com> Date: Fri, 25 Aug 2023 09:43:14 +0200 Subject: [PATCH 4/4] Update installation report docs --- docs/html/reference/installation-report.md | 5 +++++ news/12224.feature.rst | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/html/reference/installation-report.md b/docs/html/reference/installation-report.md index 5823205f9..e0cfcd97e 100644 --- a/docs/html/reference/installation-report.md +++ b/docs/html/reference/installation-report.md @@ -56,6 +56,9 @@ package with the following properties: URL reference. `false` if the requirements was provided as a name and version specifier. +- `is_yanked`: `true` if the requirement was yanked from the index, but was still + selected by pip conform to [PEP 592](https://peps.python.org/pep-0592/#installers). + - `download_info`: Information about the artifact (to be) downloaded for installation, using the [direct URL data 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): } }, "is_direct": false, + "is_yanked": false, "requested": true, "metadata": { "name": "pydantic", @@ -133,6 +137,7 @@ will produce an output similar to this (metadata abriged for brevity): } }, "is_direct": true, + "is_yanked": false, "requested": true, "metadata": { "name": "packaging", diff --git a/news/12224.feature.rst b/news/12224.feature.rst index 5a6977254..d87426578 100644 --- a/news/12224.feature.rst +++ b/news/12224.feature.rst @@ -1 +1 @@ -Add ``is_yanked`` boolean entry to the installation report (``--report``) to indicate whether the requirement was yanked from the index, but still was selected by pip conform PEP 592. +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.