From 239a30737277887fed9f609ae786a0fb80591be4 Mon Sep 17 00:00:00 2001 From: Guy Tuval Date: Sat, 24 Jul 2021 16:24:30 +0300 Subject: [PATCH] Error handling upon `uninstall` invalid parameter (#10171) Co-authored-by: Tzu-ping Chung --- news/4958.feature.rst | 1 + src/pip/_internal/commands/uninstall.py | 10 ++++++++++ tests/functional/test_uninstall.py | 12 ++++++++++++ 3 files changed, 23 insertions(+) create mode 100644 news/4958.feature.rst diff --git a/news/4958.feature.rst b/news/4958.feature.rst new file mode 100644 index 000000000..fbceb5cde --- /dev/null +++ b/news/4958.feature.rst @@ -0,0 +1 @@ +Add a warning when passing an invalid requirement to ``pip uninstall``. diff --git a/src/pip/_internal/commands/uninstall.py b/src/pip/_internal/commands/uninstall.py index dc22b5d1d..c590627ea 100644 --- a/src/pip/_internal/commands/uninstall.py +++ b/src/pip/_internal/commands/uninstall.py @@ -1,3 +1,4 @@ +import logging from optparse import Values from typing import List @@ -14,6 +15,8 @@ from pip._internal.req.constructors import ( ) from pip._internal.utils.misc import protect_pip_from_modification_on_windows +logger = logging.getLogger(__name__) + class UninstallCommand(Command, SessionCommandMixin): """ @@ -58,6 +61,13 @@ class UninstallCommand(Command, SessionCommandMixin): ) if req.name: reqs_to_uninstall[canonicalize_name(req.name)] = req + else: + logger.warning( + "Invalid requirement: %r ignored -" + " the uninstall command expects named" + " requirements.", + name, + ) for filename in options.requirements: for parsed_req in parse_requirements( filename, diff --git a/tests/functional/test_uninstall.py b/tests/functional/test_uninstall.py index e6e32dad9..4fea1e2f9 100644 --- a/tests/functional/test_uninstall.py +++ b/tests/functional/test_uninstall.py @@ -76,6 +76,18 @@ def test_basic_uninstall_with_scripts(script): ) +@pytest.mark.parametrize("name", + ["GTrolls.tar.gz", + "https://guyto.com/archives/"]) +def test_uninstall_invalid_parameter(script, caplog, name): + result = script.pip("uninstall", name, "-y", expect_error=True) + expected_message = ( + f"Invalid requirement: '{name}' ignored -" + f" the uninstall command expects named requirements." + ) + assert expected_message in result.stderr + + @pytest.mark.network def test_uninstall_easy_install_after_import(script): """