| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 | 
							- """Contains the Command base classes that depend on PipSession.
 
- The classes in this module are in a separate module so the commands not
 
- needing download / PackageFinder capability don't unnecessarily import the
 
- PackageFinder machinery and all its vendored dependencies, etc.
 
- """
 
- import logging
 
- import os
 
- from functools import partial
 
- from pip._internal.cli import cmdoptions
 
- from pip._internal.cli.base_command import Command
 
- from pip._internal.cli.command_context import CommandContextMixIn
 
- from pip._internal.exceptions import CommandError, PreviousBuildDirError
 
- from pip._internal.index.package_finder import PackageFinder
 
- from pip._internal.models.selection_prefs import SelectionPreferences
 
- from pip._internal.network.download import Downloader
 
- from pip._internal.network.session import PipSession
 
- from pip._internal.operations.prepare import RequirementPreparer
 
- from pip._internal.req.constructors import (
 
-     install_req_from_editable,
 
-     install_req_from_line,
 
-     install_req_from_parsed_requirement,
 
-     install_req_from_req_string,
 
- )
 
- from pip._internal.req.req_file import parse_requirements
 
- from pip._internal.req.req_set import RequirementSet
 
- from pip._internal.self_outdated_check import (
 
-     make_link_collector,
 
-     pip_self_version_check,
 
- )
 
- from pip._internal.utils.temp_dir import tempdir_kinds
 
- from pip._internal.utils.typing import MYPY_CHECK_RUNNING
 
- if MYPY_CHECK_RUNNING:
 
-     from optparse import Values
 
-     from typing import Any, List, Optional, Tuple
 
-     from pip._internal.cache import WheelCache
 
-     from pip._internal.models.target_python import TargetPython
 
-     from pip._internal.req.req_install import InstallRequirement
 
-     from pip._internal.req.req_tracker import RequirementTracker
 
-     from pip._internal.resolution.base import BaseResolver
 
-     from pip._internal.utils.temp_dir import (
 
-         TempDirectory,
 
-         TempDirectoryTypeRegistry,
 
-     )
 
- logger = logging.getLogger(__name__)
 
- class SessionCommandMixin(CommandContextMixIn):
 
-     """
 
-     A class mixin for command classes needing _build_session().
 
-     """
 
-     def __init__(self):
 
-         # type: () -> None
 
-         super(SessionCommandMixin, self).__init__()
 
-         self._session = None  # Optional[PipSession]
 
-     @classmethod
 
-     def _get_index_urls(cls, options):
 
-         # type: (Values) -> Optional[List[str]]
 
-         """Return a list of index urls from user-provided options."""
 
-         index_urls = []
 
-         if not getattr(options, "no_index", False):
 
-             url = getattr(options, "index_url", None)
 
-             if url:
 
-                 index_urls.append(url)
 
-         urls = getattr(options, "extra_index_urls", None)
 
-         if urls:
 
-             index_urls.extend(urls)
 
-         # Return None rather than an empty list
 
-         return index_urls or None
 
-     def get_default_session(self, options):
 
-         # type: (Values) -> PipSession
 
-         """Get a default-managed session."""
 
-         if self._session is None:
 
-             self._session = self.enter_context(self._build_session(options))
 
-             # there's no type annotation on requests.Session, so it's
 
-             # automatically ContextManager[Any] and self._session becomes Any,
 
-             # then https://github.com/python/mypy/issues/7696 kicks in
 
-             assert self._session is not None
 
-         return self._session
 
-     def _build_session(self, options, retries=None, timeout=None):
 
-         # type: (Values, Optional[int], Optional[int]) -> PipSession
 
-         assert not options.cache_dir or os.path.isabs(options.cache_dir)
 
