Esempio n. 1
0
    def get_dist_to_uninstall(self, candidate: Candidate) -> Optional[BaseDistribution]:
        # TODO: Are there more cases this needs to return True? Editable?
        dist = self._installed_dists.get(candidate.project_name)
        if dist is None:  # Not installed, no uninstallation required.
            return None

        # Prevent uninstalling packages from /usr
        if dist_location(dist._dist) in (
                get_scheme('', prefix=sys.base_prefix).purelib,
                get_scheme('', prefix=sys.base_prefix).platlib,
            ):
            return None

        # We're installing into global site. The current installation must
        # be uninstalled, no matter it's in global or user site, because the
        # user site installation has precedence over global.
        if not self._use_user_site:
            return dist

        # We're installing into user site. Remove the user site installation.
        if dist.in_usersite:
            return dist

        # We're installing into user site, but the installed incompatible
        # package is in global site. We can't uninstall that, and would let
        # the new user installation to "shadow" it. But shadowing won't work
        # in virtual environments, so we error out.
        if running_under_virtualenv() and dist.in_site_packages:
            message = (
                f"Will not install to the user site because it will lack "
                f"sys.path precedence to {dist.raw_name} in {dist.location}"
            )
            raise InstallationError(message)
        return None
Esempio n. 2
0
def dist_in_install_path(dist):
    """
    Return True if given Distribution is installed in
    path matching distutils_scheme layout.
    """
    norm_path = normalize_path(dist_location(dist))
    return norm_path.startswith(normalize_path(
        get_scheme("").purelib.split('python')[0]))
Esempio n. 3
0
    def _handle_target_dir(
        self, target_dir: str, target_temp_dir: TempDirectory, upgrade: bool
    ) -> None:
        ensure_dir(target_dir)

        # Checking both purelib and platlib directories for installed
        # packages to be moved to target directory
        lib_dir_list = []

        # Checking both purelib and platlib directories for installed
        # packages to be moved to target directory
        scheme = get_scheme('', home=target_temp_dir.path)
        purelib_dir = scheme.purelib
        platlib_dir = scheme.platlib
        data_dir = scheme.data

        if os.path.exists(purelib_dir):
            lib_dir_list.append(purelib_dir)
        if os.path.exists(platlib_dir) and platlib_dir != purelib_dir:
            lib_dir_list.append(platlib_dir)
        if os.path.exists(data_dir):
            lib_dir_list.append(data_dir)

        for lib_dir in lib_dir_list:
            for item in os.listdir(lib_dir):
                if lib_dir == data_dir:
                    ddir = os.path.join(data_dir, item)
                    if any(s.startswith(ddir) for s in lib_dir_list[:-1]):
                        continue
                target_item_dir = os.path.join(target_dir, item)
                if os.path.exists(target_item_dir):
                    if not upgrade:
                        logger.warning(
                            'Target directory %s already exists. Specify '
                            '--upgrade to force replacement.',
                            target_item_dir
                        )
                        continue
                    if os.path.islink(target_item_dir):
                        logger.warning(
                            'Target directory %s already exists and is '
                            'a link. pip will not automatically replace '
                            'links, please remove if replacement is '
                            'desired.',
                            target_item_dir
                        )
                        continue
                    if os.path.isdir(target_item_dir):
                        shutil.rmtree(target_item_dir)
                    else:
                        os.remove(target_item_dir)

                shutil.move(
                    os.path.join(lib_dir, item),
                    target_item_dir
                )
Esempio n. 4
0
def get_lib_location_guesses(user: bool = False,
                             home: Optional[str] = None,
                             root: Optional[str] = None,
                             isolated: bool = False,
                             prefix: Optional[str] = None) -> List[str]:
    scheme = get_scheme(
        '',
        user=user,
        home=home,
        root=root,
        isolated=isolated,
        prefix=prefix,
    )
    return [scheme.purelib, scheme.platlib]
