Пример #1
0
    def save(self, pypi_version, current_time):
        # type: (str, datetime.datetime) -> None
        # If we do not have a path to cache in, don't bother saving.
        if not self.statefile_path:
            return

        # Check to make sure that we own the directory
        if not check_path_owner(os.path.dirname(self.statefile_path)):
            return

        # Now that we've ensured the directory is owned by this user, we'll go
        # ahead and make sure that all our directories are created.
        ensure_dir(os.path.dirname(self.statefile_path))

        # Attempt to write out our version check file
        with lockfile.LockFile(self.statefile_path):
            if os.path.exists(self.statefile_path):
                with open(self.statefile_path) as statefile:
                    state = json.load(statefile)
            else:
                state = {}

            state[sys.prefix] = {
                "last_check": current_time.strftime(SELFCHECK_DATE_FMT),
                "pypi_version": pypi_version,
            }

            with open(self.statefile_path, "w") as statefile:
                json.dump(state, statefile, sort_keys=True,
                          separators=(",", ":"))
Пример #2
0
    def save(self, pypi_version, current_time):
        # type: (str, datetime.datetime) -> None
        # If we do not have a path to cache in, don't bother saving.
        if not self.statefile_path:
            return

        # Check to make sure that we own the directory
        if not check_path_owner(os.path.dirname(self.statefile_path)):
            return

        # Now that we've ensured the directory is owned by this user, we'll go
        # ahead and make sure that all our directories are created.
        ensure_dir(os.path.dirname(self.statefile_path))

        state = {
            # Include the key so it's easy to tell which pip wrote the
            # file.
            "key": self.key,
            "last_check": current_time.strftime(SELFCHECK_DATE_FMT),
            "pypi_version": pypi_version,
        }

        text = json.dumps(state, sort_keys=True, separators=(",", ":"))

        # Attempt to write out our version check file
        with lockfile.LockFile(self.statefile_path):
            # Since we have a prefix-specific state file, we can just
            # overwrite whatever is there, no need to check.
            with open(self.statefile_path, "w") as statefile:
                statefile.write(text)
Пример #3
0
    def save(self, pypi_version, current_time):
        # type: (str, datetime.datetime) -> None
        # If we do not have a path to cache in, don't bother saving.
        if not self.statefile_path:
            return

        # Check to make sure that we own the directory
        if not check_path_owner(os.path.dirname(self.statefile_path)):
            return

        # Now that we've ensured the directory is owned by this user, we'll go
        # ahead and make sure that all our directories are created.
        ensure_dir(os.path.dirname(self.statefile_path))

        # Attempt to write out our version check file
        with lockfile.LockFile(self.statefile_path):
            if os.path.exists(self.statefile_path):
                with open(self.statefile_path) as statefile:
                    state = json.load(statefile)
            else:
                state = {}

            state[sys.prefix] = {
                "last_check": current_time.strftime(SELFCHECK_DATE_FMT),
                "pypi_version": pypi_version,
            }

            with open(self.statefile_path, "w") as statefile:
                json.dump(state,
                          statefile,
                          sort_keys=True,
                          separators=(",", ":"))
    def save(self, pypi_version, current_time):
        # type: (str, datetime.datetime) -> None
        # If we do not have a path to cache in, don't bother saving.
        if not self.statefile_path:
            return

        # Check to make sure that we own the directory
        if not check_path_owner(os.path.dirname(self.statefile_path)):
            return

        # Now that we've ensured the directory is owned by this user, we'll go
        # ahead and make sure that all our directories are created.
        ensure_dir(os.path.dirname(self.statefile_path))

        state = {
            # Include the key so it's easy to tell which pip wrote the
            # file.
            "key": self.key,
            "last_check": current_time.strftime(SELFCHECK_DATE_FMT),
            "pypi_version": pypi_version,
        }

        text = json.dumps(state, sort_keys=True, separators=(",", ":"))

        with adjacent_tmp_file(self.statefile_path) as f:
            f.write(ensure_binary(text))

        try:
            # Since we have a prefix-specific state file, we can just
            # overwrite whatever is there, no need to check.
            replace(f.name, self.statefile_path)
        except OSError:
            # Best effort.
            pass
Пример #5
0
    def __init__(self, *args, **kwargs):
        super(SafeFileCache, self).__init__(*args, **kwargs)

        # 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 it is not owned by the user executing pip then we will disable
        # the cache and log a warning.
        if not check_path_owner(self.directory):
            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.",
                self.directory,
            )

            # Set our directory to None to disable the Cache
            self.directory = None
Пример #6
0
    def __init__(self, *args, **kwargs):
        super(SafeFileCache, self).__init__(*args, **kwargs)

        # 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 it is not owned by the user executing pip then we will disable
        # the cache and log a warning.
        if not check_path_owner(self.directory):
            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.",
                self.directory,
            )

            # Set our directory to None to disable the Cache
            self.directory = None
Пример #7
0
    def run(self, options, args):
        cmdoptions.check_install_build_global(options)

        upgrade_strategy = "to-satisfy-only"
        if options.upgrade:
            upgrade_strategy = options.upgrade_strategy

        if options.build_dir:
            options.build_dir = os.path.abspath(options.build_dir)

        options.src_dir = os.path.abspath(options.src_dir)
        install_options = options.install_options or []
        if options.use_user_site:
            if options.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.")
            install_options.append('--user')
            install_options.append('--prefix=')

        target_temp_dir = TempDirectory(kind="target")
        if options.target_dir:
            options.ignore_installed = True
            options.target_dir = os.path.abspath(options.target_dir)
            if (os.path.exists(options.target_dir)
                    and not os.path.isdir(options.target_dir)):
                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.create()
            install_options.append('--home=' + target_temp_dir.path)

        global_options = options.global_options or []

        with self._build_session(options) as session:
            finder = self._build_package_finder(options, session)
            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 TempDirectory(options.build_dir,
                               delete=build_delete,
                               kind="install") as directory:
                requirement_set = RequirementSet(
                    require_hashes=options.require_hashes, )

                try:
                    self.populate_requirement_set(requirement_set, args,
                                                  options, finder, session,
                                                  self.name, wheel_cache)
                    preparer = RequirementPreparer(
                        build_dir=directory.path,
                        src_dir=options.src_dir,
                        download_dir=None,
                        wheel_download_dir=None,
                        progress_bar=options.progress_bar,
                        build_isolation=options.build_isolation,
                    )

                    resolver = Resolver(
                        preparer=preparer,
                        finder=finder,
                        session=session,
                        wheel_cache=wheel_cache,
                        use_user_site=options.use_user_site,
                        upgrade_strategy=upgrade_strategy,
                        force_reinstall=options.force_reinstall,
                        ignore_dependencies=options.ignore_dependencies,
                        ignore_requires_python=options.ignore_requires_python,
                        ignore_installed=options.ignore_installed,
                        isolated=options.isolated_mode,
                    )
                    resolver.resolve(requirement_set)

                    # If caching is disabled or wheel is not installed don't
                    # try to build wheels.
                    if wheel and options.cache_dir:
                        # build wheels before install.
                        wb = WheelBuilder(
                            finder,
                            preparer,
                            wheel_cache,
                            build_options=[],
                            global_options=[],
                        )
                        # Ignore the result: a failed wheel will be
                        # installed from the sdist/vcs whatever.
                        wb.build(requirement_set.requirements.values(),
                                 session=session,
                                 autobuilding=True)

                    to_install = resolver.get_installation_order(
                        requirement_set)

                    # Consistency Checking of the package set we're installing.
                    should_warn_about_conflicts = (
                        not options.ignore_dependencies
                        and options.warn_about_conflicts)
                    if should_warn_about_conflicts:
                        self._warn_about_conflicts(to_install)

                    # Don't warn about script install locations if
                    # --target has been specified
                    warn_script_location = options.warn_script_location
                    if options.target_dir:
                        warn_script_location = False

                    installed = install_given_reqs(
                        to_install,
                        install_options,
                        global_options,
                        root=options.root_path,
                        home=target_temp_dir.path,
                        prefix=options.prefix_path,
                        pycompile=options.compile,
                        warn_script_location=warn_script_location,
                        use_user_site=options.use_user_site,
                    )

                    possible_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,
                    )
                    reqs = sorted(installed, key=operator.attrgetter('name'))
                    items = []
                    for req in reqs:
                        item = req.name
                        try:
                            installed_version = get_installed_version(
                                req.name, possible_lib_locations)
                            if installed_version:
                                item += '-' + installed_version
                        except Exception:
                            pass
                        items.append(item)
                    installed = ' '.join(items)
                    if installed:
                        logger.info('Successfully installed %s', installed)
                except EnvironmentError as e:
                    message_parts = []

                    user_option_part = "Consider using the `--user` option"
                    permissions_part = "Check the permissions"

                    if e.errno == errno.EPERM:
                        if not options.use_user_site:
                            message_parts.extend([
                                user_option_part,
                                " or ",
                                permissions_part.lower(),
                            ])
                        else:
                            message_parts.append(permissions_part)
                        message_parts.append("\n")

                    logger.error("".join(message_parts),
                                 exc_info=(self.verbosity > 1))
                    return ERROR
                except PreviousBuildDirError:
                    options.no_clean = True
                    raise
                finally:
                    # Clean up
                    if not options.no_clean:
                        requirement_set.cleanup_files()
                        wheel_cache.cleanup()

        if options.target_dir:
            self._handle_target_dir(options.target_dir, target_temp_dir,
                                    options.upgrade)
        return requirement_set
