diff --git a/news/3934.fixed.md b/news/3934.fixed.md new file mode 100644 index 0000000000..a30f475770 --- /dev/null +++ b/news/3934.fixed.md @@ -0,0 +1,7 @@ +(pypi) `pip.parse(uv_lock = ...)` no longer exposes uv workspace/root members +that resolve to no wheel or sdist (e.g. `source = { virtual = "." }` or editable +installs). Previously these source-less packages were added to the hub's +`all_requirements` / `all_whl_requirements` with an alias to a subpackage that +does not exist, breaking analysis for anything enumerating the full set such as +`modules_mapping(wheels = all_whl_requirements)` +([#3934](https://github.com/bazel-contrib/rules_python/issues/3934)). diff --git a/python/private/pypi/parse_requirements.bzl b/python/private/pypi/parse_requirements.bzl index be3ad9a5e5..648ec9e65c 100644 --- a/python/private/pypi/parse_requirements.bzl +++ b/python/private/pypi/parse_requirements.bzl @@ -292,7 +292,14 @@ def _parse_uv_lock_json(uv_lock, all_platforms, logger, extra_pip_args = None, p versions = sorted(info["versions"].keys()) item = struct( name = norm_name, - is_exposed = True, + # Only expose packages that resolved to at least one source. uv + # workspace/root members (e.g. `source = { virtual = "." }` or + # editable installs) resolve to no wheel/sdist, so exposing them + # would add a dangling entry to the hub's `all_requirements` / + # `all_whl_requirements` and create an alias to a subpackage that + # doesn't exist. This mirrors the requirements path, which also + # gates `is_exposed`. + is_exposed = bool(info["resolved_srcs"]), is_multiple_versions = len(versions) > 1, index_url = info["index_url"], srcs = info["resolved_srcs"], diff --git a/tests/pypi/parse_requirements/parse_requirements_tests.bzl b/tests/pypi/parse_requirements/parse_requirements_tests.bzl index 576a31ae5d..57b3ea5d3e 100644 --- a/tests/pypi/parse_requirements/parse_requirements_tests.bzl +++ b/tests/pypi/parse_requirements/parse_requirements_tests.bzl @@ -1193,7 +1193,7 @@ def _test_uv_lock_primary_source_includes_virtual(env): struct( name = "virtual_pkg", index_url = "", - is_exposed = True, + is_exposed = False, is_multiple_versions = False, srcs = [], ), @@ -1620,7 +1620,7 @@ def _test_uv_lock_requires_dist_extras(env): struct( name = "root_pkg", index_url = "", - is_exposed = True, + is_exposed = False, is_multiple_versions = False, srcs = [], ),