Lightweight alternative to `pip check`?

In Nixpkgs we recently made the migration from using pip for building and installing wheels to using build and installer. It was only after that we realized that installer does not actually check whether runtime dependencies are met.

Is there any lightweight alternative to what pip does for checking runtime dependencies?

I had the same question while working on this problem in conda. For me, it would even help if someone could point me where the logic for pip check is hidden in pip’s source code. Code search/navigation didn’t help me much.

1 Like

It’s pretty easy to write your own using importlib.metadata and packaging. Here’s something I wrote a long time ago but probably still works well:

def check_dependency_issues() -> None:
    # This is very similar to `pip check`
    versions = {}
    reqs = {}
    for dist in importlib.metadata.distributions():
        metadata = dist.metadata
        name = canonical_name(metadata["Name"])
        versions[name] = packaging.version.parse(metadata["Version"])
        reqs[name] = [
            for r in (dist.requires or [])
            if (req := packaging.requirements.Requirement(r)) is not None

    # Like `pip check`, we don't handle extras very well
    # This is because there's no way to tell if an extra was requested. If we wanted, we could
    # do slightly better than pip by finding all requirements that require an extra and using that
    # as a heuristic to tell if an extra was requested.

    def req_is_needed(req: packaging.requirements.Requirement) -> bool:
        if req.marker is None:
            return True
            return req.marker.evaluate()
        except packaging.markers.UndefinedEnvironmentName:
            # likely because the req has an extra
            return False

    for package, version in versions.items():
        for req in reqs[package]:
            req_name = canonical_name(

            if not req_is_needed(req):

            if req_name in versions:
                if not req.specifier.contains(versions[req_name], prereleases=True):
                        f"{package} {version} requires {req}, "
                        f"but {versions[req_name]} is installed"

            print_err(f"{package} {version} is missing requirement {req}")

Looks like the core of the code is and the entrypoint is


Looking at the code for pip and build, I’m wondering if I am over-complicating things here?