Пример #8
0
    def _main(self, args):
        # type: (List[str]) -> int
        # We must initialize this before the tempdir manager, otherwise the
        # configuration would not be accessible by the time we clean up the
        # tempdir manager.
        self.tempdir_registry = self.enter_context(tempdir_registry())
        # Intentionally set as early as possible so globally-managed temporary
        # directories are available to the rest of the code.
        self.enter_context(global_tempdir_manager())

        options, args = self.parse_args(args)

        # Set verbosity so that it can be used elsewhere.
        self.verbosity = options.verbose - options.quiet

        level_number = setup_logging(
            verbosity=self.verbosity,
            no_color=options.no_color,
            user_log_file=options.log,
        )

        # TODO: Try to get these passing down from the command?
        #       without resorting to os.environ to hold these.
        #       This also affects isolated builds and it should.

        if options.no_input:
            os.environ['PIP_NO_INPUT'] = '1'

        if options.exists_action:
            os.environ['PIP_EXISTS_ACTION'] = ' '.join(options.exists_action)

        if options.require_venv and not self.ignore_require_venv:
            # If a venv is required check if it can really be found
            if not running_under_virtualenv():
                logger.critical(
                    'Could not find an activated virtualenv (required).'
                )
                sys.exit(VIRTUALENV_NOT_FOUND)

        if options.cache_dir:
            options.cache_dir = normalize_path(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

        if getattr(options, "build_dir", None):
            deprecated(
                reason=(
                    "The -b/--build/--build-dir/--build-directory "
                    "option is deprecated and has no effect anymore."
                ),
                replacement=(
                    "use the TMPDIR/TEMP/TMP environment variable, "
                    "possibly combined with --no-clean"
                ),
                gone_in="21.1",
                issue=8333,
            )

        if '2020-resolver' in options.features_enabled:
            logger.warning(
                "--use-feature=2020-resolver no longer has any effect, "
                "since it is now the default dependency resolver in pip. "
                "This will become an error in pip 21.0."
            )

        try:
            status = self.run(options, args)
            assert isinstance(status, int)
            return status
        except PreviousBuildDirError as exc:
            logger.critical(str(exc))
            logger.debug('Exception information:', exc_info=True)

            return PREVIOUS_BUILD_DIR_ERROR
        except (InstallationError, UninstallationError, BadCommand,
                NetworkConnectionError) as exc:
            logger.critical(str(exc))
            logger.debug('Exception information:', exc_info=True)

            return ERROR
        except CommandError as exc:
            logger.critical('%s', exc)
            logger.debug('Exception information:', exc_info=True)

            return ERROR
        except BrokenStdoutLoggingError:
            # Bypass our logger and write any remaining messages to stderr
            # because stdout no longer works.
            print('ERROR: Pipe to stdout was broken', file=sys.stderr)
            if level_number <= logging.DEBUG:
                traceback.print_exc(file=sys.stderr)

            return ERROR
        except KeyboardInterrupt:
            logger.critical('Operation cancelled by user')
            logger.debug('Exception information:', exc_info=True)

            return ERROR
        except BaseException:
            logger.critical('Exception:', exc_info=True)

            return UNKNOWN_ERROR
        finally:
            self.handle_pip_version_check(options)
Пример #9
0
    def run(self, options, args):
        # type: (Values, List[Any]) -> int
        cmdoptions.check_install_build_global(options)
        upgrade_strategy = "to-satisfy-only"
        if options.upgrade:
            upgrade_strategy = options.upgrade_strategy

        if options.build_dir:
            options.build_dir = os.path.abspath(options.build_dir)

        cmdoptions.check_dist_restriction(options, check_target=True)

        options.src_dir = os.path.abspath(options.src_dir)
        install_options = options.install_options or []
        if options.use_user_site:
            if options.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.")
            install_options.append('--user')
            install_options.append('--prefix=')

        target_temp_dir = None  # type: Optional[TempDirectory]
        target_temp_dir_path = None  # type: Optional[str]
        if options.target_dir:
            options.ignore_installed = True
            options.target_dir = os.path.abspath(options.target_dir)
            if (os.path.exists(options.target_dir)
                    and not os.path.isdir(options.target_dir)):
                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
            install_options.append('--home=' + target_temp_dir_path)

        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_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 RequirementTracker() as req_tracker, TempDirectory(
                options.build_dir, delete=build_delete,
                kind="install") as directory:
            requirement_set = RequirementSet(
                require_hashes=options.require_hashes,
                check_supported_wheels=not options.target_dir,
            )

            try:
                self.populate_requirement_set(requirement_set, args, options,
                                              finder, session, wheel_cache)
                preparer = self.make_requirement_preparer(
                    temp_build_dir=directory,
                    options=options,
                    req_tracker=req_tracker,
                )
                resolver = self.make_resolver(
                    preparer=preparer,
                    finder=finder,
                    session=session,
                    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,
                )
                resolver.resolve(requirement_set)

                try:
                    pip_req = requirement_set.get_requirement("pip")
                except KeyError:
                    modifying_pip = None
                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)

                check_binary_allowed = get_check_binary_allowed(
                    finder.format_control)
                # Consider legacy and PEP517-using requirements separately
                legacy_requirements = []
                pep517_requirements = []
                for req in requirement_set.requirements.values():
                    if req.use_pep517:
                        pep517_requirements.append(req)
                    else:
                        legacy_requirements.append(req)

                wheel_builder = WheelBuilder(
                    preparer,
                    wheel_cache,
                    build_options=[],
                    global_options=[],
                    check_binary_allowed=check_binary_allowed,
                )

                build_failures = build_wheels(
                    builder=wheel_builder,
                    pep517_requirements=pep517_requirements,
                    legacy_requirements=legacy_requirements,
                )

                # If we're using PEP 517, we cannot do a direct install
                # so we fail here.
                if build_failures:
                    raise InstallationError(
                        "Could not build wheels for {} which use"
                        " PEP 517 and cannot be installed directly".format(
                            ", ".join(r.name for r in build_failures)))

                to_install = resolver.get_installation_order(requirement_set)

                # Consistency Checking of the package set we're installing.
                should_warn_about_conflicts = (not options.ignore_dependencies
                                               and
                                               options.warn_about_conflicts)
                if should_warn_about_conflicts:
                    self._warn_about_conflicts(to_install)

                # Don't warn about script install locations if
                # --target has been specified
                warn_script_location = options.warn_script_location
                if options.target_dir:
                    warn_script_location = False

                installed = install_given_reqs(
                    to_install,
                    install_options,
                    global_options,
                    root=options.root_path,
                    home=target_temp_dir_path,
                    prefix=options.prefix_path,
                    pycompile=options.compile,
                    warn_script_location=warn_script_location,
                    use_user_site=options.use_user_site,
                )

                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,
                )
                working_set = pkg_resources.WorkingSet(lib_locations)

                reqs = sorted(installed, key=operator.attrgetter('name'))
                items = []
                for req in reqs:
                    item = req.name
                    try:
                        installed_version = get_installed_version(
                            req.name, working_set=working_set)
                        if installed_version:
                            item += '-' + installed_version
                    except Exception:
                        pass
                    items.append(item)
                installed_desc = ' '.join(items)
                if installed_desc:
                    write_output(
                        'Successfully installed %s',
                        installed_desc,
                    )
            except EnvironmentError as error:
                show_traceback = (self.verbosity >= 1)

                message = create_env_error_message(
                    error,
                    show_traceback,
                    options.use_user_site,
                )
                logger.error(message, exc_info=show_traceback)

                return ERROR
            except PreviousBuildDirError:
                options.no_clean = True
                raise
            finally:
                # Clean up
                if not options.no_clean:
                    requirement_set.cleanup_files()
                    wheel_cache.cleanup()

        if options.target_dir:
            self._handle_target_dir(options.target_dir, target_temp_dir,
                                    options.upgrade)

        return SUCCESS