Esempio n. 5
0
    def _install_wheel(self, pkg):

        pkg._assert_paths(install=True)

        if pkg.package_path.endswith('.whl'):
            log.info(
                style_note("Found Python Wheel",
                           os.path.basename(self.dist_info_dir)))
        else:
            log.info(
                style_note("Found dist-info",
                           os.path.basename(self.dist_info_dir)))
            log.warning("Bare dist-info does not appear to be a wheel.")

        wheel_dir, dist_info_name = os.path.split(self.dist_info_dir)
        wheel_name = os.path.splitext(dist_info_name)[0]

        # Lets just take advantage of pip!
        # The only reason we're reading into pip like this is because we
        # would rather just do this part, rather than have it go through
        # the full process with the *.whl file. If this breaks, feel
        # free to do something like:
        #     pip install --force-reinstall --prefix {pkg.install_path} --no-deps {pkg.package_path}
        # along with:
        #     --no-warn-script-location
        #     --disable-pip-version-check

        # We delay the import just in case the bootstrap is borked.
        from pip._internal.operations.install.wheel import install_wheel
        from pip._internal.locations import get_scheme

        # We may to trick pip into installing into another version's directories.
        scheme = get_scheme(self.name, prefix=pkg.install_path)
        version = get_default_python().version
        src_python = '{}python{}.{}{}'.format(os.path.sep, sys.version_info[0],
                                              sys.version_info[1], os.path.sep)
        dst_python = '{}python{}.{}{}'.format(os.path.sep, version[0],
                                              version[1], os.path.sep)
        if src_python != dst_python:
            for k in 'platlib', 'purelib', 'headers', 'scripts', 'data':
                setattr(scheme, k,
                        getattr(scheme, k).replace(src_python, dst_python))

        req = DummyPipRequirement()
        req.name = wheel_name
        install_wheel(pkg.name, pkg.package_path, scheme,
                      '<VEE dummy request>')
Esempio n. 6
0
def get_lib_location_guesses(
        user=False,  # type: bool
        home=None,  # type: Optional[str]
        root=None,  # type: Optional[str]
        isolated=False,  # type: bool
        prefix=None  # type: Optional[str]
):
    # type:(...) -> List[str]
    scheme = get_scheme(
        '',
        user=user,
        home=home,
        root=root,
        isolated=isolated,
        prefix=prefix,
    )
    return [scheme.purelib, scheme.platlib]
Esempio n. 7
0
 def install(
     self,
     install_options,  # type: List[str]
     global_options=None,  # type: Optional[Sequence[str]]
     root=None,  # type: Optional[str]
     home=None,  # type: Optional[str]
     prefix=None,  # type: Optional[str]
     warn_script_location=True,  # type: bool
     use_user_site=False,  # type: bool
     pycompile=True  # type: bool
 ):
     # type: (...) -> None
     scheme = get_scheme(
         self.name,
         user=use_user_site,
         home=home,
         root=root,
         isolated=self.isolated,
         prefix=prefix,
     )
Esempio n. 8
0
    def test_install_prefix(self, data, tmpdir):
        prefix = os.path.join(os.path.sep, 'some', 'path')
        self.prep(data, tmpdir)
        scheme = get_scheme(
            self.name,
            user=False,
            home=None,
            root=tmpdir,
            isolated=False,
            prefix=prefix,
        )
        wheel.install_wheel(
            self.name,
            self.wheelpath,
            scheme=scheme,
            req_description=str(self.req),
        )

        bin_dir = 'Scripts' if WINDOWS else 'bin'
        assert os.path.exists(os.path.join(tmpdir, 'some', 'path', bin_dir))
        assert os.path.exists(os.path.join(tmpdir, 'some', 'path', 'my_data'))
