Esempio n. 1
0
def test_requires_dists_none(pygoogleearth_zip_sdist):
    # type: (str) -> None
    assert [] == list(requires_dists(pygoogleearth_zip_sdist))
    with example_distribution("MarkupSafe-1.0-cp27-cp27mu-linux_x86_64.whl") as (wheel_path, dist):
        assert [] == list(requires_dists(wheel_path))
        assert [] == list(requires_dists(dist))

    # This tests a strange case detailed here:
    #   https://github.com/pantsbuild/pex/issues/1201#issuecomment-791715585
    with downloaded_sdist("et-xmlfile==1.0.1") as sdist, warnings.catch_warnings(
        record=True
    ) as events:
        assert [] == list(requires_dists(sdist))
        assert len(events) == 1
        warning = events[0]
        assert PEXWarning == warning.category
        assert (
            dedent(
                """\
                Ignoring 1 `Requires` field in {sdist} metadata:
                1.) Requires: python (>=2.6.0)

                You may have issues using the 'et_xmlfile' distribution as a result.
                More information on this workaround can be found here:
                  https://github.com/pantsbuild/pex/issues/1201#issuecomment-791715585
                """
            ).format(sdist=sdist)
            == str(warning.message)
        )
Esempio n. 2
0
def test_requires_dists():
    # type: () -> None
    with example_distribution("aws_cfn_bootstrap-1.4-py2-none-any.whl") as (wheel_path, dist):
        expected_requirements = [
            Requirement.parse(req)
            for req in ("python-daemon>=1.5.2,<2.0", "pystache>=0.4.0", "setuptools")
        ]
        assert expected_requirements == list(requires_dists(wheel_path))
        assert expected_requirements == list(requires_dists(dist))
Esempio n. 3
0
 def _info(
     self,
     pex,  # type: PEX
     options,  # type: Namespace
 ):
     # type: (...) -> Result
     with self._distributions_output(pex, options) as (distributions, output):
         for distribution in distributions:
             if options.verbose:
                 requires_python = dist_metadata.requires_python(distribution)
                 requires_dists = list(dist_metadata.requires_dists(distribution))
                 self.dump_json(
                     options,
                     dict(
                         project_name=distribution.project_name,
                         version=distribution.version,
                         requires_python=str(requires_python) if requires_python else None,
                         requires_dists=[str(dist) for dist in requires_dists],
                         location=distribution.location,
                     ),
                     output,
                 )
             else:
                 output.write(
                     "{project_name} {version} {location}".format(
                         project_name=distribution.project_name,
                         version=distribution.version,
                         location=distribution.location,
                     )
                 )
             output.write("\n")
     return Ok()
Esempio n. 4
0
def test_requires_dists():
    # type: () -> None
    with example_distribution(
            "aws_cfn_bootstrap-1.4-py2-none-any.whl") as dist:
        assert [
            Requirement.parse(req) for req in (
                "python-daemon>=1.5.2,<2.0",
                "pystache>=0.4.0",
                "setuptools",
            )
        ] == list(requires_dists(dist))
Esempio n. 5
0
 def _create_dependency_graph(pex):
     # type: (PEX) -> DiGraph
     graph = DiGraph(
         pex.path(),
         fontsize="14",
         labelloc="t",
         label="Dependency graph of {} for interpreter {} ({})".format(
             pex.path(), pex.interpreter.binary, pex.interpreter.identity.requirement
         ),
     )
     marker_environment = pex.interpreter.identity.env_markers.copy()
     marker_environment["extra"] = []
     present_dists = frozenset(dist.project_name for dist in pex.resolve())
     for dist in pex.resolve():
         graph.add_node(
             name=dist.project_name,
             label="{name} {version}".format(name=dist.project_name, version=dist.version),
             URL="https://pypi.org/project/{name}/{version}".format(
                 name=dist.project_name, version=dist.version
             ),
             target="_blank",
         )
         for req in requires_dists(dist):
             if (
                 req.project_name not in present_dists
                 and req.marker
                 and not req.marker.evaluate(environment=marker_environment)
             ):
                 graph.add_node(
                     name=req.project_name,
                     color="lightgrey",
                     style="filled",
                     tooltip="inactive requirement",
                     URL="https://pypi.org/project/{name}".format(name=req.project_name),
                     target="_blank",
                 )
             graph.add_edge(
                 start=dist.project_name,
                 end=req.project_name,
                 label="{specifier}{marker}".format(
                     specifier=req.specifier if req.specifier else "",
                     marker="; {}".format(req.marker) if req.marker else "",
                 )
                 if (req.specifier or req.marker)
                 else None,
                 fontsize="10",
             )
     return graph
