summaryrefslogtreecommitdiff
path: root/venv/lib/python3.11/site-packages/pip/_internal/commands/install.py
diff options
context:
space:
mode:
authorcyfraeviolae <cyfraeviolae>2024-04-03 03:17:55 -0400
committercyfraeviolae <cyfraeviolae>2024-04-03 03:17:55 -0400
commit12cf076118570eebbff08c6b3090e0d4798447a1 (patch)
tree3ba25e17e3c3a5e82316558ba3864b955919ff72 /venv/lib/python3.11/site-packages/pip/_internal/commands/install.py
parentc45662ff3923b34614ddcc8feb9195541166dcc5 (diff)
no venv
Diffstat (limited to 'venv/lib/python3.11/site-packages/pip/_internal/commands/install.py')
-rw-r--r--venv/lib/python3.11/site-packages/pip/_internal/commands/install.py774
1 files changed, 0 insertions, 774 deletions
diff --git a/venv/lib/python3.11/site-packages/pip/_internal/commands/install.py b/venv/lib/python3.11/site-packages/pip/_internal/commands/install.py
deleted file mode 100644
index e944bb9..0000000
--- a/venv/lib/python3.11/site-packages/pip/_internal/commands/install.py
+++ /dev/null
@@ -1,774 +0,0 @@
-import errno
-import json
-import operator
-import os
-import shutil
-import site
-from optparse import SUPPRESS_HELP, Values
-from typing import List, Optional
-
-from pip._vendor.rich import print_json
-
-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,
- 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
-from pip._internal.metadata import get_environment
-from pip._internal.models.installation_report import InstallationReport
-from pip._internal.operations.build.build_tracker import get_build_tracker
-from pip._internal.operations.check import ConflictDetails, check_install_conflicts
-from pip._internal.req import install_given_reqs
-from pip._internal.req.req_install import (
- InstallRequirement,
- check_legacy_setup_py_options,
-)
-from pip._internal.utils.compat import WINDOWS
-from pip._internal.utils.filesystem import test_writable_dir
-from pip._internal.utils.logging import getLogger
-from pip._internal.utils.misc import (
- check_externally_managed,
- ensure_dir,
- get_pip_version,
- protect_pip_from_modification_on_windows,
- write_output,
-)
-from pip._internal.utils.temp_dir import TempDirectory
-from pip._internal.utils.virtualenv import (
- running_under_virtualenv,
- virtualenv_no_global,
-)
-from pip._internal.wheel_builder import build, should_build_for_install_command
-
-logger = getLogger(__name__)
-
-
-class InstallCommand(RequirementCommand):
- """
- Install packages from:
-
- - PyPI (and other indexes) using requirement specifiers.
- - VCS project urls.
- - Local project directories.
- - Local or remote source archives.
-
- pip also supports installing from "requirements files", which provide
- an easy way to specify a whole environment to be installed.
- """
-
- usage = """
- %prog [options] <requirement specifier> [package-index-options] ...
- %prog [options] -r <requirements file> [package-index-options] ...
- %prog [options] [-e] <vcs project url> ...
- %prog [options] [-e] <local project path> ...
- %prog [options] <archive url/path> ..."""
-
- def add_options(self) -> None:
- self.cmd_opts.add_option(cmdoptions.requirements())
- self.cmd_opts.add_option(cmdoptions.constraints())
- self.cmd_opts.add_option(cmdoptions.no_deps())
- self.cmd_opts.add_option(cmdoptions.pre())
-
- self.cmd_opts.add_option(cmdoptions.editable())
- self.cmd_opts.add_option(
- "--dry-run",
- action="store_true",
- dest="dry_run",
- default=False,
- help=(
- "Don't actually install anything, just print what would be. "
- "Can be used in combination with --ignore-installed "
- "to 'resolve' the requirements."
- ),
- )
- self.cmd_opts.add_option(
- "-t",
- "--target",
- dest="target_dir",
- metavar="dir",
- default=None,
- help=(
- "Install packages into <dir>. "
- "By default this will not replace existing files/folders in "
- "<dir>. Use --upgrade to replace existing packages in <dir> "
- "with new versions."
- ),
- )
- cmdoptions.add_target_python_options(self.cmd_opts)
-
- self.cmd_opts.add_option(
- "--user",
- dest="use_user_site",
- action="store_true",
- help=(
- "Install to the Python user install directory for your "
- "platform. Typically ~/.local/, or %APPDATA%\\Python on "
- "Windows. (See the Python documentation for site.USER_BASE "
- "for full details.)"
- ),
- )
- self.cmd_opts.add_option(
- "--no-user",
- dest="use_user_site",
- action="store_false",
- help=SUPPRESS_HELP,
- )
- self.cmd_opts.add_option(
- "--root",
- dest="root_path",
- metavar="dir",
- default=None,
- help="Install everything relative to this alternate root directory.",
- )
- self.cmd_opts.add_option(
- "--prefix",
- dest="prefix_path",
- metavar="dir",
- default=None,
- help=(
- "Installation prefix where lib, bin and other top-level "
- "folders are placed. Note that the resulting installation may "
- "contain scripts and other resources which reference the "
- "Python interpreter of pip, and not that of ``--prefix``. "
- "See also the ``--python`` option if the intention is to "
- "install packages into another (possibly pip-free) "
- "environment."
- ),
- )
-
- self.cmd_opts.add_option(cmdoptions.src())
-
- self.cmd_opts.add_option(
- "-U",
- "--upgrade",
- dest="upgrade",
- action="store_true",
- help=(
- "Upgrade all specified packages to the newest available "
- "version. The handling of dependencies depends on the "
- "upgrade-strategy used."
- ),
- )
-
- self.cmd_opts.add_option(
- "--upgrade-strategy",
- dest="upgrade_strategy",
- default="only-if-needed",
- choices=["only-if-needed", "eager"],
- help=(
- "Determines how dependency upgrading should be handled "
- "[default: %default]. "
- '"eager" - dependencies are upgraded regardless of '
- "whether the currently installed version satisfies the "
- "requirements of the upgraded package(s). "
- '"only-if-needed" - are upgraded only when they do not '
- "satisfy the requirements of the upgraded package(s)."
- ),
- )
-
- self.cmd_opts.add_option(
- "--force-reinstall",
- dest="force_reinstall",
- action="store_true",
- help="Reinstall all packages even if they are already up-to-date.",
- )
-
- self.cmd_opts.add_option(
- "-I",
- "--ignore-installed",
- dest="ignore_installed",
- action="store_true",
- help=(
- "Ignore the installed packages, overwriting them. "
- "This can break your system if the existing package "
- "is of a different version or was installed "
- "with a different package manager!"
- ),
- )
-
- self.cmd_opts.add_option(cmdoptions.ignore_requires_python())
- self.cmd_opts.add_option(cmdoptions.no_build_isolation())
- self.cmd_opts.add_option(cmdoptions.use_pep517())
- self.cmd_opts.add_option(cmdoptions.no_use_pep517())
- self.cmd_opts.add_option(cmdoptions.check_build_deps())
- self.cmd_opts.add_option(cmdoptions.override_externally_managed())
-
- self.cmd_opts.add_option(cmdoptions.config_settings())
- self.cmd_opts.add_option(cmdoptions.global_options())
-
- self.cmd_opts.add_option(
- "--compile",
- action="store_true",
- dest="compile",
- default=True,
- help="Compile Python source files to bytecode",
- )
-
- self.cmd_opts.add_option(
- "--no-compile",
- action="store_false",
- dest="compile",
- help="Do not compile Python source files to bytecode",
- )
-
- self.cmd_opts.add_option(
- "--no-warn-script-location",
- action="store_false",
- dest="warn_script_location",
- default=True,
- help="Do not warn when installing scripts outside PATH",
- )
- self.cmd_opts.add_option(
- "--no-warn-conflicts",
- action="store_false",
- dest="warn_about_conflicts",
- default=True,
- help="Do not warn about broken dependencies",
- )
- self.cmd_opts.add_option(cmdoptions.no_binary())
- self.cmd_opts.add_option(cmdoptions.only_binary())
- self.cmd_opts.add_option(cmdoptions.prefer_binary())
- self.cmd_opts.add_option(cmdoptions.require_hashes())
- self.cmd_opts.add_option(cmdoptions.progress_bar())
- self.cmd_opts.add_option(cmdoptions.root_user_action())
-
- index_opts = cmdoptions.make_option_group(
- cmdoptions.index_group,
- self.parser,
- )
-
- self.parser.insert_option_group(0, index_opts)
- self.parser.insert_option_group(0, self.cmd_opts)
-
- self.cmd_opts.add_option(
- "--report",
- dest="json_report_file",
- metavar="file",
- default=None,
- help=(
- "Generate a JSON file describing what pip did to install "
- "the provided requirements. "
- "Can be used in combination with --dry-run and --ignore-installed "
- "to 'resolve' the requirements. "
- "When - is used as file name it writes to stdout. "
- "When writing to stdout, please combine with the --quiet option "
- "to avoid mixing pip logging output with JSON output."
- ),
- )
-
- @with_cleanup
- def run(self, options: Values, args: List[str]) -> int:
- if options.use_user_site and options.target_dir is not None:
- raise CommandError("Can not combine '--user' and '--target'")
-
- # Check whether the environment we're installing into is externally
- # managed, as specified in PEP 668. Specifying --root, --target, or
- # --prefix disables the check, since there's no reliable way to locate
- # the EXTERNALLY-MANAGED file for those cases. An exception is also
- # made specifically for "--dry-run --report" for convenience.
- installing_into_current_environment = (
- not (options.dry_run and options.json_report_file)
- and options.root_path is None
- and options.target_dir is None
- and options.prefix_path is None
- )
- if (
- installing_into_current_environment
- and not options.override_externally_managed
- ):
- check_externally_managed()
-
- upgrade_strategy = "to-satisfy-only"
- if options.upgrade:
- upgrade_strategy = options.upgrade_strategy
-
- cmdoptions.check_dist_restriction(options, check_target=True)
-
- logger.verbose("Using %s", get_pip_version())
- options.use_user_site = decide_user_install(
- options.use_user_site,
- prefix_path=options.prefix_path,
- target_dir=options.target_dir,
- root_path=options.root_path,
- isolated_mode=options.isolated_mode,
- )
-
- target_temp_dir: Optional[TempDirectory] = None
- target_temp_dir_path: Optional[str] = None
- if options.target_dir:
- options.ignore_installed = True
- options.target_dir = os.path.abspath(options.target_dir)
- if (
- # fmt: off
- os.path.exists(options.target_dir) and
- not os.path.isdir(options.target_dir)
- # fmt: on
- ):
- raise CommandError(
- "Target path exists but is not a directory, will not continue."
- )
-
- # Create a target directory for using with the target option
- target_temp_dir = TempDirectory(kind="target")
- target_temp_dir_path = target_temp_dir.path
- self.enter_context(target_temp_dir)
-
- global_options = options.global_options or []
-
- session = self.get_default_session(options)
-
- target_python = make_target_python(options)
- finder = self._build_package_finder(
- options=options,
- session=session,
- target_python=target_python,
- ignore_requires_python=options.ignore_requires_python,
- )
- build_tracker = self.enter_context(get_build_tracker())
-
- directory = TempDirectory(
- delete=not options.no_clean,
- kind="install",
- globally_managed=True,
- )
-
- try:
- reqs = self.get_requirements(args, options, finder, session)
- check_legacy_setup_py_options(options, reqs)
-
- wheel_cache = WheelCache(options.cache_dir)
-
- # Only when installing is it permitted to use PEP 660.
- # In other circumstances (pip wheel, pip download) we generate
- # regular (i.e. non editable) metadata and wheels.
- for req in reqs:
- req.permit_editable_wheels = True
-
- preparer = self.make_requirement_preparer(
- temp_build_dir=directory,
- options=options,
- build_tracker=build_tracker,
- session=session,
- finder=finder,
- use_user_site=options.use_user_site,
- verbosity=self.verbosity,
- )
- resolver = self.make_resolver(
- preparer=preparer,
- finder=finder,
- options=options,
- wheel_cache=wheel_cache,
- use_user_site=options.use_user_site,
- ignore_installed=options.ignore_installed,
- ignore_requires_python=options.ignore_requires_python,
- force_reinstall=options.force_reinstall,
- upgrade_strategy=upgrade_strategy,
- use_pep517=options.use_pep517,
- )
-
- self.trace_basic_info(finder)
-
- requirement_set = resolver.resolve(
- reqs, check_supported_wheels=not options.target_dir
- )
-
- if options.json_report_file:
- report = InstallationReport(requirement_set.requirements_to_install)
- if options.json_report_file == "-":
- print_json(data=report.to_dict())
- else:
- with open(options.json_report_file, "w", encoding="utf-8") as f:
- json.dump(report.to_dict(), f, indent=2, ensure_ascii=False)
-
- if options.dry_run:
- # In non dry-run mode, the legacy versions and specifiers check
- # will be done as part of conflict detection.
- requirement_set.warn_legacy_versions_and_specifiers()
- would_install_items = sorted(
- (r.metadata["name"], r.metadata["version"])
- for r in requirement_set.requirements_to_install
- )
- if would_install_items:
- write_output(
- "Would install %s",
- " ".join("-".join(item) for item in would_install_items),
- )
- return SUCCESS
-
- try:
- pip_req = requirement_set.get_requirement("pip")
- except KeyError:
- modifying_pip = False
- else:
- # If we're not replacing an already installed pip,
- # we're not modifying it.
- modifying_pip = pip_req.satisfied_by is None
- protect_pip_from_modification_on_windows(modifying_pip=modifying_pip)
-
- reqs_to_build = [
- r
- for r in requirement_set.requirements.values()
- if should_build_for_install_command(r)
- ]
-
- _, build_failures = build(
- reqs_to_build,
- wheel_cache=wheel_cache,
- verify=True,
- build_options=[],
- global_options=global_options,
- )
-
- if build_failures:
- raise InstallationError(
- "Could not build wheels for {}, which is required to "
- "install pyproject.toml-based projects".format(
- ", ".join(r.name for r in build_failures) # type: ignore
- )
- )
-
- to_install = resolver.get_installation_order(requirement_set)
-
- # Check for conflicts in the package set we're installing.
- conflicts: Optional[ConflictDetails] = None
- should_warn_about_conflicts = (
- not options.ignore_dependencies and options.warn_about_conflicts
- )
- if should_warn_about_conflicts:
- conflicts = self._determine_conflicts(to_install)
-
- # Don't warn about script install locations if
- # --target or --prefix has been specified
- warn_script_location = options.warn_script_location
- if options.target_dir or options.prefix_path:
- warn_script_location = False
-
- installed = install_given_reqs(
- to_install,
- global_options,
- root=options.root_path,
- home=target_temp_dir_path,
- prefix=options.prefix_path,
- warn_script_location=warn_script_location,
- use_user_site=options.use_user_site,
- pycompile=options.compile,
- )
-
- lib_locations = get_lib_location_guesses(
- user=options.use_user_site,
- home=target_temp_dir_path,
- root=options.root_path,
- prefix=options.prefix_path,
- isolated=options.isolated_mode,
- )
- env = get_environment(lib_locations)
-
- installed.sort(key=operator.attrgetter("name"))
- items = []
- for result in installed:
- item = result.name
- try:
- installed_dist = env.get_distribution(item)
- if installed_dist is not None:
- item = f"{item}-{installed_dist.version}"
- except Exception:
- pass
- items.append(item)
-
- if conflicts is not None:
- self._warn_about_conflicts(
- conflicts,
- resolver_variant=self.determine_resolver_variant(options),
- )
-
- installed_desc = " ".join(items)
- if installed_desc:
- write_output(
- "Successfully installed %s",
- installed_desc,
- )
- except OSError as error:
- show_traceback = self.verbosity >= 1
-
- message = create_os_error_message(
- error,
- show_traceback,
- options.use_user_site,
- )
- logger.error(message, exc_info=show_traceback)
-
- return ERROR
-
- if options.target_dir:
- assert target_temp_dir
- self._handle_target_dir(
- options.target_dir, target_temp_dir, options.upgrade
- )
- if options.root_user_action == "warn":
- warn_if_run_as_root()
- return SUCCESS
-
- def _handle_target_dir(
- self, target_dir: str, target_temp_dir: TempDirectory, upgrade: bool
- ) -> None:
- ensure_dir(target_dir)
-
- # Checking both purelib and platlib directories for installed
- # packages to be moved to target directory
- lib_dir_list = []
-
- # Checking both purelib and platlib directories for installed
- # packages to be moved to target directory
- scheme = get_scheme("", home=target_temp_dir.path)
- purelib_dir = scheme.purelib
- platlib_dir = scheme.platlib
- data_dir = scheme.data
-
- if os.path.exists(purelib_dir):
- lib_dir_list.append(purelib_dir)
- if os.path.exists(platlib_dir) and platlib_dir != purelib_dir:
- lib_dir_list.append(platlib_dir)
- if os.path.exists(data_dir):
- lib_dir_list.append(data_dir)
-
- for lib_dir in lib_dir_list:
- for item in os.listdir(lib_dir):
- if lib_dir == data_dir:
- ddir = os.path.join(data_dir, item)
- if any(s.startswith(ddir) for s in lib_dir_list[:-1]):
- continue
- target_item_dir = os.path.join(target_dir, item)
- if os.path.exists(target_item_dir):
- if not upgrade:
- logger.warning(
- "Target directory %s already exists. Specify "
- "--upgrade to force replacement.",
- target_item_dir,
- )
- continue
- if os.path.islink(target_item_dir):
- logger.warning(
- "Target directory %s already exists and is "
- "a link. pip will not automatically replace "
- "links, please remove if replacement is "
- "desired.",
- target_item_dir,
- )
- continue
- if os.path.isdir(target_item_dir):
- shutil.rmtree(target_item_dir)
- else:
- os.remove(target_item_dir)
-
- shutil.move(os.path.join(lib_dir, item), target_item_dir)
-
- def _determine_conflicts(
- self, to_install: List[InstallRequirement]
- ) -> Optional[ConflictDetails]:
- try:
- return check_install_conflicts(to_install)
- except Exception:
- logger.exception(
- "Error while checking for conflicts. Please file an issue on "
- "pip's issue tracker: https://github.com/pypa/pip/issues/new"
- )
- return None
-
- def _warn_about_conflicts(
- self, conflict_details: ConflictDetails, resolver_variant: str
- ) -> None:
- package_set, (missing, conflicting) = conflict_details
- if not missing and not conflicting:
- return
-
- parts: List[str] = []
- if resolver_variant == "legacy":
- parts.append(
- "pip's legacy dependency resolver does not consider dependency "
- "conflicts when selecting packages. This behaviour is the "
- "source of the following dependency conflicts."
- )
- else:
- assert resolver_variant == "resolvelib"
- parts.append(
- "pip's dependency resolver does not currently take into account "
- "all the packages that are installed. This behaviour is the "
- "source of the following dependency conflicts."
- )
-
- # NOTE: There is some duplication here, with commands/check.py
- for project_name in missing:
- version = package_set[project_name][0]
- for dependency in missing[project_name]:
- message = (
- f"{project_name} {version} requires {dependency[1]}, "
- "which is not installed."
- )
- parts.append(message)
-
- for project_name in conflicting:
- version = package_set[project_name][0]
- for dep_name, dep_version, req in conflicting[project_name]:
- message = (
- "{name} {version} requires {requirement}, but {you} have "
- "{dep_name} {dep_version} which is incompatible."
- ).format(
- name=project_name,
- version=version,
- requirement=req,
- dep_name=dep_name,
- dep_version=dep_version,
- you=("you" if resolver_variant == "resolvelib" else "you'll"),
- )
- parts.append(message)
-
- logger.critical("\n".join(parts))
-
-
-def get_lib_location_guesses(
- user: bool = False,
- home: Optional[str] = None,
- root: Optional[str] = None,
- isolated: bool = False,
- prefix: Optional[str] = None,
-) -> List[str]:
- scheme = get_scheme(
- "",
- user=user,
- home=home,
- root=root,
- isolated=isolated,
- prefix=prefix,
- )
- return [scheme.purelib, scheme.platlib]
-
-
-def site_packages_writable(root: Optional[str], isolated: bool) -> bool:
- return all(
- test_writable_dir(d)
- for d in set(get_lib_location_guesses(root=root, isolated=isolated))
- )
-
-
-def decide_user_install(
- use_user_site: Optional[bool],
- prefix_path: Optional[str] = None,
- target_dir: Optional[str] = None,
- root_path: Optional[str] = None,
- isolated_mode: bool = False,
-) -> bool:
- """Determine whether to do a user install based on the input options.
-
- If use_user_site is False, no additional checks are done.
- If use_user_site is True, it is checked for compatibility with other
- options.
- If use_user_site is None, the default behaviour depends on the environment,
- which is provided by the other arguments.
- """
- # In some cases (config from tox), use_user_site can be set to an integer
- # rather than a bool, which 'use_user_site is False' wouldn't catch.
- if (use_user_site is not None) and (not use_user_site):
- logger.debug("Non-user install by explicit request")
- return False
-
- if use_user_site:
- if prefix_path:
- raise CommandError(
- "Can not combine '--user' and '--prefix' as they imply "
- "different installation locations"
- )
- if virtualenv_no_global():
- raise InstallationError(
- "Can not perform a '--user' install. User site-packages "
- "are not visible in this virtualenv."
- )
- logger.debug("User install by explicit request")
- return True
-
- # If we are here, user installs have not been explicitly requested/avoided
- assert use_user_site is None
-
- # user install incompatible with --prefix/--target
- if prefix_path or target_dir:
- logger.debug("Non-user install due to --prefix or --target option")
- return False
-
- # If user installs are not enabled, choose a non-user install
- if not site.ENABLE_USER_SITE:
- logger.debug("Non-user install because user site-packages disabled")
- return False
-
- # If we have permission for a non-user install, do that,
- # otherwise do a user install.
- if site_packages_writable(root=root_path, isolated=isolated_mode):
- logger.debug("Non-user install because site-packages writeable")
- return False
-
- logger.info(
- "Defaulting to user installation because normal site-packages "
- "is not writeable"
- )
- return True
-
-
-def create_os_error_message(
- error: OSError, show_traceback: bool, using_user_site: bool
-) -> str:
- """Format an error message for an OSError
-
- It may occur anytime during the execution of the install command.
- """
- parts = []
-
- # Mention the error if we are not going to show a traceback
- parts.append("Could not install packages due to an OSError")
- if not show_traceback:
- parts.append(": ")
- parts.append(str(error))
- else:
- parts.append(".")
-
- # Spilt the error indication from a helper message (if any)
- parts[-1] += "\n"
-
- # Suggest useful actions to the user:
- # (1) using user site-packages or (2) verifying the permissions
- if error.errno == errno.EACCES:
- user_option_part = "Consider using the `--user` option"
- permissions_part = "Check the permissions"
-
- if not running_under_virtualenv() and not using_user_site:
- parts.extend(
- [
- user_option_part,
- " or ",
- permissions_part.lower(),
- ]
- )
- else:
- parts.append(permissions_part)
- parts.append(".\n")
-
- # Suggest the user to enable Long Paths if path length is
- # more than 260
- if (
- WINDOWS
- and error.errno == errno.ENOENT
- and error.filename
- and len(error.filename) > 260
- ):
- parts.append(
- "HINT: This error might have occurred since "
- "this system does not have Windows Long Path "
- "support enabled. You can find information on "
- "how to enable this at "
- "https://pip.pypa.io/warnings/enable-long-paths\n"
- )
-
- return "".join(parts).strip() + "\n"