Esempio n. 9
0
    def test_install_prefix(self, data: TestData, tmpdir: Path) -> None:
        prefix = os.path.join(os.path.sep, "some", "path")
        self.prep(data, tmpdir)
        scheme = get_scheme(
            self.name,
            user=False,
            home=None,
            root=str(
                tmpdir),  # Casting needed for CPython 3.10+. See GH-10358.
            isolated=False,
            prefix=prefix,
        )
        wheel.install_wheel(
            self.name,
            self.wheelpath,
            scheme=scheme,
            req_description=str(self.req),
        )

        bin_dir = "Scripts" if WINDOWS else "bin"
        assert os.path.exists(os.path.join(tmpdir, "some", "path", bin_dir))
        assert os.path.exists(os.path.join(tmpdir, "some", "path", "my_data"))
Esempio n. 10
0
    def install(
        self,
        install_options,  # type: List[str]
        global_options=None,  # type: Optional[Sequence[str]]
        root=None,  # type: Optional[str]
        home=None,  # type: Optional[str]
        prefix=None,  # type: Optional[str]
        warn_script_location=True,  # type: bool
        use_user_site=False,  # type: bool
        pycompile=True  # type: bool
    ):
        # type: (...) -> None
        scheme = get_scheme(
            self.name,
            user=use_user_site,
            home=home,
            root=root,
            isolated=self.isolated,
            prefix=prefix,
        )

        global_options = global_options if global_options is not None else []
        if self.editable:
            self.install_editable(
                install_options,
                global_options,
                prefix=prefix,
                home=home,
                use_user_site=use_user_site,
            )
            return

        if self.is_wheel:
            self.move_wheel_files(
                self.source_dir,
                scheme=scheme,
                warn_script_location=warn_script_location,
                pycompile=pycompile,
            )
            self.install_succeeded = True
            return

        # Extend the list of global and install options passed on to
        # the setup.py call with the ones from the requirements file.
        # Options specified in requirements file override those
        # specified on the command line, since the last option given
        # to setup.py is the one that is used.
        global_options = list(global_options) + \
            self.options.get('global_options', [])
        install_options = list(install_options) + \
            self.options.get('install_options', [])

        header_dir = scheme.headers

        with TempDirectory(kind="record") as temp_dir:
            record_filename = os.path.join(temp_dir.path, 'install-record.txt')
            install_args = make_setuptools_install_args(
                self.setup_py_path,
                global_options=global_options,
                install_options=install_options,
                record_filename=record_filename,
                root=root,
                prefix=prefix,
                header_dir=header_dir,
                home=home,
                use_user_site=use_user_site,
                no_user_config=self.isolated,
                pycompile=pycompile,
            )

            runner = runner_with_spinner_message(
                "Running setup.py install for {}".format(self.name)
            )
            with indent_log(), self.build_env:
                runner(
                    cmd=install_args,
                    cwd=self.unpacked_source_directory,
                )

            if not os.path.exists(record_filename):
                logger.debug('Record file %s not found', record_filename)
                return
            self.install_succeeded = True

            def prepend_root(path):
                # type: (str) -> str
                if root is None or not os.path.isabs(path):
                    return path
                else:
                    return change_root(root, path)

            with open(record_filename) as f:
                for line in f:
                    directory = os.path.dirname(line)
                    if directory.endswith('.egg-info'):
                        egg_info_dir = prepend_root(directory)
                        break
                else:
                    deprecated(
                        reason=(
                            "{} did not indicate that it installed an "
                            ".egg-info directory. Only setup.py projects "
                            "generating .egg-info directories are supported."
                        ).format(self),
                        replacement=(
                            "for maintainers: updating the setup.py of {0}. "
                            "For users: contact the maintainers of {0} to let "
                            "them know to update their setup.py.".format(
                                self.name
                            )
                        ),
                        gone_in="20.2",
                        issue=6998,
                    )
                    # FIXME: put the record somewhere
                    return
            new_lines = []
            with open(record_filename) as f:
                for line in f:
                    filename = line.strip()
                    if os.path.isdir(filename):
                        filename += os.path.sep
                    new_lines.append(
                        os.path.relpath(prepend_root(filename), egg_info_dir)
                    )
            new_lines.sort()
            ensure_dir(egg_info_dir)
            inst_files_path = os.path.join(egg_info_dir, 'installed-files.txt')
            with open(inst_files_path, 'w') as f:
                f.write('\n'.join(new_lines) + '\n')
