Ejemplo n.º 1
0
 def test_std_install_with_direct_url(self, data, tmpdir):
     """Test that install_wheel creates direct_url.json metadata when
     provided with a direct_url argument. Also test that the RECORDS
     file contains an entry for direct_url.json in that case.
     Note direct_url.url is intentionally different from wheelpath,
     because wheelpath is typically the result of a local build.
     """
     self.prep(data, tmpdir)
     direct_url = DirectUrl(
         url="file:///home/user/archive.tgz",
         info=ArchiveInfo(),
     )
     wheel.install_wheel(
         self.name,
         self.wheelpath,
         scheme=self.scheme,
         req_description=str(self.req),
         direct_url=direct_url,
     )
     direct_url_path = os.path.join(
         self.dest_dist_info, DIRECT_URL_METADATA_NAME
     )
     self.assert_permission(direct_url_path, 0o644)
     with open(direct_url_path, 'rb') as f:
         expected_direct_url_json = direct_url.to_json()
         direct_url_json = f.read().decode("utf-8")
         assert direct_url_json == expected_direct_url_json
     # check that the direc_url file is part of RECORDS
     with open(os.path.join(self.dest_dist_info, "RECORD")) as f:
         assert DIRECT_URL_METADATA_NAME in f.read()
Ejemplo n.º 2
0
 def test_std_install(self, data, tmpdir):
     self.prep(data, tmpdir)
     wheel.install_wheel(
         self.name,
         self.wheelpath,
         scheme=self.scheme,
         req_description=str(self.req),
     )
     self.assert_installed()
Ejemplo n.º 3
0
 def test_std_install_requested(self, data: TestData, tmpdir: Path) -> None:
     self.prep(data, tmpdir)
     wheel.install_wheel(
         self.name,
         self.wheelpath,
         scheme=self.scheme,
         req_description=str(self.req),
         requested=True,
     )
     self.assert_installed(0o644)
     requested_path = os.path.join(self.dest_dist_info, "REQUESTED")
     assert os.path.isfile(requested_path)
Ejemplo n.º 4
0
 def test_dist_info_contains_empty_dir(self, data, tmpdir):
     """
     Test that empty dirs are not installed
     """
     # e.g. https://github.com/pypa/pip/issues/1632#issuecomment-38027275
     self.prep(data, tmpdir)
     wheel.install_wheel(
         self.name,
         self.wheelpath,
         scheme=self.scheme,
         req_description=str(self.req),
     )
     self.assert_installed(0o644)
     assert not os.path.isdir(os.path.join(self.dest_dist_info,
                                           'empty_dir'))
Ejemplo n.º 5
0
    def test_wheel_install_rejects_bad_paths(self, data, tmpdir, path):
        self.prep(data, tmpdir)
        wheel_path = make_wheel(
            "simple", "0.1.0", extra_files={path: "example contents\n"}
        ).save_to_dir(tmpdir)
        with pytest.raises(InstallationError) as e:
            wheel.install_wheel(
                "simple",
                str(wheel_path),
                scheme=self.scheme,
                req_description="simple",
            )

        exc_text = str(e.value)
        assert os.path.basename(wheel_path) in exc_text
        assert "example" in exc_text
Ejemplo n.º 6
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>')
Ejemplo n.º 7
0
    def test_std_install_with_custom_umask(self, data, tmpdir, user_mask,
                                           expected_permission):
        """Test that the files created after install honor the permissions
        set when the user sets a custom umask"""

        prev_umask = os.umask(user_mask)
        try:
            self.prep(data, tmpdir)
            wheel.install_wheel(
                self.name,
                self.wheelpath,
                scheme=self.scheme,
                req_description=str(self.req),
            )
            self.assert_installed(expected_permission)
        finally:
            os.umask(prev_umask)
Ejemplo n.º 8
0
    def test_invalid_entrypoints_fail(
        self, data, tmpdir, entrypoint, entrypoint_type
    ):
        self.prep(data, tmpdir)
        wheel_path = make_wheel(
            "simple", "0.1.0", entry_points={entrypoint_type: [entrypoint]}
        ).save_to_dir(tmpdir)
        with pytest.raises(InstallationError) as e:
            wheel.install_wheel(
                "simple",
                str(wheel_path),
                scheme=self.scheme,
                req_description="simple",
            )

        exc_text = str(e.value)
        assert os.path.basename(wheel_path) in exc_text
        assert entrypoint in exc_text
Ejemplo n.º 9
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'))
Ejemplo n.º 10
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"))
Ejemplo 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
Ejemplo n.º 12
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,
            )
Ejemplo n.º 14
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,
            )
Ejemplo n.º 15
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
Ejemplo n.º 16
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

        # 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

            # We intentionally do not use any encoding to read the file because
            # setuptools writes the file using distutils.file_util.write_file,
            # which does not specify an encoding.
            with open(record_filename) as f:
                record_lines = f.read().splitlines()

        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)

        for line in record_lines:
            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 = []
        for line in record_lines:
            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')