Skip to content

build.check_dependency ignores URL reqs with names that match an installed distribution #860

Open
@gschaffner

Description

@gschaffner

When build.check_dependency sees a URL req with a name that matches an installed distribution, it considers the URL req met. For example:

import importlib.metadata

import build


def get_version(distribution_name: str) -> str | None:
    try:
        return importlib.metadata.version(distribution_name)
    except ModuleNotFoundError:
        return None


# Some version of packaging is installed:
packaging_ver = importlib.metadata.version("packaging")
assert packaging_ver is not None and packaging_ver != "24.1"
print(
    f"{tuple(build.check_dependency("packaging @ git+https://github.com/pypa/[email protected]")) = !r}"
)

# No version of sniffio is installed:
sniffio_ver = get_version("sniffio")
assert sniffio_ver is None
print(
    f"{tuple(build.check_dependency("sniffio @ git+https://github.com/python-trio/[email protected]")) = !r}"
)

Output (in a venv with packaging==24.2 and without sniffio):

tuple(build.check_dependency("packaging @ git+https://github.com/pypa/[email protected]")) = ()
tuple(build.check_dependency("sniffio @ git+https://github.com/python-trio/[email protected]")) = (('sniffio@ git+https://github.com/python-trio/[email protected]',),)

The packaging URL req is reported as met but it is not. The sniffio URL req is correctly reported as unmet.

With check_dependency's current documentation, this seems like a bug; it should be able to verify that URL reqs are met.

Is it possible via PEP 610?

     try:
         dist = importlib.metadata.distribution(req.name)
     except importlib.metadata.PackageNotFoundError:
         # dependency is not installed in the environment.
         yield (*ancestral_req_strings, normalised_req_string)
     else:
         if req.specifier and not req.specifier.contains(dist.version, prereleases=True):
             # the installed version is incompatible.
             yield (*ancestral_req_strings, normalised_req_string)
+        elif req.url and pseudocode(dist.origin != req.url):
+            yield (*ancestral_req_strings, normalised_req_string)
         elif dist.requires:
             for other_req_string in dist.requires:
                 # yields transitive dependencies that are not satisfied.
                 yield from check_dependency(other_req_string, (*ancestral_req_strings, normalised_req_string), req.extras)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions