From 9729c813780ff7a8b1ae2454b3a54b182419c0d7 Mon Sep 17 00:00:00 2001 From: Kristian Hartikainen Date: Mon, 21 Sep 2026 22:49:38 +0000 Subject: [PATCH 1/2] fix(pypi): include platform-specific packages in unified hub Use each hub's full wheel map when creating unified aliases so that platform-specific requirements resolve on supported platforms. --- news/unified-platform-packages.fixed.md | 2 ++ python/private/pypi/extension.bzl | 2 +- tests/integration/unified_pypi/BUILD.bazel | 16 ++++++++++++++ tests/integration/unified_pypi/MODULE.bazel | 13 ++++++++++-- .../requirements_b_without_six.txt | 3 +++ tests/integration/unified_pypi_test.py | 21 +++++++++++++++++++ 6 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 news/unified-platform-packages.fixed.md create mode 100644 tests/integration/unified_pypi/requirements_b_without_six.txt diff --git a/news/unified-platform-packages.fixed.md b/news/unified-platform-packages.fixed.md new file mode 100644 index 0000000000..4e99394f83 --- /dev/null +++ b/news/unified-platform-packages.fixed.md @@ -0,0 +1,2 @@ +(pypi) Include platform-specific packages in the unified `@pypi` hub so that +their aliases resolve on supported target platforms. diff --git a/python/private/pypi/extension.bzl b/python/private/pypi/extension.bzl index cafe245eb2..952c65755f 100644 --- a/python/private/pypi/extension.bzl +++ b/python/private/pypi/extension.bzl @@ -505,7 +505,7 @@ def _create_unified_hub_repo(mods): extra_aliases = {} for hub_name in hubs: - for pkg_name in mods.exposed_packages.get(hub_name, []): + for pkg_name in mods.hub_whl_map[hub_name]: norm_pkg = normalize_name(pkg_name) if norm_pkg not in packages: packages[norm_pkg] = [] diff --git a/tests/integration/unified_pypi/BUILD.bazel b/tests/integration/unified_pypi/BUILD.bazel index c0b9905fa6..19a8a1925c 100644 --- a/tests/integration/unified_pypi/BUILD.bazel +++ b/tests/integration/unified_pypi/BUILD.bazel @@ -59,3 +59,19 @@ py_binary( main = "bin_declared_only.py", deps = ["@pypi//declared_only_pkg:declared-only-alias"], ) + +platform( + name = "linux_x86_64", + constraint_values = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], +) + +platform( + name = "windows_x86_64", + constraint_values = [ + "@platforms//cpu:x86_64", + "@platforms//os:windows", + ], +) diff --git a/tests/integration/unified_pypi/MODULE.bazel b/tests/integration/unified_pypi/MODULE.bazel index 6a4b87e015..f8e1589d69 100644 --- a/tests/integration/unified_pypi/MODULE.bazel +++ b/tests/integration/unified_pypi/MODULE.bazel @@ -1,5 +1,6 @@ module(name = "unified_pypi") +bazel_dep(name = "platforms", version = "0.0.11") bazel_dep(name = "rules_python", version = "0.0.0") local_path_override( module_name = "rules_python", @@ -36,11 +37,19 @@ pip.parse( ) use_repo(pip, "pypi_a") -# pypi_b has colorama and six, and acts as designated fallback +# `pypi_b` supplies `six` only on Linux and is the fallback hub. pip.parse( hub_name = "pypi_b", python_version = "3.11", - requirements_lock = "//:requirements_b.txt", + requirements_by_platform = { + "//:requirements_b.txt": "linux_*", + "//:requirements_b_without_six.txt": "osx_*,windows_*", + }, + target_platforms = [ + "{os}_{arch}", + "linux_x86_64", + "windows_x86_64", + ], ) use_repo(pip, "pypi_b") diff --git a/tests/integration/unified_pypi/requirements_b_without_six.txt b/tests/integration/unified_pypi/requirements_b_without_six.txt new file mode 100644 index 0000000000..ab5f031951 --- /dev/null +++ b/tests/integration/unified_pypi/requirements_b_without_six.txt @@ -0,0 +1,3 @@ +colorama==0.4.5 \ + --hash=sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da \ + --hash=sha256:e6c6b4334fc50988a639d9b98ae42f5c90ec94cb1495b4fe76c5f72cf7f79435 diff --git a/tests/integration/unified_pypi_test.py b/tests/integration/unified_pypi_test.py index a19a9fcfbe..38e198f131 100644 --- a/tests/integration/unified_pypi_test.py +++ b/tests/integration/unified_pypi_test.py @@ -20,6 +20,27 @@ def test_cli_override(self): "//:test_cli", ) + def test_platform_specific_package(self): + for hub in ("auto", "pypi_b"): + with self.subTest(hub=hub): + self.run_bazel( + "build", + "--platforms=//:linux_x86_64", + f"--@rules_python//python/config_settings:venv={hub}", + "@pypi//six", + "@pypi//six:whl", + ) + + def test_platform_specific_package_rejects_unsupported_platform(self): + result = self.run_bazel( + "cquery", + "--platforms=//:windows_x86_64", + "@pypi//six", + check=False, + ) + self.assertNotEqual(result.exit_code, 0) + self.assert_result_matches(result, "No matching wheel") + def test_disjoint_package_cquery_succeeds_but_build_fails(self): self.run_bazel("cquery", "//:bin_six_a") result = self.run_bazel("build", "//:bin_six_a", check=False) From 80da4db39bc735c6d9a907d0f22212ae97108308 Mon Sep 17 00:00:00 2001 From: Kristian Hartikainen Date: Tue, 22 Sep 2026 13:20:54 -0400 Subject: [PATCH 2/2] Update documentation for platform-specific packages Clarified the inclusion of platform-specific packages in the unified @pypi hub for alias resolution on supported platforms. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- news/unified-platform-packages.fixed.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/news/unified-platform-packages.fixed.md b/news/unified-platform-packages.fixed.md index 4e99394f83..bfcbdd9df1 100644 --- a/news/unified-platform-packages.fixed.md +++ b/news/unified-platform-packages.fixed.md @@ -1,2 +1,3 @@ -(pypi) Include platform-specific packages in the unified `@pypi` hub so that -their aliases resolve on supported target platforms. +(pypi) Include platform-specific packages in the unified +`@pypi` hub so that their aliases resolve on supported target +platforms. ([#4171](https://github.com/bazel-contrib/rules_python/issues/4171))