Add a warning when run as root (e.g., sudo pip) (#9394)

This commit is contained in:
Winson Luk 2021-03-06 07:59:39 -05:00 committed by GitHub
parent 3ab760aaa1
commit c6933d5c5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 42 additions and 4 deletions

1
news/6409.bugfix.rst Normal file
View File

@ -0,0 +1 @@
Add a warning, discouraging the usage of pip as root, outside a virtual environment.

View File

@ -149,8 +149,8 @@ class Command(CommandContextMixIn):
"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.",
"that directory. If executing pip with sudo, you should "
"use sudo's -H flag.",
options.cache_dir,
)
options.cache_dir = None

View File

@ -7,6 +7,7 @@ PackageFinder machinery and all its vendored dependencies, etc.
import logging
import os
import sys
from functools import partial
from optparse import Values
from typing import Any, List, Optional, Tuple
@ -38,6 +39,7 @@ from pip._internal.utils.temp_dir import (
TempDirectoryTypeRegistry,
tempdir_kinds,
)
from pip._internal.utils.virtualenv import running_under_virtualenv
logger = logging.getLogger(__name__)
@ -152,6 +154,35 @@ KEEPABLE_TEMPDIR_TYPES = [
]
def warn_if_run_as_root():
# type: () -> None
"""Output a warning for sudo users on Unix.
In a virtual environment, sudo pip still writes to virtualenv.
On Windows, users may run pip as Administrator without issues.
This warning only applies to Unix root users outside of virtualenv.
"""
if running_under_virtualenv():
return
if not hasattr(os, "getuid"):
return
# On Windows, there are no "system managed" Python packages. Installing as
# Administrator via pip is the correct way of updating system environments.
#
# We choose sys.platform over utils.compat.WINDOWS here to enable Mypy platform
# checks: https://mypy.readthedocs.io/en/stable/common_issues.html
if sys.platform == "win32" or sys.platform == "cygwin":
return
if sys.platform == "darwin" or sys.platform == "linux":
if os.getuid() != 0:
return
logger.warning(
"Running pip as root will break packages and permissions. "
"You should install packages reliably by using venv: "
"https://pip.pypa.io/warnings/venv"
)
def with_cleanup(func):
# type: (Any) -> Any
"""Decorator for common logic related to managing temporary

View File

@ -12,7 +12,11 @@ from pip._vendor.packaging.utils import canonicalize_name
from pip._internal.cache import WheelCache
from pip._internal.cli import cmdoptions
from pip._internal.cli.cmdoptions import make_target_python
from pip._internal.cli.req_command import RequirementCommand, with_cleanup
from pip._internal.cli.req_command import (
RequirementCommand,
warn_if_run_as_root,
with_cleanup,
)
from pip._internal.cli.status_codes import ERROR, SUCCESS
from pip._internal.exceptions import CommandError, InstallationError
from pip._internal.locations import get_scheme
@ -443,6 +447,7 @@ class InstallCommand(RequirementCommand):
options.target_dir, target_temp_dir, options.upgrade
)
warn_if_run_as_root()
return SUCCESS
def _handle_target_dir(self, target_dir, target_temp_dir, upgrade):

View File

@ -4,7 +4,7 @@ from typing import List
from pip._vendor.packaging.utils import canonicalize_name
from pip._internal.cli.base_command import Command
from pip._internal.cli.req_command import SessionCommandMixin
from pip._internal.cli.req_command import SessionCommandMixin, warn_if_run_as_root
from pip._internal.cli.status_codes import SUCCESS
from pip._internal.exceptions import InstallationError
from pip._internal.req import parse_requirements
@ -88,4 +88,5 @@ class UninstallCommand(Command, SessionCommandMixin):
if uninstall_pathset:
uninstall_pathset.commit()
warn_if_run_as_root()
return SUCCESS