Exemplo n.º 1
0
def get_installed_version(dist_name, lookup_dirs=None):
    """Get the installed version of dist_name avoiding pkg_resources cache"""
    # Create a requirement that we'll look for inside of setuptools.
    req = pkg_resources.Requirement.parse(dist_name)

    # We want to avoid having this cached, so we need to construct a new
    # working set each time.
    if lookup_dirs is None:
        working_set = pkg_resources.WorkingSet()
    else:
        working_set = pkg_resources.WorkingSet(lookup_dirs)

    # Get the installed distribution from our working set
    dist = working_set.find(req)

    # Check to see if we got an installed distribution or not, if we did
    # we want to return it's version.
    return dist.version if dist else None
def get_installed_distributions(
        local_only=True,  # type: bool
        skip=stdlib_pkgs,  # type: Container[str]
        include_editables=True,  # type: bool
        editables_only=False,  # type: bool
        user_only=False,  # type: bool
        paths=None  # type: Optional[List[str]]
):
    # type: (...) -> List[Distribution]
    """
    Return a list of installed Distribution objects.

    If ``local_only`` is True (default), only return installations
    local to the current virtualenv, if in a virtualenv.

    ``skip`` argument is an iterable of lower-case project names to
    ignore; defaults to stdlib_pkgs

    If ``include_editables`` is False, don't report editables.

    If ``editables_only`` is True , only report editables.

    If ``user_only`` is True , only report installations in the user
    site directory.

    If ``paths`` is set, only report the distributions present at the
    specified list of locations.
    """
    if paths:
        working_set = pkg_resources.WorkingSet(paths)
    else:
        working_set = pkg_resources.working_set

    if local_only:
        local_test = dist_is_local
    else:

        def local_test(d):
            return True

    if include_editables:

        def editable_test(d):
            return True
    else:

        def editable_test(d):
            return not dist_is_editable(d)

    if editables_only:

        def editables_only_test(d):
            return dist_is_editable(d)
    else:

        def editables_only_test(d):
            return True

    if user_only:
        user_test = dist_in_usersite
    else:

        def user_test(d):
            return True

    return [
        d for d in working_set if local_test(d) and d.key not in skip
        and editable_test(d) and editables_only_test(d) and user_test(d)
    ]
    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
Exemplo n.º 4
0
 def from_paths(cls, paths: Optional[List[str]]) -> BaseEnvironment:
     return cls(pkg_resources.WorkingSet(paths))
Exemplo n.º 5
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

        cmdoptions.check_dist_restriction(options, check_target=True)

        install_options = options.install_options or []

        options.use_user_site = decide_user_install(
            options.use_user_site,
            prefix_path=options.prefix_path,
            target_dir=options.target_dir,
            root_path=options.root_path,
            isolated_mode=options.isolated_mode,
        )

        target_temp_dir = 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

        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)

        with get_requirement_tracker() as req_tracker, TempDirectory(
                options.build_dir, delete=build_delete,
                kind="install") as directory:
            requirement_set = RequirementSet(
                check_supported_wheels=not options.target_dir, )

            try:
                self.populate_requirement_set(requirement_set, args, options,
                                              finder, session, wheel_cache)

                warn_deprecated_install_options(requirement_set,
                                                options.install_options)

                preparer = self.make_requirement_preparer(
                    temp_build_dir=directory,
                    options=options,
                    req_tracker=req_tracker,
                    session=session,
                    finder=finder,
                    use_user_site=options.use_user_site,
                )
                resolver = self.make_resolver(
                    preparer=preparer,
                    finder=finder,
                    options=options,
                    wheel_cache=wheel_cache,
                    use_user_site=options.use_user_site,
                    ignore_installed=options.ignore_installed,
                    ignore_requires_python=options.ignore_requires_python,
                    force_reinstall=options.force_reinstall,
                    upgrade_strategy=upgrade_strategy,
                    use_pep517=options.use_pep517,
                )

                self.trace_basic_info(finder)

                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 = getattr(pip_req, "satisfied_by",
                                            None) is None
                protect_pip_from_modification_on_windows(
                    modifying_pip=modifying_pip)

                check_binary_allowed = get_check_binary_allowed(
                    finder.format_control)

                reqs_to_build = [
                    r for r in requirement_set.requirements.values()
                    if should_build_for_install_command(
                        r, check_binary_allowed)
                ]

                _, build_failures = build(
                    reqs_to_build,
                    wheel_cache=wheel_cache,
                    build_options=[],
                    global_options=[],
                )

                # If we're using PEP 517, we cannot do a direct install
                # so we fail here.
                # We don't care about failures building legacy
                # requirements, as we'll fall through to a direct
                # install for those.
                pep517_build_failures = [
                    r for r in build_failures if r.use_pep517
                ]
                if pep517_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 pep517_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)

                installed.sort(key=operator.attrgetter('name'))
                items = []
                for result in installed:
                    item = result.name
                    try:
                        installed_version = get_installed_version(
                            result.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
Exemplo n.º 6
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 = getattr(pip_req, "satisfied_by",
                                            None) 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