Repository: pypa/pip
File: src/pip/_internal/resolution/resolvelib/candidates.py (Python)

Code before:
        try:
            list(dist.iter_dependencies(list(dist.iter_provided_extras())))
        except InvalidRequirement as e:
            raise MetadataInvalid(self._ireq, str(e))

    def _prepare(self) -> BaseDistribution:
        try:
            dist = self._prepare_distribution()
        except HashError as e:
            # Provide HashError the underlying ireq that caused it. This
            # provides context for the resulting error message to show the
            # offending line to the user.
            e.req = self._ireq
            raise
        except InstallationSubprocessError as exc:
            # The output has been presented already, so don't duplicate it.
            exc.context = "See above for output."
            raise

        self._check_metadata_consistency(dist)
        return dist

    def iter_dependencies(self, with_requires: bool) -> Iterable[Optional[Requirement]]:
        yield self._factory.make_requires_python_requirement(self.dist.requires_python)
        requires = self.dist.iter_dependencies() if with_requires else ()
        for r in requires:
            yield from self._factory.make_requirements_from_spec(str(r), self._ireq)

    def get_install_requirement(self) -> Optional[InstallRequirement]:
        return self._ireq


class LinkCandidate(_InstallRequirementBackedCandidate):
    is_editable = False

    def __init__(
        self,
        link: Link,
        template: InstallRequirement,
        factory: "Factory",
        name: Optional[NormalizedName] = None,
        version: Optional[Version] = None,
    ) -> None:
        source_link = link
        cache_entry = factory.get_wheel_cache_entry(source_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:

Review comment (performance):
Maybe add a comment here to explain that the order in which we yield the requirements is important, and putting requires-python first allows us to avoid more expensive checks where possible?

Code after:
        try:
            list(dist.iter_dependencies(list(dist.iter_provided_extras())))
        except InvalidRequirement as e:
            raise MetadataInvalid(self._ireq, str(e))

    def _prepare(self) -> BaseDistribution:
        try:
            dist = self._prepare_distribution()
        except HashError as e:
            # Provide HashError the underlying ireq that caused it. This
            # provides context for the resulting error message to show the
            # offending line to the user.
            e.req = self._ireq
            raise
        except InstallationSubprocessError as exc:
            # The output has been presented already, so don't duplicate it.
            exc.context = "See above for output."
            raise

        self._check_metadata_consistency(dist)
        return dist

    def iter_dependencies(self, with_requires: bool) -> Iterable[Optional[Requirement]]:
        # Emit the Requires-Python requirement first to fail fast on
        # unsupported candidates and avoid pointless downloads/preparation.
        yield self._factory.make_requires_python_requirement(self.dist.requires_python)
        requires = self.dist.iter_dependencies() if with_requires else ()
        for r in requires:
            yield from self._factory.make_requirements_from_spec(str(r), self._ireq)

    def get_install_requirement(self) -> Optional[InstallRequirement]:
        return self._ireq


class LinkCandidate(_InstallRequirementBackedCandidate):
    is_editable = False

    def __init__(
        self,
        link: Link,
        template: InstallRequirement,
        factory: "Factory",
        name: Optional[NormalizedName] = None,
        version: Optional[Version] = None,
    ) -> None:
        source_link = link
        cache_entry = factory.get_wheel_cache_entry(source_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)