-         session = PipSession(
 
-             cache=(
 
-                 os.path.join(options.cache_dir, "http")
 
-                 if options.cache_dir else None
 
-             ),
 
-             retries=retries if retries is not None else options.retries,
 
-             trusted_hosts=options.trusted_hosts,
 
-             index_urls=self._get_index_urls(options),
 
-         )
 
-         # Handle custom ca-bundles from the user
 
-         if options.cert:
 
-             session.verify = options.cert
 
-         # Handle SSL client certificate
 
-         if options.client_cert:
 
-             session.cert = options.client_cert
 
-         # Handle timeouts
 
-         if options.timeout or timeout:
 
-             session.timeout = (
 
-                 timeout if timeout is not None else options.timeout
 
-             )
 
-         # Handle configured proxies
 
-         if options.proxy:
 
-             session.proxies = {
 
-                 "http": options.proxy,
 
-                 "https": options.proxy,
 
-             }
 
-         # Determine if we can prompt the user for authentication or not
 
-         session.auth.prompting = not options.no_input
 
-         return session
 
- class IndexGroupCommand(Command, SessionCommandMixin):
 
-     """
 
-     Abstract base class for commands with the index_group options.
 
-     This also corresponds to the commands that permit the pip version check.
 
-     """
 
-     def handle_pip_version_check(self, options):
 
-         # type: (Values) -> None
 
-         """
 
-         Do the pip version check if not disabled.
 
-         This overrides the default behavior of not doing the check.
 
-         """
 
-         # Make sure the index_group options are present.
 
-         assert hasattr(options, 'no_index')
 
-         if options.disable_pip_version_check or options.no_index:
 
-             return
 
-         # Otherwise, check if we're using the latest version of pip available.
 
-         session = self._build_session(
 
-             options,
 
-             retries=0,
 
-             timeout=min(5, options.timeout)
 
-         )
 
-         with session:
 
-             pip_self_version_check(session, options)
 
- KEEPABLE_TEMPDIR_TYPES = [
 
-     tempdir_kinds.BUILD_ENV,
 
-     tempdir_kinds.EPHEM_WHEEL_CACHE,
 
-     tempdir_kinds.REQ_BUILD,
 
- ]
 
- def with_cleanup(func):
 
-     # type: (Any) -> Any
 
-     """Decorator for common logic related to managing temporary
 
-     directories.
 
-     """
 
-     def configure_tempdir_registry(registry):
 
-         # type: (TempDirectoryTypeRegistry) -> None
 
-         for t in KEEPABLE_TEMPDIR_TYPES:
 
-             registry.set_delete(t, False)
 
-     def wrapper(self, options, args):
 
-         # type: (RequirementCommand, Values, List[Any]) -> Optional[int]
 
-         assert self.tempdir_registry is not None
 
-         if options.no_clean:
 
-             configure_tempdir_registry(self.tempdir_registry)
 
-         try:
 
-             return func(self, options, args)
 
-         except PreviousBuildDirError:
 
-             # This kind of conflict can occur when the user passes an explicit
 
-             # build directory with a pre-existing folder. In that case we do
 
-             # not want to accidentally remove it.
 
-             configure_tempdir_registry(self.tempdir_registry)
 
-             raise
 
-     return wrapper
 
- class RequirementCommand(IndexGroupCommand):
 
-     def __init__(self, *args, **kw):
 
-         # type: (Any, Any) -> None
 
-         super(RequirementCommand, self).__init__(*args, **kw)
 
-         self.cmd_opts.add_option(cmdoptions.no_clean())
 
-     @staticmethod
 
-     def make_requirement_preparer(
 
-         temp_build_dir,           # type: TempDirectory
 
-         options,                  # type: Values
 
-         req_tracker,              # type: RequirementTracker
 
-         session,                  # type: PipSession
 
-         finder,                   # type: PackageFinder
 
-         use_user_site,            # type: bool
 
-         download_dir=None,        # type: str
 
-         wheel_download_dir=None,  # type: str
 
-     ):
 
-         # type: (...) -> RequirementPreparer
 