Esempio n. 11
0
    def install(
            self,
            install_options,  # type: List[str]
            global_options=None,  # type: Optional[Sequence[str]]
            root=None,  # type: Optional[str]
            home=None,  # type: Optional[str]
            prefix=None,  # type: Optional[str]
            warn_script_location=True,  # type: bool
            use_user_site=False,  # type: bool
            pycompile=True  # type: bool
    ):
        # type: (...) -> None
        scheme = get_scheme(
            self.name,
            user=use_user_site,
            home=home,
            root=root,
            isolated=self.isolated,
            prefix=prefix,
        )

        global_options = global_options if global_options is not None else []
        if self.editable:
            install_editable_legacy(
                install_options,
                global_options,
                prefix=prefix,
                home=home,
                use_user_site=use_user_site,
                name=self.name,
                setup_py_path=self.setup_py_path,
                isolated=self.isolated,
                build_env=self.build_env,
                unpacked_source_directory=self.unpacked_source_directory,
            )
            self.install_succeeded = True
            return

        if self.is_wheel:
            assert self.local_file_path
            direct_url = None
            if self.original_link:
                direct_url = direct_url_from_link(
                    self.original_link,
                    self.source_dir,
                    self.original_link_is_in_wheel_cache,
                )
            install_wheel(
                self.name,
                self.local_file_path,
                scheme=scheme,
                req_description=str(self.req),
                pycompile=pycompile,
                warn_script_location=warn_script_location,
                direct_url=direct_url,
            )
            self.install_succeeded = True
            return

        # TODO: Why don't we do this for editable installs?

        # Extend the list of global and install options passed on to
        # the setup.py call with the ones from the requirements file.
        # Options specified in requirements file override those
        # specified on the command line, since the last option given
        # to setup.py is the one that is used.
        global_options = list(global_options) + self.global_options
        install_options = list(install_options) + self.install_options

        try:
            success = install_legacy(
                install_options=install_options,
                global_options=global_options,
                root=root,
                home=home,
                prefix=prefix,
                use_user_site=use_user_site,
                pycompile=pycompile,
                scheme=scheme,
                setup_py_path=self.setup_py_path,
                isolated=self.isolated,
                req_name=self.name,
                build_env=self.build_env,
                unpacked_source_directory=self.unpacked_source_directory,
                req_description=str(self.req),
            )
        except LegacyInstallFailure as exc:
            self.install_succeeded = False
            six.reraise(*exc.parent)
        except Exception:
            self.install_succeeded = True
            raise

        self.install_succeeded = success
Esempio n. 12
0
def _get_scheme_dict(*args, **kwargs):
    scheme = get_scheme(*args, **kwargs)
    return {k: getattr(scheme, k) for k in SCHEME_KEYS}