Пример #10
0
    def __init__(self, *args, **kwargs):
        """
        :param trusted_hosts: Domains not to emit warnings for when not using
            HTTPS.
        """
        retries = kwargs.pop("retries", 0)
        cache = kwargs.pop("cache", None)
        trusted_hosts = kwargs.pop("trusted_hosts", [])  # type: List[str]
        index_urls = kwargs.pop("index_urls", None)

        super(PipSession, self).__init__(*args, **kwargs)

        # Namespace the attribute with "pip_" just in case to prevent
        # possible conflicts with the base class.
        self.pip_trusted_origins = []  # type: List[Tuple[str, Optional[int]]]

        # Attach our User Agent to the request
        self.headers["User-Agent"] = user_agent()

        # Attach our Authentication handler to the session
        self.auth = MultiDomainBasicAuth(index_urls=index_urls)

        # Create our urllib3.Retry instance which will allow us to customize
        # how we handle retries.
        retries = urllib3.Retry(
            # Set the total number of retries that a particular request can
            # have.
            total=retries,

            # A 503 error from PyPI typically means that the Fastly -> Origin
            # connection got interrupted in some way. A 503 error in general
            # is typically considered a transient error so we'll go ahead and
            # retry it.
            # A 500 may indicate transient error in Amazon S3
            # A 520 or 527 - may indicate transient error in CloudFlare
            status_forcelist=[500, 503, 520, 527],

            # Add a small amount of back off between failed requests in
            # order to prevent hammering the service.
            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
        # require manual eviction from the cache to fix it.
        if cache:
            secure_adapter = CacheControlAdapter(
                cache=SafeFileCache(cache, use_dir_lock=True),
                max_retries=retries,
            )
        else:
            secure_adapter = HTTPAdapter(max_retries=retries)

        # Our Insecure HTTPAdapter disables HTTPS validation. It does not
        # support caching (see above) so we'll use it for all http:// URLs as
        # well as any https:// host that we've marked as ignoring TLS errors
        # for.
        insecure_adapter = InsecureHTTPAdapter(max_retries=retries)
        # Save this for later use in add_insecure_host().
        self._insecure_adapter = insecure_adapter

        self.mount("https://", secure_adapter)
        self.mount("http://", insecure_adapter)

        # Enable file:// urls
        self.mount("file://", LocalFSAdapter())

        for host in trusted_hosts:
            self.add_trusted_host(host, suppress_logging=True)
Пример #11
0
    def _main(self, args: List[str]) -> int:
        # We must initialize this before the tempdir manager, otherwise the
        # configuration would not be accessible by the time we clean up the
        # tempdir manager.
        self.tempdir_registry = self.enter_context(tempdir_registry())
        # Intentionally set as early as possible so globally-managed temporary
        # directories are available to the rest of the code.
        self.enter_context(global_tempdir_manager())

        options, args = self.parse_args(args)

        # Set verbosity so that it can be used elsewhere.
        self.verbosity = options.verbose - options.quiet

        level_number = setup_logging(
            verbosity=self.verbosity,
            no_color=options.no_color,
            user_log_file=options.log,
        )

        # TODO: Try to get these passing down from the command?
        #       without resorting to os.environ to hold these.
        #       This also affects isolated builds and it should.

        if options.no_input:
            os.environ["PIP_NO_INPUT"] = "1"

        if options.exists_action:
            os.environ["PIP_EXISTS_ACTION"] = " ".join(options.exists_action)

        if options.require_venv and not self.ignore_require_venv:
            # If a venv is required check if it can really be found
            if not running_under_virtualenv():
                logger.critical(
                    "Could not find an activated virtualenv (required).")
                sys.exit(VIRTUALENV_NOT_FOUND)

        if options.cache_dir:
            options.cache_dir = normalize_path(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 should "
                    "use sudo's -H flag.",
                    options.cache_dir,
                )
                options.cache_dir = None

        if "2020-resolver" in options.features_enabled:
            logger.warning(
                "--use-feature=2020-resolver no longer has any effect, "
                "since it is now the default dependency resolver in pip. "
                "This will become an error in pip 21.0.")

        def intercepts_unhandled_exc(
                run_func: Callable[..., int]) -> Callable[..., int]:
            @functools.wraps(run_func)
            def exc_logging_wrapper(*args: Any) -> int:
                try:
                    status = run_func(*args)
                    assert isinstance(status, int)
                    return status
                except PreviousBuildDirError as exc:
                    logger.critical(str(exc))
                    logger.debug("Exception information:", exc_info=True)

                    return PREVIOUS_BUILD_DIR_ERROR
                except DiagnosticPipError as exc:
                    logger.critical(str(exc))
                    logger.debug("Exception information:", exc_info=True)

                    return ERROR
                except (
                        InstallationError,
                        UninstallationError,
                        BadCommand,
                        NetworkConnectionError,
                ) as exc:
                    logger.critical(str(exc))
                    logger.debug("Exception information:", exc_info=True)

                    return ERROR
                except CommandError as exc:
                    logger.critical("%s", exc)
                    logger.debug("Exception information:", exc_info=True)

                    return ERROR
                except BrokenStdoutLoggingError:
                    # Bypass our logger and write any remaining messages to
                    # stderr because stdout no longer works.
                    print("ERROR: Pipe to stdout was broken", file=sys.stderr)
                    if level_number <= logging.DEBUG:
                        traceback.print_exc(file=sys.stderr)

                    return ERROR
                except KeyboardInterrupt:
                    logger.critical("Operation cancelled by user")
                    logger.debug("Exception information:", exc_info=True)

                    return ERROR
                except BaseException:
                    logger.critical("Exception:", exc_info=True)

                    return UNKNOWN_ERROR

            return exc_logging_wrapper

        try:
            if not options.debug_mode:
                run = intercepts_unhandled_exc(self.run)
            else:
                run = self.run
            return run(options, args)
        finally:
            self.handle_pip_version_check(options)
Пример #12
0
    def _main(self, args):
        # type: (List[str]) -> int
        # Intentionally set as early as possible so globally-managed temporary
        # directories are available to the rest of the code.
        self.enter_context(global_tempdir_manager())

        options, args = self.parse_args(args)

        # Set verbosity so that it can be used elsewhere.
        self.verbosity = options.verbose - options.quiet

        level_number = setup_logging(
            verbosity=self.verbosity,
            no_color=options.no_color,
            user_log_file=options.log,
        )

        if (
            sys.version_info[:2] == (2, 7) and
            not options.no_python_version_warning
        ):
            message = (
                "A future version of pip will drop support for Python 2.7. "
                "More details about Python 2 support in pip, can be found at "
                "https://pip.pypa.io/en/latest/development/release-process/#python-2-support"  # noqa
            )
            if platform.python_implementation() == "CPython":
                message = (
                    "Python 2.7 reached the end of its life on January "
                    "1st, 2020. Please upgrade your Python as Python 2.7 "
                    "is no longer maintained. "
                ) + message
            deprecated(message, replacement=None, gone_in=None)

        if options.skip_requirements_regex:
            deprecated(
                "--skip-requirements-regex is unsupported and will be removed",
                replacement=(
                    "manage requirements/constraints files explicitly, "
                    "possibly generating them from metadata"
                ),
                gone_in="20.1",
                issue=7297,
            )

        # TODO: Try to get these passing down from the command?
        #       without resorting to os.environ to hold these.
        #       This also affects isolated builds and it should.

        if options.no_input:
            os.environ['PIP_NO_INPUT'] = '1'

        if options.exists_action:
            os.environ['PIP_EXISTS_ACTION'] = ' '.join(options.exists_action)

        if options.require_venv and not self.ignore_require_venv:
            # If a venv is required check if it can really be found
            if not running_under_virtualenv():
                logger.critical(
                    'Could not find an activated virtualenv (required).'
                )
                sys.exit(VIRTUALENV_NOT_FOUND)

        if options.cache_dir:
            options.cache_dir = normalize_path(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)
Пример #13
0
    def run(self, options, args):
        options.ignore_installed = True
        # editable doesn't really make sense for `pip download`, but the bowels
        # of the RequirementSet code require that property.
        options.editables = []

        cmdoptions.check_dist_restriction(options)

        options.src_dir = os.path.abspath(options.src_dir)
        options.download_dir = normalize_path(options.download_dir)

        ensure_dir(options.download_dir)

        with self._build_session(options) as session:
            finder = self._build_package_finder(
                options=options,
                session=session,
                platform=options.platform,
                py_version_info=options.python_version,
                abi=options.abi,
                implementation=options.implementation,
            )
            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 RequirementTracker() as req_tracker, TempDirectory(
                    options.build_dir, delete=build_delete,
                    kind="download") as directory:

                requirement_set = RequirementSet(
                    require_hashes=options.require_hashes, )
                self.populate_requirement_set(requirement_set, args, options,
                                              finder, session, self.name, None)

                preparer = RequirementPreparer(
                    build_dir=directory.path,
                    src_dir=options.src_dir,
                    download_dir=options.download_dir,
                    wheel_download_dir=None,
                    progress_bar=options.progress_bar,
                    build_isolation=options.build_isolation,
                    req_tracker=req_tracker,
                )

                resolver = Resolver(
                    preparer=preparer,
                    finder=finder,
                    session=session,
                    wheel_cache=None,
                    use_user_site=False,
                    upgrade_strategy="to-satisfy-only",
                    force_reinstall=False,
                    ignore_dependencies=options.ignore_dependencies,
                    ignore_requires_python=False,
                    ignore_installed=True,
                    isolated=options.isolated_mode,
                )
                resolver.resolve(requirement_set)

                downloaded = ' '.join([
                    req.name for req in requirement_set.successfully_downloaded
                ])
                if downloaded:
                    logger.info('Successfully downloaded %s', downloaded)

                # Clean up
                if not options.no_clean:
                    requirement_set.cleanup_files()

        return requirement_set
Пример #14
0
    def run(self, options, args):
        cmdoptions.check_install_build_global(options)

        upgrade_strategy = "to-satisfy-only"
        if options.upgrade:
            upgrade_strategy = options.upgrade_strategy

        if options.build_dir:
            options.build_dir = os.path.abspath(options.build_dir)

        options.src_dir = os.path.abspath(options.src_dir)
        install_options = options.install_options or []
        if options.use_user_site:
            if options.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."
                )
            install_options.append('--user')
            install_options.append('--prefix=')

        target_temp_dir = TempDirectory(kind="target")
        if options.target_dir:
            options.ignore_installed = True
            options.target_dir = os.path.abspath(options.target_dir)
            if (os.path.exists(options.target_dir) and not
                    os.path.isdir(options.target_dir)):
                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.create()
            install_options.append('--home=' + target_temp_dir.path)

        global_options = options.global_options or []

        with self._build_session(options) as session:
            finder = self._build_package_finder(options, session)
            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 TempDirectory(
                options.build_dir, delete=build_delete, kind="install"
            ) as directory:
                requirement_set = RequirementSet(
                    require_hashes=options.require_hashes,
                )

                try:
                    self.populate_requirement_set(
                        requirement_set, args, options, finder, session,
                        self.name, wheel_cache
                    )
                    preparer = RequirementPreparer(
                        build_dir=directory.path,
                        src_dir=options.src_dir,
                        download_dir=None,
                        wheel_download_dir=None,
                        progress_bar=options.progress_bar,
                        build_isolation=options.build_isolation,
                    )

                    resolver = Resolver(
                        preparer=preparer,
                        finder=finder,
                        session=session,
                        wheel_cache=wheel_cache,
                        use_user_site=options.use_user_site,
                        upgrade_strategy=upgrade_strategy,
                        force_reinstall=options.force_reinstall,
                        ignore_dependencies=options.ignore_dependencies,
                        ignore_requires_python=options.ignore_requires_python,
                        ignore_installed=options.ignore_installed,
                        isolated=options.isolated_mode,
                    )
                    resolver.resolve(requirement_set)

                    protect_pip_from_modification_on_windows(
                        modifying_pip=requirement_set.has_requirement("pip")
                    )

                    # If caching is disabled or wheel is not installed don't
                    # try to build wheels.
                    if wheel and options.cache_dir:
                        # build wheels before install.
                        wb = WheelBuilder(
                            finder, preparer, wheel_cache,
                            build_options=[], global_options=[],
                        )
                        # Ignore the result: a failed wheel will be
                        # installed from the sdist/vcs whatever.
                        wb.build(
                            requirement_set.requirements.values(),
                            session=session, autobuilding=True
                        )

                    to_install = resolver.get_installation_order(
                        requirement_set
                    )

                    # Consistency Checking of the package set we're installing.
                    should_warn_about_conflicts = (
                        not options.ignore_dependencies and
                        options.warn_about_conflicts
                    )
                    if should_warn_about_conflicts:
                        self._warn_about_conflicts(to_install)

                    # Don't warn about script install locations if
                    # --target has been specified
                    warn_script_location = options.warn_script_location
                    if options.target_dir:
                        warn_script_location = False

                    installed = install_given_reqs(
                        to_install,
                        install_options,
                        global_options,
                        root=options.root_path,
                        home=target_temp_dir.path,
                        prefix=options.prefix_path,
                        pycompile=options.compile,
                        warn_script_location=warn_script_location,
                        use_user_site=options.use_user_site,
                    )

                    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,
                    )
                    working_set = pkg_resources.WorkingSet(lib_locations)

                    reqs = sorted(installed, key=operator.attrgetter('name'))
                    items = []
                    for req in reqs:
                        item = req.name
                        try:
                            installed_version = get_installed_version(
                                req.name, working_set=working_set
                            )
                            if installed_version:
                                item += '-' + installed_version
                        except Exception:
                            pass
                        items.append(item)
                    installed = ' '.join(items)
                    if installed:
                        logger.info('Successfully installed %s', installed)
                except EnvironmentError as error:
                    show_traceback = (self.verbosity >= 1)

                    message = create_env_error_message(
                        error, show_traceback, options.use_user_site,
                    )
                    logger.error(message, exc_info=show_traceback)

                    return ERROR
                except PreviousBuildDirError:
                    options.no_clean = True
                    raise
                finally:
                    # Clean up
                    if not options.no_clean:
                        requirement_set.cleanup_files()
                        wheel_cache.cleanup()

        if options.target_dir:
            self._handle_target_dir(
                options.target_dir, target_temp_dir, options.upgrade
            )
        return requirement_set
