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.
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] = [
req
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 https://github.com/pypa/pip/issues/4086
# 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
try:
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(req.name)
if not req_is_needed(req):
continue
if req_name in versions:
if not req.specifier.contains(versions[req_name], prereleases=True):
print_err(
f"{package} {version} requires {req}, "
f"but {versions[req_name]} is installed"
)
continue
print_err(f"{package} {version} is missing requirement {req}")