Esempio n. 13
0
    def install(
            self,
            install_options,  # type: List[str]
            global_options=None,  # type: Optional[Sequence[str]]
            root=None,  # type: Optional[str]
            home=None,  # type: Optional[str]
            prefix=None,  # type: Optional[str]
            warn_script_location=True,  # type: bool
            use_user_site=False,  # type: bool
            pycompile=True  # type: bool
    ):
        # type: (...) -> None
        scheme = get_scheme(
            self.name,
            user=use_user_site,
            home=home,
            root=root,
            isolated=self.isolated,
            prefix=prefix,
        )

        global_options = global_options if global_options is not None else []
        if self.editable:
            install_editable_legacy(
                install_options,
                global_options,
                prefix=prefix,
                home=home,
                use_user_site=use_user_site,
                name=self.name,
                setup_py_path=self.setup_py_path,
                isolated=self.isolated,
                build_env=self.build_env,
                unpacked_source_directory=self.unpacked_source_directory,
            )
            self.install_succeeded = True
            return

        if self.is_wheel:
            assert self.local_file_path
            install_wheel(
                self.name,
                self.local_file_path,
                scheme=scheme,
                req_description=str(self.req),
                pycompile=pycompile,
                warn_script_location=warn_script_location,
            )
            self.install_succeeded = True
            return

        install_legacy(
            self,
            install_options=install_options,
            global_options=global_options,
            root=root,
            home=home,
            prefix=prefix,
            use_user_site=use_user_site,
            pycompile=pycompile,
            scheme=scheme,
        )
    def install(
        self,
        install_options,  # type: List[str]
        global_options=None,  # type: Optional[Sequence[str]]
        root=None,  # type: Optional[str]
        home=None,  # type: Optional[str]
        prefix=None,  # type: Optional[str]
        warn_script_location=True,  # type: bool
        use_user_site=False,  # type: bool
        pycompile=True  # type: bool
    ):
        # type: (...) -> None
        scheme = get_scheme(
            name,
            user=use_user_site,
            home=home,
            root=root,
            isolated=isolated,
            prefix=prefix,
        )

        global_options = global_options if global_options is not None else []
        if editable:
            install_editable_legacy(
                install_options,
                global_options,
                prefix=prefix,
                home=home,
                use_user_site=use_user_site,
                name=name,
                setup_py_path=setup_py_path,
                isolated=isolated,
                build_env=build_env,
                unpacked_source_directory=unpacked_source_directory,
            )
            install_succeeded = True
            return

        if is_wheel:
            assert local_file_path
            direct_url = None
            if original_link:
                direct_url = direct_url_from_link(
                    original_link,
                    source_dir,
                    original_link_is_in_wheel_cache,
                )
            install_wheel(
                name,
                local_file_path,
                scheme=scheme,
                req_description=str(req),
                pycompile=pycompile,
                warn_script_location=warn_script_location,
                direct_url=direct_url,
                requested=user_supplied,
            )
            install_succeeded = True
            return

        # TODO: Why don't we do this for editable installs?

        # Extend the list of global and install options passed on to
        # the setup.py call with the ones from the requirements file.
        # Options specified in requirements file override those
        # specified on the command line, since the last option given
        # to setup.py is the one that is used.
        global_options = list(global_options) + global_options
        install_options = list(install_options) + install_options

        try:
            success = install_legacy(
                install_options=install_options,
                global_options=global_options,
                root=root,
                home=home,
                prefix=prefix,
                use_user_site=use_user_site,
                pycompile=pycompile,
                scheme=scheme,
                setup_py_path=setup_py_path,
                isolated=isolated,
                req_name=name,
                build_env=build_env,
                unpacked_source_directory=unpacked_source_directory,
                req_description=str(req),
            )
        except LegacyInstallFailure as exc:
            install_succeeded = False
            six.reraise(*exc.parent)
        except Exception:
            install_succeeded = True
            raise

        install_succeeded = success

        if success and legacy_install_reason == 8368:
            deprecated(
                reason=(
                    "{} was installed using the legacy 'setup.py install' "
                    "method, because a wheel could not be built for it.".
                    format(name)
                ),
                replacement="to fix the wheel build issue reported above",
                gone_in="21.0",
                issue=8368,
            )