Пример #15
0
    def run(self, options, args):
        options.ignore_installed = True
        # editable doesn't really make sense for `pip download`, but the bowels
        # of the RequirementSet code require that property.
        options.editables = []

        if options.python_version:
            python_versions = [options.python_version]
        else:
            python_versions = None

        dist_restriction_set = any([
            options.python_version,
            options.platform,
            options.abi,
            options.implementation,
        ])
        binary_only = FormatControl(set(), {':all:'})
        no_sdist_dependencies = (
            options.format_control != binary_only and
            not options.ignore_dependencies
        )
        if dist_restriction_set and no_sdist_dependencies:
            raise CommandError(
                "When restricting platform and interpreter constraints using "
                "--python-version, --platform, --abi, or --implementation, "
                "either --no-deps must be set, or --only-binary=:all: must be "
                "set and --no-binary must not be set (or must be set to "
                ":none:)."
            )

        options.src_dir = os.path.abspath(options.src_dir)
        options.download_dir = normalize_path(options.download_dir)

        ensure_dir(options.download_dir)

        with self._build_session(options) as session:
            finder = self._build_package_finder(
                options=options,
                session=session,
                platform=options.platform,
                python_versions=python_versions,
                abi=options.abi,
                implementation=options.implementation,
            )
            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 RequirementTracker() as req_tracker, TempDirectory(
                options.build_dir, delete=build_delete, kind="download"
            ) as directory:

                requirement_set = RequirementSet(
                    require_hashes=options.require_hashes,
                )
                self.populate_requirement_set(
                    requirement_set,
                    args,
                    options,
                    finder,
                    session,
                    self.name,
                    None
                )

                preparer = RequirementPreparer(
                    build_dir=directory.path,
                    src_dir=options.src_dir,
                    download_dir=options.download_dir,
                    wheel_download_dir=None,
                    progress_bar=options.progress_bar,
                    build_isolation=options.build_isolation,
                    req_tracker=req_tracker,
                )

                resolver = Resolver(
                    preparer=preparer,
                    finder=finder,
                    session=session,
                    wheel_cache=None,
                    use_user_site=False,
                    upgrade_strategy="to-satisfy-only",
                    force_reinstall=False,
                    ignore_dependencies=options.ignore_dependencies,
                    ignore_requires_python=False,
                    ignore_installed=True,
                    isolated=options.isolated_mode,
                )
                resolver.resolve(requirement_set)

                downloaded = ' '.join([
                    req.name for req in requirement_set.successfully_downloaded
                ])
                if downloaded:
                    logger.info('Successfully downloaded %s', downloaded)

                # Clean up
                if not options.no_clean:
                    requirement_set.cleanup_files()

        return requirement_set
