diff --git a/news/7488.bugfix b/news/7488.bugfix new file mode 100644 index 000000000..047a8c1fc --- /dev/null +++ b/news/7488.bugfix @@ -0,0 +1,2 @@ +Effectively disable the wheel cache when it is not writable, as is the +case with the http cache. diff --git a/src/pip/_internal/cli/base_command.py b/src/pip/_internal/cli/base_command.py index 6fbc26c0f..74dcb0b3f 100644 --- a/src/pip/_internal/cli/base_command.py +++ b/src/pip/_internal/cli/base_command.py @@ -31,6 +31,7 @@ from pip._internal.exceptions import ( UninstallationError, ) from pip._internal.utils.deprecation import deprecated +from pip._internal.utils.filesystem import check_path_owner from pip._internal.utils.logging import BrokenStdoutLoggingError, setup_logging from pip._internal.utils.misc import get_prog from pip._internal.utils.temp_dir import global_tempdir_manager @@ -168,6 +169,18 @@ class Command(CommandContextMixIn): ) sys.exit(VIRTUALENV_NOT_FOUND) + if options.cache_dir: + if not check_path_owner(options.cache_dir): + logger.warning( + "The directory '%s' or its parent directory is not owned " + "or is not writable by the current user. The cache " + "has been disabled. Check the permissions and owner of " + "that directory. If executing pip with sudo, you may want " + "sudo's -H flag.", + options.cache_dir, + ) + options.cache_dir = None + try: status = self.run(options, args) # FIXME: all commands should return an exit status diff --git a/src/pip/_internal/commands/download.py b/src/pip/_internal/commands/download.py index 23ee11a5b..24da3eb2a 100644 --- a/src/pip/_internal/commands/download.py +++ b/src/pip/_internal/commands/download.py @@ -11,7 +11,6 @@ from pip._internal.cli.cmdoptions import make_target_python from pip._internal.cli.req_command import RequirementCommand from pip._internal.req import RequirementSet from pip._internal.req.req_tracker import get_requirement_tracker -from pip._internal.utils.filesystem import check_path_owner from pip._internal.utils.misc import ensure_dir, normalize_path, write_output from pip._internal.utils.temp_dir import TempDirectory @@ -99,16 +98,6 @@ class DownloadCommand(RequirementCommand): target_python=target_python, ) build_delete = (not (options.no_clean or options.build_dir)) - if options.cache_dir and not check_path_owner(options.cache_dir): - logger.warning( - "The directory '%s' or its parent directory is not owned " - "by the current user and caching wheels has been " - "disabled. check the permissions and owner of that " - "directory. If executing pip with sudo, you may want " - "sudo's -H flag.", - options.cache_dir, - ) - options.cache_dir = None with get_requirement_tracker() as req_tracker, TempDirectory( options.build_dir, delete=build_delete, kind="download" diff --git a/src/pip/_internal/commands/install.py b/src/pip/_internal/commands/install.py index c7dcf28df..32b814800 100644 --- a/src/pip/_internal/commands/install.py +++ b/src/pip/_internal/commands/install.py @@ -34,7 +34,7 @@ from pip._internal.req import RequirementSet, install_given_reqs from pip._internal.req.req_tracker import get_requirement_tracker from pip._internal.utils.deprecation import deprecated from pip._internal.utils.distutils_args import parse_distutils_args -from pip._internal.utils.filesystem import check_path_owner, test_writable_dir +from pip._internal.utils.filesystem import test_writable_dir from pip._internal.utils.misc import ( ensure_dir, get_installed_version, @@ -330,17 +330,6 @@ class InstallCommand(RequirementCommand): build_delete = (not (options.no_clean or options.build_dir)) wheel_cache = WheelCache(options.cache_dir, options.format_control) - if options.cache_dir and not check_path_owner(options.cache_dir): - logger.warning( - "The directory '%s' or its parent directory is not owned " - "by the current user and caching wheels has been " - "disabled. check the permissions and owner of that " - "directory. If executing pip with sudo, you may want " - "sudo's -H flag.", - options.cache_dir, - ) - options.cache_dir = None - with get_requirement_tracker() as req_tracker, TempDirectory( options.build_dir, delete=build_delete, kind="install" ) as directory: diff --git a/src/pip/_internal/network/session.py b/src/pip/_internal/network/session.py index 2d208cb65..f5eb15ef2 100644 --- a/src/pip/_internal/network/session.py +++ b/src/pip/_internal/network/session.py @@ -27,7 +27,6 @@ from pip._internal.network.auth import MultiDomainBasicAuth from pip._internal.network.cache import SafeFileCache # Import ssl from compat so the initial import occurs in only one place. from pip._internal.utils.compat import has_tls, ipaddress -from pip._internal.utils.filesystem import check_path_owner from pip._internal.utils.glibc import libc_ver from pip._internal.utils.misc import ( build_url_from_netloc, @@ -264,19 +263,6 @@ class PipSession(requests.Session): backoff_factor=0.25, ) - # Check to ensure that the directory containing our cache directory - # is owned by the user current executing pip. If it does not exist - # we will check the parent directory until we find one that does exist. - if cache and not check_path_owner(cache): - logger.warning( - "The directory '%s' or its parent directory is not owned by " - "the current user and the cache has been disabled. Please " - "check the permissions and owner of that directory. If " - "executing pip with sudo, you may want sudo's -H flag.", - cache, - ) - cache = None - # We want to _only_ cache responses on securely fetched origins. We do # this because we can't validate the response of an insecurely fetched # origin, and we don't want someone to be able to poison the cache and diff --git a/tests/functional/test_wheel.py b/tests/functional/test_wheel.py index 7a66a78fd..792f5fe6c 100644 --- a/tests/functional/test_wheel.py +++ b/tests/functional/test_wheel.py @@ -120,6 +120,7 @@ def test_pip_wheel_builds_when_no_binary_set(script, data): assert "Building wheel for simple" in str(res), str(res) +@pytest.mark.skipif("sys.platform == 'win32'") def test_pip_wheel_readonly_cache(script, data, tmpdir): cache_dir = tmpdir / "cache" cache_dir.mkdir() @@ -133,7 +134,7 @@ def test_pip_wheel_readonly_cache(script, data, tmpdir): allow_stderr_warning=True, ) assert res.returncode == 0 - assert "caching wheels has been disabled" in str(res), str(res) + assert "The cache has been disabled." in str(res), str(res) def test_pip_wheel_builds_editable_deps(script, data):