Esempio n. 15
0
    def install(
        self,
        install_options: List[str],
        global_options: Optional[Sequence[str]] = None,
        root: Optional[str] = None,
        home: Optional[str] = None,
        prefix: Optional[str] = None,
        warn_script_location: bool = True,
        use_user_site: bool = False,
        pycompile: bool = True,
    ) -> None:
        scheme = get_scheme(
            self.name,
            user=use_user_site,
            home=home,
            root=root,
            isolated=self.isolated,
            prefix=prefix,
        )

        global_options = global_options if global_options is not None else []
        if self.editable and not self.is_wheel:
            install_editable_legacy(
                install_options,
                global_options,
                prefix=prefix,
                home=home,
                use_user_site=use_user_site,
                name=self.name,
                setup_py_path=self.setup_py_path,
                isolated=self.isolated,
                build_env=self.build_env,
                unpacked_source_directory=self.unpacked_source_directory,
            )
            self.install_succeeded = True
            return

        if self.is_wheel:
            assert self.local_file_path
            direct_url = None
            # TODO this can be refactored to direct_url = self.download_info
            if self.editable:
                direct_url = direct_url_for_editable(
                    self.unpacked_source_directory)
            elif self.original_link:
                direct_url = direct_url_from_link(
                    self.original_link,
                    self.source_dir,
                    self.original_link_is_in_wheel_cache,
                )
            install_wheel(
                self.name,
                self.local_file_path,
                scheme=scheme,
                req_description=str(self.req),
                pycompile=pycompile,
                warn_script_location=warn_script_location,
                direct_url=direct_url,
                requested=self.user_supplied,
            )
            self.install_succeeded = True
            return

        # TODO: Why don't we do this for editable installs?

        # Extend the list of global and install options passed on to
        # the setup.py call with the ones from the requirements file.
        # Options specified in requirements file override those
        # specified on the command line, since the last option given
        # to setup.py is the one that is used.
        global_options = list(global_options) + self.global_options
        install_options = list(install_options) + self.install_options

        try:
            success = install_legacy(
                install_options=install_options,
                global_options=global_options,
                root=root,
                home=home,
                prefix=prefix,
                use_user_site=use_user_site,
                pycompile=pycompile,
                scheme=scheme,
                setup_py_path=self.setup_py_path,
                isolated=self.isolated,
                req_name=self.name,
                build_env=self.build_env,
                unpacked_source_directory=self.unpacked_source_directory,
                req_description=str(self.req),
            )
        except LegacyInstallFailure as exc:
            self.install_succeeded = False
            raise exc
        except Exception:
            self.install_succeeded = True
            raise

        self.install_succeeded = success

        if success and self.legacy_install_reason == 8368:
            deprecated(
                reason=("{} was installed using the legacy 'setup.py install' "
                        "method, because a wheel could not be built for it.".
                        format(self.name)),
                replacement="to fix the wheel build issue reported above",
                gone_in=None,
                issue=8368,
            )
Esempio n. 16
0
    def __wheelInstall(self, name: str, filewhl: str) -> bool:
        """
            Install .whl package

            Parameters
            ----------
                name : str
                    name of package
                filewhl : str
                    path of package file

            Returns
            -------
            bool
                whether the package is installed

            >>> __wheelInstall("package", "/tmp/packsX/package.whl")
            False

            >>> __wheelInstall("package", "/tmp/packsX/package.whl")
            True

        """

        try:
            pack = pr.get_distribution(name)

        except Exception:
            scheme = get_scheme(
                name,
                user=False,
                home=None,
                root=None,
                prefix=None,
            )

            install_wheel(
                name,
                filewhl,
                scheme=scheme,
                req_description=name,
                pycompile=True,
            )

            return False

        if self.__u:
            removeDependency(f"{pack.key}=={pack.version}")

            scheme = get_scheme(
                name,
                user=False,
                home=None,
                root=None,
                prefix=None,
            )

            install_wheel(
                name,
                filewhl,
                scheme=scheme,
                req_description=name,
                pycompile=True,
            )

            return False

        return True
Esempio n. 17
0
def _get_scheme_dict(*args: Any, **kwargs: Any) -> Dict[str, str]:
    scheme = get_scheme(*args, **kwargs)
    return {k: getattr(scheme, k) for k in SCHEME_KEYS}