Пример #16
0
    def run(self, options, args):
        cmdoptions.check_install_build_global(options)
        upgrade_strategy = "to-satisfy-only"
        if options.upgrade:
            upgrade_strategy = options.upgrade_strategy

        if options.build_dir:
            options.build_dir = os.path.abspath(options.build_dir)

        cmdoptions.check_dist_restriction(options, check_target=True)

        if options.python_version:
            python_versions = [options.python_version]
        else:
            python_versions = None

        options.src_dir = os.path.abspath(options.src_dir)
        install_options = options.install_options or []
        if options.use_user_site:
            if options.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."
                )
            install_options.append('--user')
            install_options.append('--prefix=')

        target_temp_dir = TempDirectory(kind="target")
        if options.target_dir:
            options.ignore_installed = True
            options.target_dir = os.path.abspath(options.target_dir)
            if (os.path.exists(options.target_dir) and not
                    os.path.isdir(options.target_dir)):
                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.create()
            install_options.append('--home=' + target_temp_dir.path)

        global_options = options.global_options or []

        with self._build_session(options) as session:
            finder = self._build_package_finder(
                options=options,
                session=session,
                platform=options.platform,
                python_versions=python_versions,
                abi=options.abi,
                implementation=options.implementation,
            )
            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 RequirementTracker() as req_tracker, TempDirectory(
                options.build_dir, delete=build_delete, kind="install"
            ) as directory:
                requirement_set = RequirementSet(
                    require_hashes=options.require_hashes,
                    check_supported_wheels=not options.target_dir,
                )

                try:
                    self.populate_requirement_set(
                        requirement_set, args, options, finder, session,
                        self.name, wheel_cache
                    )
                    preparer = RequirementPreparer(
                        build_dir=directory.path,
                        src_dir=options.src_dir,
                        download_dir=None,
                        wheel_download_dir=None,
                        progress_bar=options.progress_bar,
                        build_isolation=options.build_isolation,
                        req_tracker=req_tracker,
                    )

                    resolver = Resolver(
                        preparer=preparer,
                        finder=finder,
                        session=session,
                        wheel_cache=wheel_cache,
                        use_user_site=options.use_user_site,
                        upgrade_strategy=upgrade_strategy,
                        force_reinstall=options.force_reinstall,
                        ignore_dependencies=options.ignore_dependencies,
                        ignore_requires_python=options.ignore_requires_python,
                        ignore_installed=options.ignore_installed,
                        isolated=options.isolated_mode,
                        use_pep517=options.use_pep517
                    )
                    resolver.resolve(requirement_set)

                    protect_pip_from_modification_on_windows(
                        modifying_pip=requirement_set.has_requirement("pip")
                    )

                    # Consider legacy and PEP517-using requirements separately
                    legacy_requirements = []
                    pep517_requirements = []
                    for req in requirement_set.requirements.values():
                        if req.use_pep517:
                            pep517_requirements.append(req)
                        else:
                            legacy_requirements.append(req)

                    # We don't build wheels for legacy requirements if we
                    # don't have wheel installed or we don't have a cache dir
                    try:
                        import wheel  # noqa: F401
                        build_legacy = bool(options.cache_dir)
                    except ImportError:
                        build_legacy = False

                    wb = WheelBuilder(
                        finder, preparer, wheel_cache,
                        build_options=[], global_options=[],
                    )

                    # Always build PEP 517 requirements
                    build_failures = wb.build(
                        pep517_requirements,
                        session=session, autobuilding=True
                    )

                    if build_legacy:
                        # We don't care about failures building legacy
                        # requirements, as we'll fall through to a direct
                        # install for those.
                        wb.build(
                            legacy_requirements,
                            session=session, autobuilding=True
                        )

                    # If we're using PEP 517, we cannot do a direct install
                    # so we fail here.
                    if build_failures:
                        raise InstallationError(
                            "Could not build wheels for {} which use" +
                            " PEP 517 and cannot be installed directly".format(
                                ", ".join(r.name for r in build_failures)))

                    to_install = resolver.get_installation_order(
                        requirement_set
                    )

                    # Consistency Checking of the package set we're installing.
                    should_warn_about_conflicts = (
                        not options.ignore_dependencies and
                        options.warn_about_conflicts
                    )
                    if should_warn_about_conflicts:
                        self._warn_about_conflicts(to_install)

                    # Don't warn about script install locations if
                    # --target has been specified
                    warn_script_location = options.warn_script_location
                    if options.target_dir:
                        warn_script_location = False

                    installed = install_given_reqs(
                        to_install,
                        install_options,
                        global_options,
                        root=options.root_path,
                        home=target_temp_dir.path,
                        prefix=options.prefix_path,
                        pycompile=options.compile,
                        warn_script_location=warn_script_location,
                        use_user_site=options.use_user_site,
                    )

                    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,
                    )
                    working_set = pkg_resources.WorkingSet(lib_locations)

                    reqs = sorted(installed, key=operator.attrgetter('name'))
                    items = []
                    for req in reqs:
                        item = req.name
                        try:
                            installed_version = get_installed_version(
                                req.name, working_set=working_set
                            )
                            if installed_version:
                                item += '-' + installed_version
                        except Exception:
                            pass
                        items.append(item)
                    installed = ' '.join(items)
                    if installed:
                        logger.info('Successfully installed %s', installed)
                except EnvironmentError as error:
                    show_traceback = (self.verbosity >= 1)

                    message = create_env_error_message(
                        error, show_traceback, options.use_user_site,
                    )
                    logger.error(message, exc_info=show_traceback)

                    return ERROR
                except PreviousBuildDirError:
                    options.no_clean = True
                    raise
                finally:
                    # Clean up
                    if not options.no_clean:
                        requirement_set.cleanup_files()
                        wheel_cache.cleanup()

        if options.target_dir:
            self._handle_target_dir(
                options.target_dir, target_temp_dir, options.upgrade
            )
        return requirement_set
