diff --git a/news/10459.feature.rst b/news/10459.feature.rst new file mode 100644 index 00000000000..bc4e74f8527 --- /dev/null +++ b/news/10459.feature.rst @@ -0,0 +1,2 @@ +Do not raise error when there are no files to remove with ``pip cache purge/remove``. +Instead log a warning and continue (to log that we removed 0 files). diff --git a/src/pip/_internal/commands/cache.py b/src/pip/_internal/commands/cache.py index c3b6c767444..f1a489d324f 100644 --- a/src/pip/_internal/commands/cache.py +++ b/src/pip/_internal/commands/cache.py @@ -170,12 +170,16 @@ def remove_cache_items(self, options: Values, args: List[Any]) -> None: files = self._find_wheels(options, args[0]) - # Only fetch http files if no specific pattern given + no_matching_msg = "No matching packages" if args[0] == "*": + # Only fetch http files if no specific pattern given files += self._find_http_files(options) + else: + # Add the pattern to the log message + no_matching_msg += ' for pattern "{}"'.format(args[0]) if not files: - raise CommandError("No matching packages") + logger.warning(no_matching_msg) for filename in files: os.unlink(filename) diff --git a/tests/functional/test_cache.py b/tests/functional/test_cache.py index ba3283fddb0..ef3f2e4c849 100644 --- a/tests/functional/test_cache.py +++ b/tests/functional/test_cache.py @@ -244,6 +244,24 @@ def test_cache_list_with_empty_cache_abspath(script): assert result.stdout.strip() == "" +@pytest.mark.usefixtures("empty_wheel_cache") +def test_cache_purge_with_empty_cache(script): + """Running `pip cache purge` with an empty cache should print a warning + and exit without an error code.""" + result = script.pip("cache", "purge", allow_stderr_warning=True) + assert result.stderr == "WARNING: No matching packages\n" + assert result.stdout == "Files removed: 0\n" + + +@pytest.mark.usefixtures("populate_wheel_cache") +def test_cache_remove_with_bad_pattern(script): + """Running `pip cache remove` with a bad pattern should print a warning + and exit without an error code.""" + result = script.pip("cache", "remove", "aaa", allow_stderr_warning=True) + assert result.stderr == 'WARNING: No matching packages for pattern "aaa"\n' + assert result.stdout == "Files removed: 0\n" + + def test_cache_list_too_many_args(script): """Passing `pip cache list` too many arguments should cause an error.""" script.pip("cache", "list", "aaa", "bbb", expect_error=True)