-         """
 
-         Create a RequirementPreparer instance for the given parameters.
 
-         """
 
-         downloader = Downloader(session, progress_bar=options.progress_bar)
 
-         temp_build_dir_path = temp_build_dir.path
 
-         assert temp_build_dir_path is not None
 
-         return RequirementPreparer(
 
-             build_dir=temp_build_dir_path,
 
-             src_dir=options.src_dir,
 
-             download_dir=download_dir,
 
-             wheel_download_dir=wheel_download_dir,
 
-             build_isolation=options.build_isolation,
 
-             req_tracker=req_tracker,
 
-             downloader=downloader,
 
-             finder=finder,
 
-             require_hashes=options.require_hashes,
 
-             use_user_site=use_user_site,
 
-         )
 
-     @staticmethod
 
-     def make_resolver(
 
-         preparer,                            # type: RequirementPreparer
 
-         finder,                              # type: PackageFinder
 
-         options,                             # type: Values
 
-         wheel_cache=None,                    # type: Optional[WheelCache]
 
-         use_user_site=False,                 # type: bool
 
-         ignore_installed=True,               # type: bool
 
-         ignore_requires_python=False,        # type: bool
 
-         force_reinstall=False,               # type: bool
 
-         upgrade_strategy="to-satisfy-only",  # type: str
 
-         use_pep517=None,                     # type: Optional[bool]
 
-         py_version_info=None            # type: Optional[Tuple[int, ...]]
 
-     ):
 
-         # type: (...) -> BaseResolver
 
-         """
 
-         Create a Resolver instance for the given parameters.
 
-         """
 
-         make_install_req = partial(
 
-             install_req_from_req_string,
 
-             isolated=options.isolated_mode,
 
-             use_pep517=use_pep517,
 
-         )
 
-         # The long import name and duplicated invocation is needed to convince
 
-         # Mypy into correctly typechecking. Otherwise it would complain the
 
-         # "Resolver" class being redefined.
 
-         if 'resolver' in options.unstable_features:
 
-             import pip._internal.resolution.resolvelib.resolver
 
-             return pip._internal.resolution.resolvelib.resolver.Resolver(
 
-                 preparer=preparer,
 
-                 finder=finder,
 
-                 wheel_cache=wheel_cache,
 
-                 make_install_req=make_install_req,
 
-                 use_user_site=use_user_site,
 
-                 ignore_dependencies=options.ignore_dependencies,
 
-                 ignore_installed=ignore_installed,
 
-                 ignore_requires_python=ignore_requires_python,
 
-                 force_reinstall=force_reinstall,
 
-                 upgrade_strategy=upgrade_strategy,
 
-                 py_version_info=py_version_info,
 
-             )
 
-         import pip._internal.resolution.legacy.resolver
 
-         return pip._internal.resolution.legacy.resolver.Resolver(
 
-             preparer=preparer,
 
-             finder=finder,
 
-             wheel_cache=wheel_cache,
 
-             make_install_req=make_install_req,
 
-             use_user_site=use_user_site,
 
-             ignore_dependencies=options.ignore_dependencies,
 
-             ignore_installed=ignore_installed,
 
-             ignore_requires_python=ignore_requires_python,
 
-             force_reinstall=force_reinstall,
 
-             upgrade_strategy=upgrade_strategy,
 
-             py_version_info=py_version_info,
 
-         )
 
-     def get_requirements(
 
-         self,
 
-         args,             # type: List[str]
 
-         options,          # type: Values
 
-         finder,           # type: PackageFinder
 
-         session,          # type: PipSession
 
-         check_supported_wheels=True,  # type: bool
 
-     ):
 
-         # type: (...) -> List[InstallRequirement]
 
-         """
 
-         Parse command-line arguments into the corresponding requirements.
 
-         """
 
-         requirement_set = RequirementSet(
 
-             check_supported_wheels=check_supported_wheels
 
-         )
 