Пример #17
0
    def run(self, options, args):
        cmdoptions.check_install_build_global(options)

        def is_venv():
            return hasattr(sys, 'real_prefix') or \
                    (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix)

        # Check whether we have root privileges and aren't in venv/virtualenv
        if os.getuid() == 0 and not is_venv():
            logger.warning(
                "WARNING: Running pip install with root privileges is "
                "generally not a good idea. Try `%s install --user` instead." %
                path.basename(sys.argv[0]))

        upgrade_strategy = "to-satisfy-only"
        if options.upgrade:
            upgrade_strategy = options.upgrade_strategy

        if options.build_dir:
            options.build_dir = os.path.abspath(options.build_dir)

        options.src_dir = os.path.abspath(options.src_dir)
        install_options = options.install_options or []
        if options.use_user_site:
            if options.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.")
            install_options.append('--user')
            install_options.append('--prefix=')

        target_temp_dir = TempDirectory(kind="target")
        if options.target_dir:
            options.ignore_installed = True
            options.target_dir = os.path.abspath(options.target_dir)
            if (os.path.exists(options.target_dir)
                    and not os.path.isdir(options.target_dir)):
                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.create()
            install_options.append('--home=' + target_temp_dir.path)

        global_options = options.global_options or []

        with self._build_session(options) as session:
            finder = self._build_package_finder(options, session)
            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 RequirementTracker() as req_tracker, TempDirectory(
                    options.build_dir, delete=build_delete,
                    kind="install") as directory:
                requirement_set = RequirementSet(
                    require_hashes=options.require_hashes, )

                try:
                    self.populate_requirement_set(requirement_set, args,
                                                  options, finder, session,
                                                  self.name, wheel_cache)
                    preparer = RequirementPreparer(
                        build_dir=directory.path,
                        src_dir=options.src_dir,
                        download_dir=None,
                        wheel_download_dir=None,
                        progress_bar=options.progress_bar,
                        build_isolation=options.build_isolation,
                        req_tracker=req_tracker,
                    )

                    resolver = Resolver(
                        preparer=preparer,
                        finder=finder,
                        session=session,
                        wheel_cache=wheel_cache,
                        use_user_site=options.use_user_site,
                        upgrade_strategy=upgrade_strategy,
                        force_reinstall=options.force_reinstall,
                        ignore_dependencies=options.ignore_dependencies,
                        ignore_requires_python=options.ignore_requires_python,
                        ignore_installed=options.ignore_installed,
                        isolated=options.isolated_mode,
                    )
                    resolver.resolve(requirement_set)

                    protect_pip_from_modification_on_windows(
                        modifying_pip=requirement_set.has_requirement("pip"))

                    # If caching is disabled or wheel is not installed don't
                    # try to build wheels.
                    if wheel and options.cache_dir:
                        # build wheels before install.
                        wb = WheelBuilder(
                            finder,
                            preparer,
                            wheel_cache,
                            build_options=[],
                            global_options=[],
                        )
                        # Ignore the result: a failed wheel will be
                        # installed from the sdist/vcs whatever.
                        wb.build(requirement_set.requirements.values(),
                                 session=session,
                                 autobuilding=True)

                    to_install = resolver.get_installation_order(
                        requirement_set)

                    # Consistency Checking of the package set we're installing.
                    should_warn_about_conflicts = (
                        not options.ignore_dependencies
                        and options.warn_about_conflicts)
                    if should_warn_about_conflicts:
                        self._warn_about_conflicts(to_install)

                    # Don't warn about script install locations if
                    # --target has been specified
                    warn_script_location = options.warn_script_location
                    if options.target_dir:
                        warn_script_location = False

                    installed = install_given_reqs(
                        to_install,
                        install_options,
                        global_options,
                        root=options.root_path,
                        home=target_temp_dir.path,
                        prefix=options.prefix_path,
                        pycompile=options.compile,
                        warn_script_location=warn_script_location,
                        use_user_site=options.use_user_site,
                        strip_file_prefix=options.strip_file_prefix,
                    )

                    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,
                    )
                    working_set = pkg_resources.WorkingSet(lib_locations)

                    reqs = sorted(installed, key=operator.attrgetter('name'))
                    items = []
                    for req in reqs:
                        item = req.name
                        try:
                            installed_version = get_installed_version(
                                req.name, working_set=working_set)
                            if installed_version:
                                item += '-' + installed_version
                        except Exception:
                            pass
                        items.append(item)
                    installed = ' '.join(items)
                    if installed:
                        logger.info('Successfully installed %s', installed)
                except EnvironmentError as error:
                    show_traceback = (self.verbosity >= 1)

                    message = create_env_error_message(
                        error,
                        show_traceback,
                        options.use_user_site,
                    )
                    logger.error(message, exc_info=show_traceback)

                    return ERROR
                except PreviousBuildDirError:
                    options.no_clean = True
                    raise
                finally:
                    # Clean up
                    if not options.no_clean:
                        requirement_set.cleanup_files()
                        wheel_cache.cleanup()

        if options.target_dir:
            self._handle_target_dir(options.target_dir, target_temp_dir,
                                    options.upgrade)
        return requirement_set
    def _main(self, args):
        # type: (List[str]) -> int
        # We must initialize this before the tempdir manager, otherwise the
        # configuration would not be accessible by the time we clean up the
        # tempdir manager.
        tempdir_registry = enter_context(tempdir_registry())
        # Intentionally set as early as possible so globally-managed temporary
        # directories are available to the rest of the code.
        enter_context(global_tempdir_manager())

        options, args = parse_args(args)

        # Set verbosity so that it can be used elsewhere.
        verbosity = options.verbose - options.quiet

        level_number = setup_logging(
            verbosity=verbosity,
            no_color=options.no_color,
            user_log_file=options.log,
        )

        if (sys.version_info[:2] == (2, 7)
                and not options.no_python_version_warning):
            message = (
                "pip 21.0 will drop support for Python 2.7 in January 2021. "
                "More details about Python 2 support in pip can be found at "
                "https://pip.pypa.io/en/latest/development/release-process/#python-2-support"  # noqa
            )
            if platform.python_implementation() == "CPython":
                message = (
                    "Python 2.7 reached the end of its life on January "
                    "1st, 2020. Please upgrade your Python as Python 2.7 "
                    "is no longer maintained. ") + message
            deprecated(message, replacement=None, gone_in="21.0")

        if (sys.version_info[:2] == (3, 5)
                and not options.no_python_version_warning):
            message = ("Python 3.5 reached the end of its life on September "
                       "13th, 2020. Please upgrade your Python as Python 3.5 "
                       "is no longer maintained. pip 21.0 will drop support "
                       "for Python 3.5 in January 2021.")
            deprecated(message, replacement=None, gone_in="21.0")

        # TODO: Try to get these passing down from the command?
        #       without resorting to os.environ to hold these.
        #       This also affects isolated builds and it should.

        if options.no_input:
            os.environ['PIP_NO_INPUT'] = '1'

        if options.exists_action:
            os.environ['PIP_EXISTS_ACTION'] = ' '.join(options.exists_action)

        if options.require_venv and not ignore_require_venv:
            # If a venv is required check if it can really be found
            if not running_under_virtualenv():
                logger.critical(
                    'Could not find an activated virtualenv (required).')
                sys.exit(VIRTUALENV_NOT_FOUND)

        if options.cache_dir:
            options.cache_dir = normalize_path(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

        if '2020-resolver' in options.features_enabled and not PY2:
            logger.warning(
                "--use-feature=2020-resolver no longer has any effect, "
                "since it is now the default dependency resolver in pip. "
                "This will become an error in pip 21.0.")

        try:
            status = run(options, args)
            assert isinstance(status, int)
            return status
        except PreviousBuildDirError as exc:
            logger.critical(str(exc))
            logger.debug('Exception information:', exc_info=True)

            return PREVIOUS_BUILD_DIR_ERROR
        except (InstallationError, UninstallationError, BadCommand,
                SubProcessError, NetworkConnectionError) as exc:
            logger.critical(str(exc))
            logger.debug('Exception information:', exc_info=True)

            return ERROR
        except CommandError as exc:
            logger.critical('%s', exc)
            logger.debug('Exception information:', exc_info=True)

            return ERROR
        except BrokenStdoutLoggingError:
            # Bypass our logger and write any remaining messages to stderr
            # because stdout no longer works.
            print('ERROR: Pipe to stdout was broken', file=sys.stderr)
            if level_number <= logging.DEBUG:
                traceback.print_exc(file=sys.stderr)

            return ERROR
        except KeyboardInterrupt:
            logger.critical('Operation cancelled by user')
            logger.debug('Exception information:', exc_info=True)

            return ERROR
        except BaseException:
            logger.critical('Exception:', exc_info=True)

            return UNKNOWN_ERROR
        finally:
            handle_pip_version_check(options)
Пример #19
0
    def run(self, options, args):
        options.ignore_installed = True
        # editable doesn't really make sense for `pip download`, but the bowels
        # of the RequirementSet code require that property.
        options.editables = []

        if options.python_version:
            python_versions = [options.python_version]
        else:
            python_versions = None

        dist_restriction_set = any([
            options.python_version,
            options.platform,
            options.abi,
            options.implementation,
        ])
        binary_only = FormatControl(set(), {':all:'})
        if dist_restriction_set and options.format_control != binary_only:
            raise CommandError(
                "--only-binary=:all: must be set and --no-binary must not "
                "be set (or must be set to :none:) when restricting platform "
                "and interpreter constraints using --python-version, "
                "--platform, --abi, or --implementation.")

        options.src_dir = os.path.abspath(options.src_dir)
        options.download_dir = normalize_path(options.download_dir)

        ensure_dir(options.download_dir)

        with self._build_session(options) as session:
            finder = self._build_package_finder(
                options=options,
                session=session,
                platform=options.platform,
                python_versions=python_versions,
                abi=options.abi,
                implementation=options.implementation,
            )
            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 TempDirectory(options.build_dir,
                               delete=build_delete,
                               kind="download") as directory:

                requirement_set = RequirementSet(
                    require_hashes=options.require_hashes, )
                self.populate_requirement_set(requirement_set, args, options,
                                              finder, session, self.name, None)

                preparer = RequirementPreparer(
                    build_dir=directory.path,
                    src_dir=options.src_dir,
                    download_dir=options.download_dir,
                    wheel_download_dir=None,
                    progress_bar=options.progress_bar,
                )

                resolver = Resolver(
                    preparer=preparer,
                    finder=finder,
                    session=session,
                    wheel_cache=None,
                    use_user_site=False,
                    upgrade_strategy="to-satisfy-only",
                    force_reinstall=False,
                    ignore_dependencies=options.ignore_dependencies,
                    ignore_requires_python=False,
                    ignore_installed=True,
                    isolated=options.isolated_mode,
                )
                resolver.resolve(requirement_set)

                downloaded = ' '.join([
                    req.name for req in requirement_set.successfully_downloaded
                ])
                if downloaded:
                    logger.info('Successfully downloaded %s', downloaded)

                # Clean up
                if not options.no_clean:
                    requirement_set.cleanup_files()

        return requirement_set
Пример #20
0
            os.environ['PIP_NO_INPUT'] = '1'

        if options.exists_action:
            os.environ['PIP_EXISTS_ACTION'] = ' '.join(options.exists_action)

        if options.require_venv and not self.ignore_require_venv:
            # If a venv is required check if it can really be found
            if not running_under_virtualenv():
                logger.critical(
                    'Could not find an activated virtualenv (required).'
                )
                sys.exit(VIRTUALENV_NOT_FOUND)

        if options.cache_dir:
            options.cache_dir = normalize_path(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

<<<<<<< HEAD
        if getattr(options, "build_dir", None):
            deprecated(
                reason=(
                    "The -b/--build/--build-dir/--build-directory "
Пример #21
0
    def run(self, options, args):
        cmdoptions.check_install_build_global(options)

        upgrade_strategy = "to-satisfy-only"
        if options.upgrade:
            upgrade_strategy = options.upgrade_strategy

        if options.build_dir:
            options.build_dir = os.path.abspath(options.build_dir)

        options.src_dir = os.path.abspath(options.src_dir)
        install_options = options.install_options or []
        if options.use_user_site:
            if options.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."
                )
            install_options.append('--user')
            install_options.append('--prefix=')

        target_temp_dir = TempDirectory(kind="target")
        if options.target_dir:
            options.ignore_installed = True
            options.target_dir = os.path.abspath(options.target_dir)
            if (os.path.exists(options.target_dir) and not
                    os.path.isdir(options.target_dir)):
                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.create()
            install_options.append('--home=' + target_temp_dir.path)

        global_options = options.global_options or []

        with self._build_session(options) as session:

            finder = self._build_package_finder(options, session)
            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 TempDirectory(
                options.build_dir, delete=build_delete, kind="install"
            ) as directory:
                requirement_set = RequirementSet(
                    target_dir=target_temp_dir.path,
                    pycompile=options.compile,
                    require_hashes=options.require_hashes,
                    use_user_site=options.use_user_site,
                )

                self.populate_requirement_set(
                    requirement_set, args, options, finder, session, self.name,
                    wheel_cache
                )
                preparer = RequirementPreparer(
                    build_dir=directory.path,
                    src_dir=options.src_dir,
                    download_dir=None,
                    wheel_download_dir=None,
                    progress_bar=options.progress_bar,
                )
                try:
                    resolver = Resolver(
                        preparer=preparer,
                        finder=finder,
                        session=session,
                        wheel_cache=wheel_cache,
                        use_user_site=options.use_user_site,
                        upgrade_strategy=upgrade_strategy,
                        force_reinstall=options.force_reinstall,
                        ignore_dependencies=options.ignore_dependencies,
                        ignore_requires_python=options.ignore_requires_python,
                        ignore_installed=options.ignore_installed,
                        isolated=options.isolated_mode,
                    )
                    resolver.resolve(requirement_set)

                    # on -d don't do complex things like building
                    # wheels, and don't try to build wheels when wheel is
                    # not installed.
                    if wheel and options.cache_dir:
                        # build wheels before install.
                        wb = WheelBuilder(
                            requirement_set,
                            finder,
                            preparer,
                            wheel_cache,
                            build_options=[],
                            global_options=[],
                        )
                        # Ignore the result: a failed wheel will be
                        # installed from the sdist/vcs whatever.
                        wb.build(session=session, autobuilding=True)

                    installed = requirement_set.install(
                        install_options,
                        global_options,
                        root=options.root_path,
                        prefix=options.prefix_path,
                        warn_script_location=options.warn_script_location,
                    )

                    possible_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,
                    )
                    reqs = sorted(installed, key=operator.attrgetter('name'))
                    items = []
                    for req in reqs:
                        item = req.name
                        try:
                            installed_version = get_installed_version(
                                req.name, possible_lib_locations
                            )
                            if installed_version:
                                item += '-' + installed_version
                        except Exception:
                            pass
                        items.append(item)
                    installed = ' '.join(items)
                    if installed:
                        logger.info('Successfully installed %s', installed)
                except EnvironmentError as e:
                    message_parts = []

                    user_option_part = "Consider using the `--user` option"
                    permissions_part = "Check the permissions"

                    if e.errno == errno.EPERM:
                        if not options.use_user_site:
                            message_parts.extend([
                                user_option_part, " or ",
                                permissions_part.lower(),
                            ])
                        else:
                            message_parts.append(permissions_part)
                        message_parts.append("\n")

                    logger.error(
                        "".join(message_parts), exc_info=(options.verbose > 1)
                    )
                    return ERROR
                except PreviousBuildDirError:
                    options.no_clean = True
                    raise
                finally:
                    # Clean up
                    if not options.no_clean:
                        requirement_set.cleanup_files()

        if options.target_dir:
            self._handle_target_dir(
                options.target_dir, target_temp_dir, options.upgrade
            )
        return requirement_set
Пример #22
0
    def _main(self, args):
        # type: (List[str]) -> int
        # Intentionally set as early as possible so globally-managed temporary
        # directories are available to the rest of the code.
        self.enter_context(global_tempdir_manager())

        options, args = self.parse_args(args)

        # Set verbosity so that it can be used elsewhere.
        self.verbosity = options.verbose - options.quiet

        level_number = setup_logging(
            verbosity=self.verbosity,
            no_color=options.no_color,
            user_log_file=options.log,
        )

        if (sys.version_info[:2] == (2, 7)
                and not options.no_python_version_warning):
            message = (
                "A future version of pip will drop support for Python 2.7. "
                "More details about Python 2 support in pip, can be found at "
                "https://pip.pypa.io/en/latest/development/release-process/#python-2-support"  # noqa
            )
            if platform.python_implementation() == "CPython":
                message = (
                    "Python 2.7 reached the end of its life on January "
                    "1st, 2020. Please upgrade your Python as Python 2.7 "
                    "is no longer maintained. ") + message
            deprecated(message, replacement=None, gone_in=None)

        if options.skip_requirements_regex:
            deprecated(
                "--skip-requirements-regex is unsupported and will be removed",
                replacement=(
                    "manage requirements/constraints files explicitly, "
                    "possibly generating them from metadata"),
                gone_in="20.1",
                issue=7297,
            )

        # TODO: Try to get these passing down from the command?
        #       without resorting to os.environ to hold these.
        #       This also affects isolated builds and it should.

        if options.no_input:
            os.environ['PIP_NO_INPUT'] = '1'

        if options.exists_action:
            os.environ['PIP_EXISTS_ACTION'] = ' '.join(options.exists_action)

        if options.require_venv and not self.ignore_require_venv:
            # If a venv is required check if it can really be found
            if not running_under_virtualenv():
                logger.critical(
                    'Could not find an activated virtualenv (required).')
                sys.exit(VIRTUALENV_NOT_FOUND)

        if options.cache_dir:
            options.cache_dir = normalize_path(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
            # and when it is done, isinstance is not needed anymore
            if isinstance(status, int):
                return status
        except PreviousBuildDirError as exc:
            logger.critical(str(exc))
            logger.debug('Exception information:', exc_info=True)

            return PREVIOUS_BUILD_DIR_ERROR
        except (InstallationError, UninstallationError, BadCommand) as exc:
            logger.critical(str(exc))
            logger.debug('Exception information:', exc_info=True)

            return ERROR
        except CommandError as exc:
            logger.critical('%s', exc)
            logger.debug('Exception information:', exc_info=True)

            return ERROR
        except BrokenStdoutLoggingError:
            # Bypass our logger and write any remaining messages to stderr
            # because stdout no longer works.
            print('ERROR: Pipe to stdout was broken', file=sys.stderr)
            if level_number <= logging.DEBUG:
                traceback.print_exc(file=sys.stderr)

            return ERROR
        except KeyboardInterrupt:
            logger.critical('Operation cancelled by user')
            logger.debug('Exception information:', exc_info=True)

            return ERROR
        except BaseException:
            logger.critical('Exception:', exc_info=True)

            return UNKNOWN_ERROR
        finally:
            self.handle_pip_version_check(options)

        return SUCCESS
Пример #23
0
    def run(self, options, args):
        cmdoptions.check_install_build_global(options)
        upgrade_strategy = "to-satisfy-only"
        if options.upgrade:
            upgrade_strategy = options.upgrade_strategy

        if options.build_dir:
            options.build_dir = os.path.abspath(options.build_dir)

        cmdoptions.check_dist_restriction(options, check_target=True)

        if options.python_version:
            python_versions = [options.python_version]
        else:
            python_versions = None

        options.src_dir = os.path.abspath(options.src_dir)
        install_options = options.install_options or []
        if options.use_user_site:
            if options.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.")
            install_options.append('--user')
            install_options.append('--prefix=')

        target_temp_dir = TempDirectory(kind="target")
        if options.target_dir:
            options.ignore_installed = True
            options.target_dir = os.path.abspath(options.target_dir)
            if (os.path.exists(options.target_dir)
                    and not os.path.isdir(options.target_dir)):
                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.create()
            install_options.append('--home=' + target_temp_dir.path)

        global_options = options.global_options or []

        with self._build_session(options) as session:
            finder = self._build_package_finder(
                options=options,
                session=session,
                platform=options.platform,
                python_versions=python_versions,
                abi=options.abi,
                implementation=options.implementation,
            )
            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 RequirementTracker() as req_tracker, TempDirectory(
                    options.build_dir, delete=build_delete,
                    kind="install") as directory:
                requirement_set = RequirementSet(
                    require_hashes=options.require_hashes,
                    check_supported_wheels=not options.target_dir,
                )

                try:
                    self.populate_requirement_set(requirement_set, args,
                                                  options, finder, session,
                                                  self.name, wheel_cache)
                    preparer = RequirementPreparer(
                        build_dir=directory.path,
                        src_dir=options.src_dir,
                        download_dir=None,
                        wheel_download_dir=None,
                        progress_bar=options.progress_bar,
                        build_isolation=options.build_isolation,
                        req_tracker=req_tracker,
                    )

                    resolver = Resolver(
                        preparer=preparer,
                        finder=finder,
                        session=session,
                        wheel_cache=wheel_cache,
                        use_user_site=options.use_user_site,
                        upgrade_strategy=upgrade_strategy,
                        force_reinstall=options.force_reinstall,
                        ignore_dependencies=options.ignore_dependencies,
                        ignore_requires_python=options.ignore_requires_python,
                        ignore_installed=options.ignore_installed,
                        isolated=options.isolated_mode,
                        use_pep517=options.use_pep517)
                    resolver.resolve(requirement_set)

                    protect_pip_from_modification_on_windows(
                        modifying_pip=requirement_set.has_requirement("pip"))

                    # Consider legacy and PEP517-using requirements.txt separately
                    legacy_requirements = []
                    pep517_requirements = []
                    for req in requirement_set.requirements.values():
                        if req.use_pep517:
                            pep517_requirements.append(req)
                        else:
                            legacy_requirements.append(req)

                    # We don't build wheels for legacy requirements.txt if we
                    # don't have wheel installed or we don't have a cache dir
                    try:
                        import wheel  # noqa: F401
                        build_legacy = bool(options.cache_dir)
                    except ImportError:
                        build_legacy = False

                    wb = WheelBuilder(
                        finder,
                        preparer,
                        wheel_cache,
                        build_options=[],
                        global_options=[],
                    )

                    # Always build PEP 517 requirements.txt
                    build_failures = wb.build(pep517_requirements,
                                              session=session,
                                              autobuilding=True)

                    if build_legacy:
                        # We don't care about failures building legacy
                        # requirements.txt, as we'll fall through to a direct
                        # install for those.
                        wb.build(legacy_requirements,
                                 session=session,
                                 autobuilding=True)

                    # If we're using PEP 517, we cannot do a direct install
                    # so we fail here.
                    if build_failures:
                        raise InstallationError(
                            "Could not build wheels for {} which use"
                            " PEP 517 and cannot be installed directly".format(
                                ", ".join(r.name for r in build_failures)))

                    to_install = resolver.get_installation_order(
                        requirement_set)

                    # Consistency Checking of the package set we're installing.
                    should_warn_about_conflicts = (
                        not options.ignore_dependencies
                        and options.warn_about_conflicts)
                    if should_warn_about_conflicts:
                        self._warn_about_conflicts(to_install)

                    # Don't warn about script install locations if
                    # --target has been specified
                    warn_script_location = options.warn_script_location
                    if options.target_dir:
                        warn_script_location = False

                    installed = install_given_reqs(
                        to_install,
                        install_options,
                        global_options,
                        root=options.root_path,
                        home=target_temp_dir.path,
                        prefix=options.prefix_path,
                        pycompile=options.compile,
                        warn_script_location=warn_script_location,
                        use_user_site=options.use_user_site,
                    )

                    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,
                    )
                    working_set = pkg_resources.WorkingSet(lib_locations)

                    reqs = sorted(installed, key=operator.attrgetter('name'))
                    items = []
                    for req in reqs:
                        item = req.name
                        try:
                            installed_version = get_installed_version(
                                req.name, working_set=working_set)
                            if installed_version:
                                item += '-' + installed_version
                        except Exception:
                            pass
                        items.append(item)
                    installed = ' '.join(items)
                    if installed:
                        logger.info('Successfully installed %s', installed)
                except EnvironmentError as error:
                    show_traceback = (self.verbosity >= 1)

                    message = create_env_error_message(
                        error,
                        show_traceback,
                        options.use_user_site,
                    )
                    logger.error(message, exc_info=show_traceback)

                    return ERROR
                except PreviousBuildDirError:
                    options.no_clean = True
                    raise
                finally:
                    # Clean up
                    if not options.no_clean:
                        requirement_set.cleanup_files()
                        wheel_cache.cleanup()

        if options.target_dir:
            self._handle_target_dir(options.target_dir, target_temp_dir,
                                    options.upgrade)
        return requirement_set
Пример #24
0
    def run(self, options, args):
        options.ignore_installed = True
        # editable doesn't really make sense for `pip download`, but the bowels
        # of the RequirementSet code require that property.
        options.editables = []

        cmdoptions.check_dist_restriction(options)

        options.src_dir = os.path.abspath(options.src_dir)
        options.download_dir = normalize_path(options.download_dir)

        ensure_dir(options.download_dir)

        with self._build_session(options) as session:
            target_python = make_target_python(options)
            finder = self._build_package_finder(
                options=options,
                session=session,
                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 RequirementTracker() as req_tracker, TempDirectory(
                    options.build_dir, delete=build_delete,
                    kind="download") as directory:

                requirement_set = RequirementSet(
                    require_hashes=options.require_hashes, )
                self.populate_requirement_set(requirement_set, args, options,
                                              finder, session, None)

                preparer = self.make_requirement_preparer(
                    temp_directory=directory,
                    options=options,
                    req_tracker=req_tracker,
                    download_dir=options.download_dir,
                )

                resolver = self.make_resolver(
                    preparer=preparer,
                    finder=finder,
                    session=session,
                    options=options,
                    py_version_info=options.python_version,
                )
                resolver.resolve(requirement_set)

                downloaded = ' '.join([
                    req.name for req in requirement_set.successfully_downloaded
                ])
                if downloaded:
                    logger.info('Successfully downloaded %s', downloaded)

                # Clean up
                if not options.no_clean:
                    requirement_set.cleanup_files()

        return requirement_set