From 23cb11d934b5cef4230df966f665885755816b6b Mon Sep 17 00:00:00 2001 From: Richard Levasseur Date: Wed, 25 Jun 2025 13:14:36 -0700 Subject: [PATCH 1/8] fix: delete BUILD et al files from pypi sourced dependencies --- python/private/pypi/whl_library.bzl | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/python/private/pypi/whl_library.bzl b/python/private/pypi/whl_library.bzl index c271449b3d..601a5c0280 100644 --- a/python/private/pypi/whl_library.bzl +++ b/python/private/pypi/whl_library.bzl @@ -471,8 +471,26 @@ def _whl_library_impl(rctx): ], ) - rctx.file("BUILD.bazel", build_file_contents) + # Delete these in case the wheel had them. They generally don't cause + # a problem, but let's avoid the chance of that happening. + rctx.file("WORKSPACE") + rctx.file("WORKSPACE.bazel") + rctx.file("MODULE.bazel") + rctx.file("REPO.bazel") + + paths = list(rctx.path(".").readdir()) + for _ in range(10000000): + if not paths: + break + path = paths.pop() + + # BUILD files interfere with globbing and Bazel package boundaries. + if path.basename in ("BUILD", "BUILD.bazel"): + rctx.delete(path) + elif path.is_dir: + paths.extend(path.readdir()) + rctx.file("BUILD.bazel", build_file_contents) return def _generate_entry_point_contents( From 34a3090e8fa2c3eb55b4a6e7526f9796b4788f5a Mon Sep 17 00:00:00 2001 From: Richard Levasseur Date: Wed, 25 Jun 2025 14:06:16 -0700 Subject: [PATCH 2/8] add test --- MODULE.bazel | 2 + python/private/internal_dev_deps.bzl | 13 +++++++ python/private/pypi/whl_library.bzl | 1 + tests/support/whl_from_dir/BUILD.bazel | 0 .../whl_from_dir/whl_from_dir_repo.bzl | 38 +++++++++++++++++++ tests/whl_with_build_files/BUILD.bazel | 7 ++++ tests/whl_with_build_files/testdata/BUILD | 0 .../whl_with_build_files/testdata/BUILD.bazel | 0 .../testdata/somepkg-1.0.dist-info/BUILD | 0 .../somepkg-1.0.dist-info/BUILD.bazel | 0 .../testdata/somepkg-1.0.dist-info/METADATA | 0 .../testdata/somepkg-1.0.dist-info/RECORD | 0 .../testdata/somepkg-1.0.dist-info/WHEEL | 1 + .../testdata/somepkg/BUILD | 0 .../testdata/somepkg/BUILD.bazel | 0 .../testdata/somepkg/__init__.py | 0 .../testdata/somepkg/a.py | 0 .../testdata/somepkg/subpkg/BUILD | 0 .../testdata/somepkg/subpkg/BUILD.bazel | 0 .../testdata/somepkg/subpkg/__init__.py | 0 .../testdata/somepkg/subpkg/b.py | 0 .../whl_with_build_files/verify_files_test.py | 12 ++++++ 22 files changed, 74 insertions(+) create mode 100644 tests/support/whl_from_dir/BUILD.bazel create mode 100644 tests/support/whl_from_dir/whl_from_dir_repo.bzl create mode 100644 tests/whl_with_build_files/BUILD.bazel create mode 100644 tests/whl_with_build_files/testdata/BUILD create mode 100644 tests/whl_with_build_files/testdata/BUILD.bazel create mode 100644 tests/whl_with_build_files/testdata/somepkg-1.0.dist-info/BUILD create mode 100644 tests/whl_with_build_files/testdata/somepkg-1.0.dist-info/BUILD.bazel create mode 100644 tests/whl_with_build_files/testdata/somepkg-1.0.dist-info/METADATA create mode 100644 tests/whl_with_build_files/testdata/somepkg-1.0.dist-info/RECORD create mode 100644 tests/whl_with_build_files/testdata/somepkg-1.0.dist-info/WHEEL create mode 100644 tests/whl_with_build_files/testdata/somepkg/BUILD create mode 100644 tests/whl_with_build_files/testdata/somepkg/BUILD.bazel create mode 100644 tests/whl_with_build_files/testdata/somepkg/__init__.py create mode 100644 tests/whl_with_build_files/testdata/somepkg/a.py create mode 100644 tests/whl_with_build_files/testdata/somepkg/subpkg/BUILD create mode 100644 tests/whl_with_build_files/testdata/somepkg/subpkg/BUILD.bazel create mode 100644 tests/whl_with_build_files/testdata/somepkg/subpkg/__init__.py create mode 100644 tests/whl_with_build_files/testdata/somepkg/subpkg/b.py create mode 100644 tests/whl_with_build_files/verify_files_test.py diff --git a/MODULE.bazel b/MODULE.bazel index 77fa12d113..b1d8711815 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -103,6 +103,8 @@ use_repo( internal_dev_deps, "buildkite_config", "rules_python_runtime_env_tc_info", + "somepkg_with_build_files", + "whl_with_build_files", ) # Add gazelle plugin so that we can run the gazelle example as an e2e integration diff --git a/python/private/internal_dev_deps.bzl b/python/private/internal_dev_deps.bzl index 600c934ace..179c3c7465 100644 --- a/python/private/internal_dev_deps.bzl +++ b/python/private/internal_dev_deps.bzl @@ -14,6 +14,8 @@ """Module extension for internal dev_dependency=True setup.""" load("@bazel_ci_rules//:rbe_repo.bzl", "rbe_preconfig") +load("//python/private/pypi:whl_library.bzl", "whl_library") +load("//tests/support/whl_from_dir:whl_from_dir_repo.bzl", "whl_from_dir_repo") load(":runtime_env_repo.bzl", "runtime_env_repo") def _internal_dev_deps_impl(mctx): @@ -28,6 +30,17 @@ def _internal_dev_deps_impl(mctx): ) runtime_env_repo(name = "rules_python_runtime_env_tc_info") + whl_from_dir_repo( + name = "whl_with_build_files", + root = "//tests/whl_with_build_files/testdata:BUILD.bazel", + output = "somepkg-1.0-any-none-any.whl", + ) + whl_library( + name = "somepkg_with_build_files", + whl_file = "@whl_with_build_files//:somepkg-1.0-any-none-any.whl", + requirement = "somepkg", + ) + internal_dev_deps = module_extension( implementation = _internal_dev_deps_impl, doc = "This extension creates internal rules_python dev dependencies.", diff --git a/python/private/pypi/whl_library.bzl b/python/private/pypi/whl_library.bzl index 601a5c0280..de5fcb9f91 100644 --- a/python/private/pypi/whl_library.bzl +++ b/python/private/pypi/whl_library.bzl @@ -249,6 +249,7 @@ def _whl_library_impl(rctx): whl_path = None if rctx.attr.whl_file: + rctx.watch(rctx.attr.whl_file) whl_path = rctx.path(rctx.attr.whl_file) # Simulate the behaviour where the whl is present in the current directory. diff --git a/tests/support/whl_from_dir/BUILD.bazel b/tests/support/whl_from_dir/BUILD.bazel new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/support/whl_from_dir/whl_from_dir_repo.bzl b/tests/support/whl_from_dir/whl_from_dir_repo.bzl new file mode 100644 index 0000000000..1bf1fd5b45 --- /dev/null +++ b/tests/support/whl_from_dir/whl_from_dir_repo.bzl @@ -0,0 +1,38 @@ +"""Creates a whl file from a directory tree. + +Used to test wheels. Avoids checking in prebuilt files and their associated +security risks. +""" + +load("//python/private:repo_utils.bzl", "repo_utils") + +def _whl_from_dir_repo(rctx): + manifest = [] + + root = rctx.path(rctx.attr.root).dirname + rctx.watch_tree(root) + + output = rctx.path(rctx.attr.output) + repo_utils.execute_checked( + rctx, + # cd to root so zip recursively takes everything there. + working_directory = str(root), + op = "WhlFromDir", + arguments = [ + "zip", + "-0", # Skip compressing + "-X", # Don't store file time or metadata + str(output), + "-r", + ".", + ], + ) + rctx.file("BUILD.bazel", 'exports_files(glob(["*"]))') + +whl_from_dir_repo = repository_rule( + implementation = _whl_from_dir_repo, + attrs = { + "root": attr.label(), + "output": attr.string(), + }, +) diff --git a/tests/whl_with_build_files/BUILD.bazel b/tests/whl_with_build_files/BUILD.bazel new file mode 100644 index 0000000000..5c4949c310 --- /dev/null +++ b/tests/whl_with_build_files/BUILD.bazel @@ -0,0 +1,7 @@ +load("//python:py_test.bzl", "py_test") + +py_test( + name = "verify_files_test", + srcs = ["verify_files_test.py"], + deps = ["@somepkg_with_build_files//:pkg"], +) diff --git a/tests/whl_with_build_files/testdata/BUILD b/tests/whl_with_build_files/testdata/BUILD new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/whl_with_build_files/testdata/BUILD.bazel b/tests/whl_with_build_files/testdata/BUILD.bazel new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/whl_with_build_files/testdata/somepkg-1.0.dist-info/BUILD b/tests/whl_with_build_files/testdata/somepkg-1.0.dist-info/BUILD new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/whl_with_build_files/testdata/somepkg-1.0.dist-info/BUILD.bazel b/tests/whl_with_build_files/testdata/somepkg-1.0.dist-info/BUILD.bazel new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/whl_with_build_files/testdata/somepkg-1.0.dist-info/METADATA b/tests/whl_with_build_files/testdata/somepkg-1.0.dist-info/METADATA new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/whl_with_build_files/testdata/somepkg-1.0.dist-info/RECORD b/tests/whl_with_build_files/testdata/somepkg-1.0.dist-info/RECORD new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/whl_with_build_files/testdata/somepkg-1.0.dist-info/WHEEL b/tests/whl_with_build_files/testdata/somepkg-1.0.dist-info/WHEEL new file mode 100644 index 0000000000..a64521a1cc --- /dev/null +++ b/tests/whl_with_build_files/testdata/somepkg-1.0.dist-info/WHEEL @@ -0,0 +1 @@ +Wheel-Version: 1.0 diff --git a/tests/whl_with_build_files/testdata/somepkg/BUILD b/tests/whl_with_build_files/testdata/somepkg/BUILD new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/whl_with_build_files/testdata/somepkg/BUILD.bazel b/tests/whl_with_build_files/testdata/somepkg/BUILD.bazel new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/whl_with_build_files/testdata/somepkg/__init__.py b/tests/whl_with_build_files/testdata/somepkg/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/whl_with_build_files/testdata/somepkg/a.py b/tests/whl_with_build_files/testdata/somepkg/a.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/whl_with_build_files/testdata/somepkg/subpkg/BUILD b/tests/whl_with_build_files/testdata/somepkg/subpkg/BUILD new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/whl_with_build_files/testdata/somepkg/subpkg/BUILD.bazel b/tests/whl_with_build_files/testdata/somepkg/subpkg/BUILD.bazel new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/whl_with_build_files/testdata/somepkg/subpkg/__init__.py b/tests/whl_with_build_files/testdata/somepkg/subpkg/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/whl_with_build_files/testdata/somepkg/subpkg/b.py b/tests/whl_with_build_files/testdata/somepkg/subpkg/b.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/whl_with_build_files/verify_files_test.py b/tests/whl_with_build_files/verify_files_test.py new file mode 100644 index 0000000000..0af7c93ad9 --- /dev/null +++ b/tests/whl_with_build_files/verify_files_test.py @@ -0,0 +1,12 @@ +import unittest + +class VerifyFilestest(unittest.TestCase): + + def test_stuff(self): + import somepkg + import somepkg.a + import somepkg.subpkg + import somepkg.subpkg.b + +if __name__ == "__main__": + unittest.main() From 7cceefcb85692a48daf02815476ab21539df9974 Mon Sep 17 00:00:00 2001 From: Richard Levasseur Date: Wed, 25 Jun 2025 14:59:58 -0700 Subject: [PATCH 3/8] skip workspace, windows --- tests/support/support.bzl | 6 ++++++ tests/whl_with_build_files/BUILD.bazel | 2 ++ 2 files changed, 8 insertions(+) diff --git a/tests/support/support.bzl b/tests/support/support.bzl index 7bab263c66..adb8e75f71 100644 --- a/tests/support/support.bzl +++ b/tests/support/support.bzl @@ -19,6 +19,7 @@ # rules_testing or as config_setting values, which don't support Label in some # places. +load("//python/private:bzlmod_enabled.bzl", "BZLMOD_ENABLED") # buildifier: disable=bzl-visibility load("//python/private:util.bzl", "IS_BAZEL_7_OR_HIGHER") # buildifier: disable=bzl-visibility MAC = Label("//tests/support:mac") @@ -48,3 +49,8 @@ SUPPORTS_BOOTSTRAP_SCRIPT = select({ "@platforms//os:windows": ["@platforms//:incompatible"], "//conditions:default": [], }) if IS_BAZEL_7_OR_HIGHER else ["@platforms//:incompatible"] + +SUPPORTS_BZLMOD_UNIXY = select({ + "@platforms//os:windows": ["@platforms//:incompatible"], + "//conditions:default": [], +}) if BZLMOD_ENABLED else ["@platforms//:incompatible"] diff --git a/tests/whl_with_build_files/BUILD.bazel b/tests/whl_with_build_files/BUILD.bazel index 5c4949c310..cf78aa7fc0 100644 --- a/tests/whl_with_build_files/BUILD.bazel +++ b/tests/whl_with_build_files/BUILD.bazel @@ -1,7 +1,9 @@ load("//python:py_test.bzl", "py_test") +load("//tests/support:support.bzl", "BZLMOD_UNIXY") py_test( name = "verify_files_test", srcs = ["verify_files_test.py"], + target_compatible_with = BZLMOD_UNIXY, deps = ["@somepkg_with_build_files//:pkg"], ) From 3369453a5437d05201015fc0565d297bdd5d762a Mon Sep 17 00:00:00 2001 From: Richard Levasseur Date: Wed, 25 Jun 2025 15:01:49 -0700 Subject: [PATCH 4/8] fix bzlmod_unixy import --- tests/whl_with_build_files/BUILD.bazel | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/whl_with_build_files/BUILD.bazel b/tests/whl_with_build_files/BUILD.bazel index cf78aa7fc0..e26dc1c3a6 100644 --- a/tests/whl_with_build_files/BUILD.bazel +++ b/tests/whl_with_build_files/BUILD.bazel @@ -1,9 +1,9 @@ load("//python:py_test.bzl", "py_test") -load("//tests/support:support.bzl", "BZLMOD_UNIXY") +load("//tests/support:support.bzl", "SUPPORTS_BZLMOD_UNIXY") py_test( name = "verify_files_test", srcs = ["verify_files_test.py"], - target_compatible_with = BZLMOD_UNIXY, + target_compatible_with = SUPPORTS_BZLMOD_UNIXY, deps = ["@somepkg_with_build_files//:pkg"], ) From 0a8c2fd5d42890b445f168e44ad04ddd36f62d1a Mon Sep 17 00:00:00 2001 From: Richard Levasseur Date: Wed, 25 Jun 2025 15:08:55 -0700 Subject: [PATCH 5/8] ignore test data files, format test, fixup bzl code --- .bazelrc | 4 ++-- .../whl_from_dir/whl_from_dir_repo.bzl | 22 ++++++++++++++----- .../whl_with_build_files/testdata/REPO.bazel | 0 .../whl_with_build_files/verify_files_test.py | 2 ++ 4 files changed, 21 insertions(+), 7 deletions(-) create mode 100644 tests/whl_with_build_files/testdata/REPO.bazel diff --git a/.bazelrc b/.bazelrc index f7f31aed98..8997db9f91 100644 --- a/.bazelrc +++ b/.bazelrc @@ -4,8 +4,8 @@ # (Note, we cannot use `common --deleted_packages` because the bazel version command doesn't support it) # To update these lines, execute # `bazel run @rules_bazel_integration_test//tools:update_deleted_packages` -build --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/patches,examples/bzlmod/py_proto_library,examples/bzlmod/py_proto_library/example.com/another_proto,examples/bzlmod/py_proto_library/example.com/proto,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/another_proto,examples/py_proto_library/example.com/proto,gazelle,gazelle/manifest,gazelle/manifest/generate,gazelle/manifest/hasher,gazelle/manifest/test,gazelle/modules_mapping,gazelle/python,gazelle/pythonconfig,gazelle/python/private,tests/integration/compile_pip_requirements,tests/integration/compile_pip_requirements_test_from_external_repo,tests/integration/custom_commands,tests/integration/ignore_root_user_error,tests/integration/ignore_root_user_error/submodule,tests/integration/local_toolchains,tests/integration/pip_parse,tests/integration/pip_parse/empty,tests/integration/py_cc_toolchain_registered,tests/modules/another_module,tests/modules/other,tests/modules/other/nspkg_delta,tests/modules/other/nspkg_gamma,tests/modules/other/nspkg_single,tests/modules/other/simple_v1,tests/modules/other/simple_v2,tests/modules/other/with_external_data -query --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/patches,examples/bzlmod/py_proto_library,examples/bzlmod/py_proto_library/example.com/another_proto,examples/bzlmod/py_proto_library/example.com/proto,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/another_proto,examples/py_proto_library/example.com/proto,gazelle,gazelle/manifest,gazelle/manifest/generate,gazelle/manifest/hasher,gazelle/manifest/test,gazelle/modules_mapping,gazelle/python,gazelle/pythonconfig,gazelle/python/private,tests/integration/compile_pip_requirements,tests/integration/compile_pip_requirements_test_from_external_repo,tests/integration/custom_commands,tests/integration/ignore_root_user_error,tests/integration/ignore_root_user_error/submodule,tests/integration/local_toolchains,tests/integration/pip_parse,tests/integration/pip_parse/empty,tests/integration/py_cc_toolchain_registered,tests/modules/another_module,tests/modules/other,tests/modules/other/nspkg_delta,tests/modules/other/nspkg_gamma,tests/modules/other/nspkg_single,tests/modules/other/simple_v1,tests/modules/other/simple_v2,tests/modules/other/with_external_data +build --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/patches,examples/bzlmod/py_proto_library,examples/bzlmod/py_proto_library/example.com/another_proto,examples/bzlmod/py_proto_library/example.com/proto,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/another_proto,examples/py_proto_library/example.com/proto,gazelle,gazelle/manifest,gazelle/manifest/generate,gazelle/manifest/hasher,gazelle/manifest/test,gazelle/modules_mapping,gazelle/python,gazelle/pythonconfig,gazelle/python/private,tests/integration/compile_pip_requirements,tests/integration/compile_pip_requirements_test_from_external_repo,tests/integration/custom_commands,tests/integration/ignore_root_user_error,tests/integration/ignore_root_user_error/submodule,tests/integration/local_toolchains,tests/integration/pip_parse,tests/integration/pip_parse/empty,tests/integration/py_cc_toolchain_registered,tests/modules/another_module,tests/modules/other,tests/modules/other/nspkg_delta,tests/modules/other/nspkg_gamma,tests/modules/other/nspkg_single,tests/modules/other/simple_v1,tests/modules/other/simple_v2,tests/modules/other/with_external_data,tests/whl_with_build_files/testdata,tests/whl_with_build_files/testdata/somepkg,tests/whl_with_build_files/testdata/somepkg-1.0.dist-info,tests/whl_with_build_files/testdata/somepkg/subpkg +query --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/patches,examples/bzlmod/py_proto_library,examples/bzlmod/py_proto_library/example.com/another_proto,examples/bzlmod/py_proto_library/example.com/proto,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/another_proto,examples/py_proto_library/example.com/proto,gazelle,gazelle/manifest,gazelle/manifest/generate,gazelle/manifest/hasher,gazelle/manifest/test,gazelle/modules_mapping,gazelle/python,gazelle/pythonconfig,gazelle/python/private,tests/integration/compile_pip_requirements,tests/integration/compile_pip_requirements_test_from_external_repo,tests/integration/custom_commands,tests/integration/ignore_root_user_error,tests/integration/ignore_root_user_error/submodule,tests/integration/local_toolchains,tests/integration/pip_parse,tests/integration/pip_parse/empty,tests/integration/py_cc_toolchain_registered,tests/modules/another_module,tests/modules/other,tests/modules/other/nspkg_delta,tests/modules/other/nspkg_gamma,tests/modules/other/nspkg_single,tests/modules/other/simple_v1,tests/modules/other/simple_v2,tests/modules/other/with_external_data,tests/whl_with_build_files/testdata,tests/whl_with_build_files/testdata/somepkg,tests/whl_with_build_files/testdata/somepkg-1.0.dist-info,tests/whl_with_build_files/testdata/somepkg/subpkg test --test_output=errors diff --git a/tests/support/whl_from_dir/whl_from_dir_repo.bzl b/tests/support/whl_from_dir/whl_from_dir_repo.bzl index 1bf1fd5b45..4e16e8ee4a 100644 --- a/tests/support/whl_from_dir/whl_from_dir_repo.bzl +++ b/tests/support/whl_from_dir/whl_from_dir_repo.bzl @@ -4,11 +4,9 @@ Used to test wheels. Avoids checking in prebuilt files and their associated security risks. """ -load("//python/private:repo_utils.bzl", "repo_utils") +load("//python/private:repo_utils.bzl", "repo_utils") # buildifier: disable=bzl-visibility def _whl_from_dir_repo(rctx): - manifest = [] - root = rctx.path(rctx.attr.root).dirname rctx.watch_tree(root) @@ -32,7 +30,21 @@ def _whl_from_dir_repo(rctx): whl_from_dir_repo = repository_rule( implementation = _whl_from_dir_repo, attrs = { - "root": attr.label(), - "output": attr.string(), + "output": attr.string( + doc = """ +Output file name to write. Should match the wheel filename format: +`pkg-version-pyversion-abi-platform.whl`. Typically a value like +`mypkg-1.0-any-none-any.whl` is whats used for testing. + +For the full format, see +https://packaging.python.org/en/latest/specifications/binary-distribution-format/#file-name-convention +""", + ), + "root": attr.label( + doc = """ +A file whose directory will be put into the output wheel. All files +are included verbatim. + """, + ), }, ) diff --git a/tests/whl_with_build_files/testdata/REPO.bazel b/tests/whl_with_build_files/testdata/REPO.bazel new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/whl_with_build_files/verify_files_test.py b/tests/whl_with_build_files/verify_files_test.py index 0af7c93ad9..a3e83f4364 100644 --- a/tests/whl_with_build_files/verify_files_test.py +++ b/tests/whl_with_build_files/verify_files_test.py @@ -1,5 +1,6 @@ import unittest + class VerifyFilestest(unittest.TestCase): def test_stuff(self): @@ -8,5 +9,6 @@ def test_stuff(self): import somepkg.subpkg import somepkg.subpkg.b + if __name__ == "__main__": unittest.main() From 62f05ecca3980a52d04870159f97ebf782aa1b22 Mon Sep 17 00:00:00 2001 From: Richard Levasseur Date: Wed, 25 Jun 2025 15:12:35 -0700 Subject: [PATCH 6/8] fixup package refs --- python/private/internal_dev_deps.bzl | 2 +- tests/support/whl_from_dir/whl_from_dir_repo.bzl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/private/internal_dev_deps.bzl b/python/private/internal_dev_deps.bzl index 179c3c7465..bb7d76f56a 100644 --- a/python/private/internal_dev_deps.bzl +++ b/python/private/internal_dev_deps.bzl @@ -32,7 +32,7 @@ def _internal_dev_deps_impl(mctx): whl_from_dir_repo( name = "whl_with_build_files", - root = "//tests/whl_with_build_files/testdata:BUILD.bazel", + root = "//tests/whl_with_build_files:testdata/BUILD.bazel", output = "somepkg-1.0-any-none-any.whl", ) whl_library( diff --git a/tests/support/whl_from_dir/whl_from_dir_repo.bzl b/tests/support/whl_from_dir/whl_from_dir_repo.bzl index 4e16e8ee4a..176525636c 100644 --- a/tests/support/whl_from_dir/whl_from_dir_repo.bzl +++ b/tests/support/whl_from_dir/whl_from_dir_repo.bzl @@ -8,7 +8,7 @@ load("//python/private:repo_utils.bzl", "repo_utils") # buildifier: disable=bzl def _whl_from_dir_repo(rctx): root = rctx.path(rctx.attr.root).dirname - rctx.watch_tree(root) + repo_utils.watch_tree(rctx, root) output = rctx.path(rctx.attr.output) repo_utils.execute_checked( From f982303a89975fae0a2721fe37403500422224db Mon Sep 17 00:00:00 2001 From: Richard Levasseur Date: Wed, 25 Jun 2025 15:16:27 -0700 Subject: [PATCH 7/8] comment why its just import statements --- tests/whl_with_build_files/verify_files_test.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/whl_with_build_files/verify_files_test.py b/tests/whl_with_build_files/verify_files_test.py index a3e83f4364..cfbbaa3aff 100644 --- a/tests/whl_with_build_files/verify_files_test.py +++ b/tests/whl_with_build_files/verify_files_test.py @@ -3,7 +3,10 @@ class VerifyFilestest(unittest.TestCase): - def test_stuff(self): + def test_wheel_with_build_files_importable(self): + # If the BUILD files are present, then these imports should fail + # because globs won't pass package boundaries, and the necessary + # py files end up missing in runfiles. import somepkg import somepkg.a import somepkg.subpkg From 9840ca10a934e67846041ff847a6f2dd6fcf016c Mon Sep 17 00:00:00 2001 From: Richard Levasseur Date: Fri, 27 Jun 2025 08:52:22 -0700 Subject: [PATCH 8/8] update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4facff4917..67a4048a22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,9 @@ END_UNRELEASED_TEMPLATE * (pypi) Fixes an issue where builds using a `bazel vendor` vendor directory would fail if the constraints file contained environment markers. Fixes [#2996](https://github.com/bazel-contrib/rules_python/issues/2996). +* (pypi) Wheels with BUILD.bazel (or other special Bazel files) no longer + result in missing files at runtime + ([#2782](https://github.com/bazel-contrib/rules_python/issues/2782)). {#v0-0-0-added} ### Added