From 8222d788f6f22caa2bdb0b5cb9242ea928bad3b8 Mon Sep 17 00:00:00 2001 From: "Pradyun S. Gedam" Date: Thu, 3 Aug 2017 04:55:21 +0530 Subject: [PATCH] Switch pip uninstall behaviour to be idempotent pip uninstall no longer aborts if a package is not installed; instead it prints a warning that the package is not installed and it is skipping the uninstallation of it for this reason. --- src/pip/_internal/req/req_install.py | 5 ++--- tests/functional/test_uninstall.py | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/pip/_internal/req/req_install.py b/src/pip/_internal/req/req_install.py index 62908f71e..43b85665b 100644 --- a/src/pip/_internal/req/req_install.py +++ b/src/pip/_internal/req/req_install.py @@ -648,9 +648,8 @@ class InstallRequirement(object): """ if not self.check_if_exists(): - raise UninstallationError( - "Cannot uninstall requirement %s, not installed" % (self.name,) - ) + logger.warning("Skipping %s as it is not installed.", self.name) + return dist = self.satisfied_by or self.conflicts_with uninstalled_pathset = UninstallPathSet.from_dist(dist) diff --git a/tests/functional/test_uninstall.py b/tests/functional/test_uninstall.py index 633d3d350..609d28393 100644 --- a/tests/functional/test_uninstall.py +++ b/tests/functional/test_uninstall.py @@ -468,3 +468,25 @@ def test_uninstall_editable_and_pip_install(script, data): ) in uninstall2.files_deleted, list(uninstall2.files_deleted.keys()) list_result2 = script.pip('list', '--format=json') assert "FSPkg" not in {p["name"] for p in json.loads(list_result2.stdout)} + + +def test_uninstall_ignores_missing_packages(script, data): + """Uninstall of a non existent package prints a warning and exits cleanly + """ + result = script.pip( + 'uninstall', '-y', 'non-existent-pkg', expect_stderr=True, + ) + + assert "Skipping non-existent-pkg as it is not installed." in result.stderr + assert result.returncode == 0, "Expected clean exit" + + +def test_uninstall_ignores_missing_packages_and_uninstalls_rest(script, data): + script.pip_install_local('simple') + result = script.pip( + 'uninstall', '-y', 'non-existent-pkg', 'simple', expect_stderr=True, + ) + + assert "Skipping non-existent-pkg as it is not installed." in result.stderr + assert "Successfully uninstalled simple" in result.stdout + assert result.returncode == 0, "Expected clean exit"