-         for filename in options.constraints:
 
-             for parsed_req in parse_requirements(
 
-                     filename,
 
-                     constraint=True, finder=finder, options=options,
 
-                     session=session):
 
-                 req_to_add = install_req_from_parsed_requirement(
 
-                     parsed_req,
 
-                     isolated=options.isolated_mode,
 
-                 )
 
-                 req_to_add.is_direct = True
 
-                 requirement_set.add_requirement(req_to_add)
 
-         for req in args:
 
-             req_to_add = install_req_from_line(
 
-                 req, None, isolated=options.isolated_mode,
 
-                 use_pep517=options.use_pep517,
 
-             )
 
-             req_to_add.is_direct = True
 
-             requirement_set.add_requirement(req_to_add)
 
-         for req in options.editables:
 
-             req_to_add = install_req_from_editable(
 
-                 req,
 
-                 isolated=options.isolated_mode,
 
-                 use_pep517=options.use_pep517,
 
-             )
 
-             req_to_add.is_direct = True
 
-             requirement_set.add_requirement(req_to_add)
 
-         # NOTE: options.require_hashes may be set if --require-hashes is True
 
-         for filename in options.requirements:
 
-             for parsed_req in parse_requirements(
 
-                     filename,
 
-                     finder=finder, options=options, session=session):
 
-                 req_to_add = install_req_from_parsed_requirement(
 
-                     parsed_req,
 
-                     isolated=options.isolated_mode,
 
-                     use_pep517=options.use_pep517
 
-                 )
 
-                 req_to_add.is_direct = True
 
-                 requirement_set.add_requirement(req_to_add)
 
-         # If any requirement has hash options, enable hash checking.
 
-         requirements = requirement_set.all_requirements
 
-         if any(req.has_hash_options for req in requirements):
 
-             options.require_hashes = True
 
-         if not (args or options.editables or options.requirements):
 
-             opts = {'name': self.name}
 
-             if options.find_links:
 
-                 raise CommandError(
 
-                     'You must give at least one requirement to {name} '
 
-                     '(maybe you meant "pip {name} {links}"?)'.format(
 
-                         **dict(opts, links=' '.join(options.find_links))))
 
-             else:
 
-                 raise CommandError(
 
-                     'You must give at least one requirement to {name} '
 
-                     '(see "pip help {name}")'.format(**opts))
 
-         return requirements
 
-     @staticmethod
 
-     def trace_basic_info(finder):
 
-         # type: (PackageFinder) -> None
 
-         """
 
-         Trace basic information about the provided objects.
 
-         """
 
-         # Display where finder is looking for packages
 
-         search_scope = finder.search_scope
 
-         locations = search_scope.get_formatted_locations()
 
-         if locations:
 
-             logger.info(locations)
 
-     def _build_package_finder(
 
-         self,
 
-         options,               # type: Values
 
-         session,               # type: PipSession
 
-         target_python=None,    # type: Optional[TargetPython]
 
-         ignore_requires_python=None,  # type: Optional[bool]
 
-     ):
 
-         # type: (...) -> PackageFinder
 
-         """
 
-         Create a package finder appropriate to this requirement command.
 
-         :param ignore_requires_python: Whether to ignore incompatible
 
-             "Requires-Python" values in links. Defaults to False.
 
-         """
 
-         link_collector = make_link_collector(session, options=options)
 
-         selection_prefs = SelectionPreferences(
 
-             allow_yanked=True,
 
-             format_control=options.format_control,
 
-             allow_all_prereleases=options.pre,
 
-             prefer_binary=options.prefer_binary,
 
-             ignore_requires_python=ignore_requires_python,
 
-         )
 
-         return PackageFinder.create(
 
-             link_collector=link_collector,
 
-             selection_prefs=selection_prefs,
 
-             target_python=target_python,
 
-         )
 
 
  |