Esempio n. 6
0
    def _resolve_requirement(
            self,
            requirement,  # type: Requirement
            resolved_dists_by_key,  # type: MutableMapping[Distribution, _RequirementKey]
            required,  # type: Optional[bool]
            required_by=None,  # type: Optional[Distribution]
    ):
        # type: (...) -> Iterator[_DistributionNotFound]
        requirement_key = _RequirementKey.create(requirement)
        if requirement_key in resolved_dists_by_key:
            return

        available_distributions = [
            ranked_dist
            for ranked_dist in self._available_ranked_dists_by_key.get(
                requirement.key, []) if ranked_dist.satisfies(requirement)
        ]
        if not available_distributions:
            if required is True:
                yield _DistributionNotFound.create(requirement,
                                                   required_by=required_by)
            return

        resolved_distribution = sorted(available_distributions,
                                       reverse=True)[0].distribution
        if len(available_distributions) > 1:
            TRACER.log(
                "Resolved {req} to {dist} and discarded {discarded}.".format(
                    req=requirement,
                    dist=resolved_distribution,
                    discarded=", ".join(
                        str(ranked_dist.distribution)
                        for ranked_dist in available_distributions[1:]),
                ),
                V=9,
            )

        for dep_requirement in dist_metadata.requires_dists(
                resolved_distribution):
            # A note regarding extras and why they're passed down one level (we don't pass / use
            # dep_requirement.extras for example):
            #
            # Say we're resolving the `requirement` 'requests[security]==2.25.1'. That means
            # `resolved_distribution` is the requests distribution. It will have metadata that
            # looks like so:
            #
            # $ grep Requires-Dist requests-2.25.1.dist-info/METADATA | grep security -C1
            # Requires-Dist: certifi (>=2017.4.17)
            # Requires-Dist: pyOpenSSL (>=0.14) ; extra == 'security'
            # Requires-Dist: cryptography (>=1.3.4) ; extra == 'security'
            # Requires-Dist: PySocks (!=1.5.7,>=1.5.6) ; extra == 'socks'
            #
            # We want to recurse and resolve all standard requests requirements but also those that
            # are part of the 'security' extra. In order to resolve the latter we need to include
            # the 'security' extra environment marker.
            required = self._evaluate_marker(dep_requirement,
                                             extras=requirement.extras)
            if required is False:
                continue

            for not_found in self._resolve_requirement(
                    dep_requirement,
                    resolved_dists_by_key,
                    required,
                    required_by=resolved_distribution,
            ):
                yield not_found

        resolved_dists_by_key.update(
            (key, resolved_distribution)
            for key in requirement_key.satisfied_keys())
Esempio n. 7
0
def test_requires_dists_none():
    # type: () -> None
    with example_distribution(
            "MarkupSafe-1.0-cp27-cp27mu-linux_x86_64.whl") as dist:
        assert [] == list(requires_dists(dist))
Esempio n. 8
0
def test_requires_dists_none(pygoogleearth_zip_sdist):
    # type: (str) -> None
    assert [] == list(requires_dists(pygoogleearth_zip_sdist))
    with example_distribution("MarkupSafe-1.0-cp27-cp27mu-linux_x86_64.whl") as (wheel_path, dist):
        assert [] == list(requires_dists(wheel_path))
        assert [] == list(requires_dists(dist))