fix(bzlmod pip): ensure that sub-modules do not have invalid repos (#1549)
This fixes the cases where the 'default_version' is passed to the
'render_pkg_aliases' utility but the 'default_version' is not present
for the wheels. This usually happens when a sub-module is using the
'pip.parse' extension and the default_version can only be set by the
root module.
Previously, such a case would generate a `select()` expression that
mapped
the default condition to a non-existent target (because the sub-module
didn't
call `pip.parse()` with that version). This would either result in
errors
due the target not existing, or silently using a target intended for a
different Python version (which may work, but isn't correct to so).
Now, it results in a error via `select.no_match_error`.
Fixes #1548.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a3ea068..eb5b692 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -86,6 +86,10 @@
* (gazelle) Generate a single `py_test` target when `gazelle:python_generation_mode project`
is used.
+* (bzlmod) sub-modules now don't have the `//conditions:default` clause in the
+ hub repos created by `pip.parse`. This should fix confusing error messages
+ in case there is a misconfiguration of toolchains or a bug in `rules_python`.
+
### Added
* (bzlmod) Added `.whl` patching support via `patches` and `patch_strip`
diff --git a/python/private/render_pkg_aliases.bzl b/python/private/render_pkg_aliases.bzl
index bcbfc8c..9ebbc36 100644
--- a/python/private/render_pkg_aliases.bzl
+++ b/python/private/render_pkg_aliases.bzl
@@ -109,7 +109,11 @@
if versions:
versions = sorted(versions)
- if versions and not default_version:
+ if not versions:
+ pass
+ elif default_version in versions:
+ pass
+ else:
error_msg = NO_MATCH_ERROR_MESSAGE_TEMPLATE.format(
supported_versions = ", ".join(versions),
rules_python = rules_python,
@@ -119,6 +123,10 @@
error_msg = error_msg,
))
+ # This is to simplify the code in _render_whl_library_alias and to ensure
+ # that we don't pass a 'default_version' that is not in 'versions'.
+ default_version = None
+
lines.append(
render.alias(
name = name,
diff --git a/tests/pip_hub_repository/render_pkg_aliases/render_pkg_aliases_test.bzl b/tests/pip_hub_repository/render_pkg_aliases/render_pkg_aliases_test.bzl
index 28d95ff..dff7cd0 100644
--- a/tests/pip_hub_repository/render_pkg_aliases/render_pkg_aliases_test.bzl
+++ b/tests/pip_hub_repository/render_pkg_aliases/render_pkg_aliases_test.bzl
@@ -222,6 +222,93 @@
_tests.append(_test_bzlmod_aliases_with_no_default_version)
+def _test_bzlmod_aliases_for_non_root_modules(env):
+ actual = render_pkg_aliases(
+ default_version = "3.2.4",
+ repo_name = "pypi",
+ rules_python = "rules_python",
+ whl_map = {
+ "bar-baz": ["3.2.3", "3.1.3"],
+ },
+ )
+
+ want_key = "bar_baz/BUILD.bazel"
+ want_content = """\
+package(default_visibility = ["//visibility:public"])
+
+_NO_MATCH_ERROR = \"\"\"\\
+No matching wheel for current configuration's Python version.
+
+The current build configuration's Python version doesn't match any of the Python
+versions available for this wheel. This wheel supports the following Python versions:
+ 3.1.3, 3.2.3
+
+As matched by the `@rules_python//python/config_settings:is_python_<version>`
+configuration settings.
+
+To determine the current configuration's Python version, run:
+ `bazel config <config id>` (shown further below)
+and look for
+ rules_python//python/config_settings:python_version
+
+If the value is missing, then the "default" Python version is being used,
+which has a "null" version value and will not match version constraints.
+\"\"\"
+
+alias(
+ name = "bar_baz",
+ actual = ":pkg",
+)
+
+alias(
+ name = "pkg",
+ actual = select(
+ {
+ "@@rules_python//python/config_settings:is_python_3.1.3": "@pypi_31_bar_baz//:pkg",
+ "@@rules_python//python/config_settings:is_python_3.2.3": "@pypi_32_bar_baz//:pkg",
+ },
+ no_match_error = _NO_MATCH_ERROR,
+ ),
+)
+
+alias(
+ name = "whl",
+ actual = select(
+ {
+ "@@rules_python//python/config_settings:is_python_3.1.3": "@pypi_31_bar_baz//:whl",
+ "@@rules_python//python/config_settings:is_python_3.2.3": "@pypi_32_bar_baz//:whl",
+ },
+ no_match_error = _NO_MATCH_ERROR,
+ ),
+)
+
+alias(
+ name = "data",
+ actual = select(
+ {
+ "@@rules_python//python/config_settings:is_python_3.1.3": "@pypi_31_bar_baz//:data",
+ "@@rules_python//python/config_settings:is_python_3.2.3": "@pypi_32_bar_baz//:data",
+ },
+ no_match_error = _NO_MATCH_ERROR,
+ ),
+)
+
+alias(
+ name = "dist_info",
+ actual = select(
+ {
+ "@@rules_python//python/config_settings:is_python_3.1.3": "@pypi_31_bar_baz//:dist_info",
+ "@@rules_python//python/config_settings:is_python_3.2.3": "@pypi_32_bar_baz//:dist_info",
+ },
+ no_match_error = _NO_MATCH_ERROR,
+ ),
+)"""
+
+ env.expect.that_collection(actual.keys()).contains_exactly([want_key])
+ env.expect.that_str(actual[want_key]).equals(want_content)
+
+_tests.append(_test_bzlmod_aliases_for_non_root_modules)
+
def _test_bzlmod_aliases_are_created_for_all_wheels(env):
actual = render_pkg_aliases(
default_version = "3.2.3",