Exemplo n.º 1
0
def test_from_link_archive() -> None:
    direct_url = direct_url_from_link(Link("https://g.c/archive.tgz"))
    assert direct_url.url == "https://g.c/archive.tgz"
    assert isinstance(direct_url.info, ArchiveInfo)
    direct_url = direct_url_from_link(
        Link("https://g.c/archive.tgz#sha1=1b8c5bc61a86f377fea47b4276c8c8a5842d2220")
    )
    assert isinstance(direct_url.info, ArchiveInfo)
    assert direct_url.info.hash == "sha1=1b8c5bc61a86f377fea47b4276c8c8a5842d2220"
Exemplo n.º 2
0
def test_from_link_hide_user_password() -> None:
    # Basic test only here, other variants are covered by
    # direct_url.redact_url tests.
    direct_url = direct_url_from_link(
        Link("git+https://user:[email protected]/u/p.git@branch#egg=pkg"),
        link_is_in_wheel_cache=True,
    )
    assert direct_url.to_dict()["url"] == "https://g.c/u/p.git"
    direct_url = direct_url_from_link(
        Link("git+ssh://[email protected]/u/p.git@branch#egg=pkg"),
        link_is_in_wheel_cache=True,
    )
    assert direct_url.to_dict()["url"] == "ssh://[email protected]/u/p.git"
Exemplo n.º 3
0
    def _populate_link(self, req: InstallRequirement) -> None:
        """Ensure that if a link can be found for this, that it is found.

        Note that req.link may still be None - if the requirement is already
        installed and not needed to be upgraded based on the return value of
        _is_upgrade_allowed().

        If preparer.require_hashes is True, don't use the wheel cache, because
        cached wheels, always built locally, have different hashes than the
        files downloaded from the index server and thus throw false hash
        mismatches. Furthermore, cached wheels at present have undeterministic
        contents due to file modification times.
        """
        if req.link is None:
            req.link = self._find_requirement_link(req)

        if self.wheel_cache is None or self.preparer.require_hashes:
            return
        cache_entry = self.wheel_cache.get_cache_entry(
            link=req.link,
            package_name=req.name,
            supported_tags=get_supported(),
        )
        if cache_entry is not None:
            logger.debug("Using cached wheel link: %s", cache_entry.link)
            if req.link is req.original_link and cache_entry.persistent:
                req.original_link_is_in_wheel_cache = True
            if cache_entry.origin is not None:
                req.download_info = cache_entry.origin
            else:
                # Legacy cache entry that does not have origin.json.
                # download_info may miss the archive_info.hash field.
                req.download_info = direct_url_from_link(
                    req.link, link_is_in_wheel_cache=cache_entry.persistent)
            req.link = cache_entry.link
Exemplo n.º 4
0
def test_from_link_vcs_without_source_dir(script: PipTestEnvironment) -> None:
    direct_url = direct_url_from_link(
        Link("git+https://g.c/u/p.git@1"), link_is_in_wheel_cache=True
    )
    assert direct_url.url == "https://g.c/u/p.git"
    assert isinstance(direct_url.info, VcsInfo)
    assert direct_url.info.commit_id == "1"
Exemplo n.º 5
0
    def _prepare_linked_requirement(self, req: InstallRequirement,
                                    parallel_builds: bool) -> BaseDistribution:
        assert req.link
        link = req.link

        self._ensure_link_req_src_dir(req, parallel_builds)
        hashes = self._get_linked_req_hashes(req)

        if link.is_existing_dir():
            local_file = None
        elif link.url not in self._downloaded:
            try:
                local_file = unpack_url(
                    link,
                    req.source_dir,
                    self._download,
                    self.verbosity,
                    self.download_dir,
                    hashes,
                )
            except NetworkConnectionError as exc:
                raise InstallationError(
                    "Could not install requirement {} because of HTTP "
                    "error {} for URL {}".format(req, exc, link))
        else:
            file_path = self._downloaded[link.url]
            if hashes:
                hashes.check_against_path(file_path)
            local_file = File(file_path, content_type=None)

        # If download_info is set, we got it from the wheel cache.
        if req.download_info is None:
            # Editables don't go through this function (see
            # prepare_editable_requirement).
            assert not req.editable
            req.download_info = direct_url_from_link(link, req.source_dir)
            # Make sure we have a hash in download_info. If we got it as part of the
            # URL, it will have been verified and we can rely on it. Otherwise we
            # compute it from the downloaded file.
            if (isinstance(req.download_info.info, ArchiveInfo)
                    and not req.download_info.info.hash and local_file):
                hash = hash_file(local_file.path)[0].hexdigest()
                req.download_info.info.hash = f"sha256={hash}"

        # For use in later processing,
        # preserve the file path on the requirement.
        if local_file:
            req.local_file_path = local_file.path

        dist = _get_prepared_distribution(
            req,
            self.build_tracker,
            self.finder,
            self.build_isolation,
            self.check_build_deps,
        )
        return dist
Exemplo n.º 6
0
def test_from_link_vcs_with_source_dir_obtains_commit_id(tmpdir: Path) -> None:
    repo_path = tmpdir / "test-repo"
    repo_path.mkdir()
    repo_dir = os.fspath(repo_path)
    Git.run_command(["init"], cwd=repo_dir)
    (repo_path / "somefile").touch()
    Git.run_command(["add", "."], cwd=repo_dir)
    Git.run_command(["commit", "-m", "commit msg"], cwd=repo_dir)
    commit_id = Git.get_revision(repo_dir)
    direct_url = direct_url_from_link(Link("git+https://g.c/u/p.git"),
                                      source_dir=repo_dir)
    assert direct_url.url == "https://g.c/u/p.git"
    assert isinstance(direct_url.info, VcsInfo)
    assert direct_url.info.commit_id == commit_id
Exemplo n.º 7
0
def test_from_link_vcs_with_source_dir_obtains_commit_id(script, tmpdir):
    repo_path = tmpdir / 'test-repo'
    repo_path.mkdir()
    repo_dir = str(repo_path)
    script.run('git', 'init', cwd=repo_dir)
    (repo_path / "somefile").touch()
    script.run('git', 'add', '.', cwd=repo_dir)
    script.run('git', 'commit', '-m', 'commit msg', cwd=repo_dir)
    commit_id = script.run('git', 'rev-parse', 'HEAD',
                           cwd=repo_dir).stdout.strip()
    direct_url = direct_url_from_link(Link("git+https://g.c/u/p.git"),
                                      source_dir=repo_dir)
    assert direct_url.url == "https://g.c/u/p.git"
    assert direct_url.info.commit_id == commit_id
Exemplo n.º 8
0
    def __init__(
        self,
        link: Link,
        template: InstallRequirement,
        factory: "Factory",
        name: Optional[NormalizedName] = None,
        version: Optional[CandidateVersion] = None,
    ) -> None:
        source_link = link
        cache_entry = factory.get_wheel_cache_entry(link, name)
        if cache_entry is not None:
            logger.debug("Using cached wheel link: %s", cache_entry.link)
            link = cache_entry.link
        ireq = make_install_req_from_link(link, template)
        assert ireq.link == link
        if ireq.link.is_wheel and not ireq.link.is_file:
            wheel = Wheel(ireq.link.filename)
            wheel_name = canonicalize_name(wheel.name)
            assert name == wheel_name, f"{name!r} != {wheel_name!r} for wheel"
            # Version may not be present for PEP 508 direct URLs
            if version is not None:
                wheel_version = Version(wheel.version)
                assert version == wheel_version, "{!r} != {!r} for wheel {}".format(
                    version, wheel_version, name
                )

        if cache_entry is not None:
            if cache_entry.persistent and template.link is template.original_link:
                ireq.original_link_is_in_wheel_cache = True
            if cache_entry.origin is not None:
                ireq.download_info = cache_entry.origin
            else:
                # Legacy cache entry that does not have origin.json.
                # download_info may miss the archive_info.hash field.
                ireq.download_info = direct_url_from_link(
                    source_link, link_is_in_wheel_cache=cache_entry.persistent
                )

        super().__init__(
            link=link,
            source_link=source_link,
            ireq=ireq,
            factory=factory,
            name=name,
            version=version,
        )
Exemplo n.º 9
0
def test_from_link_vcs_with_source_dir_obtains_commit_id(
    script: PipTestEnvironment, tmpdir: Path
) -> None:
    repo_path = tmpdir / "test-repo"
    repo_path.mkdir()
    repo_dir = str(repo_path)
    script.run("git", "init", cwd=repo_dir)
    (repo_path / "somefile").touch()
    script.run("git", "add", ".", cwd=repo_dir)
    script.run("git", "commit", "-m", "commit msg", cwd=repo_dir)
    commit_id = script.run("git", "rev-parse", "HEAD", cwd=repo_dir).stdout.strip()
    direct_url = direct_url_from_link(
        Link("git+https://g.c/u/p.git"), source_dir=repo_dir
    )
    assert direct_url.url == "https://g.c/u/p.git"
    assert isinstance(direct_url.info, VcsInfo)
    assert direct_url.info.commit_id == commit_id
Exemplo n.º 10
0
def test_from_link_dir(tmpdir: Path) -> None:
    dir_url = tmpdir.as_uri()
    direct_url = direct_url_from_link(Link(dir_url))
    assert direct_url.url == dir_url
    assert isinstance(direct_url.info, DirInfo)
Exemplo n.º 11
0
def test_from_link_dir(tmpdir):
    dir_url = path_to_url(tmpdir)
    direct_url = direct_url_from_link(Link(dir_url))
    assert direct_url.url == dir_url
    assert isinstance(direct_url.info, DirInfo)
Exemplo n.º 12
0
def test_from_link_vcs_without_source_dir(script, tmpdir):
    direct_url = direct_url_from_link(Link("git+https://g.c/u/p.git@1"),
                                      link_is_in_wheel_cache=True)
    assert direct_url.url == "https://g.c/u/p.git"
    assert direct_url.info.commit_id == "1"
Exemplo 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
            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
    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,
            )
Exemplo 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,
            )