From bf63604c9b55b119b2a9083a3a5e1d54f44b48df Mon Sep 17 00:00:00 2001 From: ddelange <14880945+ddelange@users.noreply.github.com> Date: Wed, 23 Aug 2023 12:37:58 +0200 Subject: [PATCH] Filter out yanked links from available versions error message --- news/12225.bugfix.rst | 1 + .../resolution/resolvelib/factory.py | 15 ++++++++++- tests/functional/test_install.py | 27 +++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 news/12225.bugfix.rst diff --git a/news/12225.bugfix.rst b/news/12225.bugfix.rst new file mode 100644 index 00000000000..e1e0c323dc3 --- /dev/null +++ b/news/12225.bugfix.rst @@ -0,0 +1 @@ +Filter out yanked links from the available versions error message: "(from versions: 1.0, 2.0, 3.0)" will not contain yanked versions conform PEP 592. The yanked versions (if any) will be mentioned in a separate error message. diff --git a/src/pip/_internal/resolution/resolvelib/factory.py b/src/pip/_internal/resolution/resolvelib/factory.py index ed78580ab97..fbcd16a06f0 100644 --- a/src/pip/_internal/resolution/resolvelib/factory.py +++ b/src/pip/_internal/resolution/resolvelib/factory.py @@ -603,8 +603,21 @@ def _report_single_requirement_conflict( cands = self._finder.find_all_candidates(req.project_name) skipped_by_requires_python = self._finder.requires_python_skipped_reasons() - versions = [str(v) for v in sorted({c.version for c in cands})] + is_yanked: Dict[bool, Set[CandidateVersion]] = {True: set(), False: set()} + for c in cands: + is_yanked[c.link.is_yanked if c.link else False].add(c.version) + + versions = sorted(is_yanked[False]) + yanked_versions = sorted(is_yanked[True]) + + if yanked_versions: + # TODO saying "version X is yanked" isn't entirely accurate + # https://github.com/pypa/pip/issues/11745#issuecomment-1402805842 + logger.critical( + "Ignored the following yanked versions: %s", + ", ".join(yanked_versions) or "none", + ) if skipped_by_requires_python: logger.critical( "Ignored the following versions that require a different python " diff --git a/tests/functional/test_install.py b/tests/functional/test_install.py index 5e8a82fb345..161881419d6 100644 --- a/tests/functional/test_install.py +++ b/tests/functional/test_install.py @@ -2242,6 +2242,33 @@ def test_install_yanked_file_and_print_warning( assert "Successfully installed simple-3.0\n" in result.stdout, str(result) +def test_yanked_version_missing_from_availble_versions_error_message( + script: PipTestEnvironment, data: TestData +) -> None: + """ + Test yanked version is missing from available versions error message. + + Yanked files are always ignored, unless they are the only file that + matches a version specifier that "pins" to an exact version (PEP 592). + """ + result = script.pip( + "install", + "simple==", + "--index-url", + data.index_url("yanked"), + expect_error=True, + ) + # the yanked version (3.0) is filtered out from the output: + expected_warning = ( + "Could not find a version that satisfies the requirement simple== " + "(from versions: 1.0, 2.0)" + ) + assert expected_warning in result.stderr, str(result) + # and mentioned in a separate warning: + expected_warning = "Ignored the following yanked versions: 3.0" + assert expected_warning in result.stderr, str(result) + + def test_error_all_yanked_files_and_no_pin( script: PipTestEnvironment, data: TestData ) -> None: