From ef12d0ab71613d77c202d18c39d575d2397ef8aa Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Fri, 11 Jul 2025 10:41:32 -0700 Subject: [PATCH 1/3] test: Add test for main_module with bootstrap_impl=system_python --- tests/bootstrap_impls/BUILD.bazel | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/bootstrap_impls/BUILD.bazel b/tests/bootstrap_impls/BUILD.bazel index c3d44df240..836e7d7c63 100644 --- a/tests/bootstrap_impls/BUILD.bazel +++ b/tests/bootstrap_impls/BUILD.bazel @@ -13,6 +13,7 @@ # limitations under the License. load("@rules_pkg//pkg:tar.bzl", "pkg_tar") load("@rules_shell//shell:sh_test.bzl", "sh_test") +load("//python:defs.bzl", "py_library") load("//tests/support:py_reconfig.bzl", "py_reconfig_binary", "py_reconfig_test") load("//tests/support:sh_py_run_test.bzl", "sh_py_run_test") load("//tests/support:support.bzl", "SUPPORTS_BOOTSTRAP_SCRIPT") @@ -127,11 +128,22 @@ py_reconfig_test( name = "main_module_test", srcs = ["main_module.py"], bootstrap_impl = "script", - imports = ["."], main_module = "tests.bootstrap_impls.main_module", target_compatible_with = SUPPORTS_BOOTSTRAP_SCRIPT, ) +py_library( + name = "main_module_system_python_lib", + srcs = ["main_module.py"], +) + +py_reconfig_test( + name = "main_module_system_python_test", + bootstrap_impl = "system_python", + main_module = "tests.bootstrap_impls.main_module", + deps = [":main_module_system_python_lib"], +) + sh_py_run_test( name = "inherit_pythonsafepath_env_test", bootstrap_impl = "script", From e87d7e890b808d831856f90a5f9299068aa73f75 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Fri, 11 Jul 2025 10:41:45 -0700 Subject: [PATCH 2/3] feat: Support main_module with bootstrap_impl=system_python --- CHANGELOG.md | 1 + CONTRIBUTING.md | 2 +- .../main_module_entrypoint_template.py | 9 +++++ python/private/py_executable.bzl | 40 +++++++++++++++---- tests/base_rules/py_executable_base_tests.bzl | 4 +- 5 files changed, 46 insertions(+), 10 deletions(-) create mode 100644 python/private/main_module_entrypoint_template.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f02c8bbb4..6a820f8272 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -104,6 +104,7 @@ END_UNRELEASED_TEMPLATE * 3.12.11 * 3.13.5 * 3.14.0b3 +* (rules) `main_module` now works without needing to set `bootstrap_impl=script` {#v0-0-0-removed} ### Removed diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e1bd11b81d..3a384a74a0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -122,7 +122,7 @@ the [Breaking Changes](#breaking-changes) section for how to introduce breaking changes. User visible changes, such as features, fixes, or notable refactors, should -be documneted in CHANGELOG.md and their respective API doc. See [Documenting +be documented in CHANGELOG.md and their respective API doc. See [Documenting changes] for how to do so. Common `type`s: diff --git a/python/private/main_module_entrypoint_template.py b/python/private/main_module_entrypoint_template.py new file mode 100644 index 0000000000..e0f6778b29 --- /dev/null +++ b/python/private/main_module_entrypoint_template.py @@ -0,0 +1,9 @@ +""" +A shim to get `main_module` working with `bootstrap_impl=system_python`. +""" + +import os +import runpy + +if __name__ == "__main__": + runpy.run_module("%main_module%", run_name="__main__", alter_sys=True) diff --git a/python/private/py_executable.bzl b/python/private/py_executable.bzl index 7e50247e61..705416d209 100644 --- a/python/private/py_executable.bzl +++ b/python/private/py_executable.bzl @@ -201,6 +201,10 @@ accepting arbitrary Python versions. # empty target for other platforms. default = "//tools/launcher:launcher", ), + "_main_module_entrypoint_template": lambda: attrb.Label( + allow_single_file = True, + default = "//python/private:main_module_entrypoint_template.py", + ), "_py_interpreter": lambda: attrb.Label( # The configuration_field args are validated when called; # we use the precense of py_internal to indicate this Bazel @@ -360,9 +364,8 @@ def _create_executable( ) else: stage2_bootstrap = None - extra_runfiles = ctx.runfiles() zip_main = ctx.actions.declare_file(base_executable_name + ".temp", sibling = executable) - _create_stage1_bootstrap( + extra_runfiles = _create_stage1_bootstrap( ctx, output = zip_main, main_py = main_py, @@ -426,7 +429,7 @@ def _create_executable( if bootstrap_output != None: fail("Should not occur: bootstrap_output should not be used " + "when creating an executable zip") - _create_executable_zip_file( + more_runfiles = _create_executable_zip_file( ctx, output = executable, zip_file = zip_file, @@ -434,8 +437,9 @@ def _create_executable( runtime_details = runtime_details, venv = venv, ) + extra_runfiles = extra_runfiles.merge(more_runfiles) elif bootstrap_output: - _create_stage1_bootstrap( + more_runfiles = _create_stage1_bootstrap( ctx, output = bootstrap_output, stage2_bootstrap = stage2_bootstrap, @@ -445,6 +449,7 @@ def _create_executable( main_py = main_py, venv = venv, ) + extra_runfiles = extra_runfiles.merge(more_runfiles) else: # Otherwise, this should be the Windows case of launcher + zip. # Double check this just to make sure. @@ -796,6 +801,7 @@ def _create_stage1_bootstrap( is_for_zip, runtime_details, venv = None): + extra_runfiles = ctx.runfiles() runtime = runtime_details.effective_runtime if venv: @@ -833,9 +839,10 @@ def _create_stage1_bootstrap( ) template = runtime.bootstrap_template subs["%shebang%"] = runtime.stub_shebang - elif not ctx.files.srcs: - fail("mandatory 'srcs' files have not been provided") else: + if not ctx.files.srcs and not ctx.attr.main_module: + fail("mandatory 'srcs' files have not been provided") + if (ctx.configuration.coverage_enabled and runtime and runtime.coverage_tool): @@ -855,6 +862,20 @@ def _create_stage1_bootstrap( subs["%coverage_tool%"] = coverage_tool_runfiles_path subs["%import_all%"] = ("True" if ctx.fragments.bazel_py.python_import_all_repositories else "False") subs["%imports%"] = ":".join(imports.to_list()) + + if ctx.attr.main_module: + main_module_entrypoint = ctx.actions.declare_file("main_module_entrypoint.py") + ctx.actions.expand_template( + template = ctx.file._main_module_entrypoint_template, + output = main_module_entrypoint, + substitutions = {"%main_module%": ctx.attr.main_module}, + ) + main_py = main_module_entrypoint + extra_runfiles = extra_runfiles.merge(ctx.runfiles([main_module_entrypoint])) + elif not main_py: + # shouldn't happen + fail("Neither main nor main_module was provided") + subs["%main%"] = "{}/{}".format(ctx.workspace_name, main_py.short_path) ctx.actions.expand_template( @@ -863,6 +884,8 @@ def _create_stage1_bootstrap( substitutions = subs, ) + return extra_runfiles + def _create_windows_exe_launcher( ctx, *, @@ -985,7 +1008,7 @@ def _create_executable_zip_file( sibling = output, ) if stage2_bootstrap: - _create_stage1_bootstrap( + extra_runfiles = _create_stage1_bootstrap( ctx, output = prelude, stage2_bootstrap = stage2_bootstrap, @@ -994,6 +1017,7 @@ def _create_executable_zip_file( venv = venv, ) else: + extra_runfiles = ctx.runfiles() ctx.actions.write(prelude, "#!/usr/bin/env python3\n") ctx.actions.run_shell( @@ -1009,6 +1033,8 @@ def _create_executable_zip_file( progress_message = "Build Python zip executable: %{label}", ) + return extra_runfiles + def _get_cc_details_for_binary(ctx, extra_deps): cc_info = collect_cc_info(ctx, extra_deps = extra_deps) return create_cc_details_struct( diff --git a/tests/base_rules/py_executable_base_tests.bzl b/tests/base_rules/py_executable_base_tests.bzl index 49cbb1586c..d22a06f2bc 100644 --- a/tests/base_rules/py_executable_base_tests.bzl +++ b/tests/base_rules/py_executable_base_tests.bzl @@ -363,8 +363,8 @@ def _test_main_module_bootstrap_system_python(name, config): ) def _test_main_module_bootstrap_system_python_impl(env, target): - env.expect.that_target(target).failures().contains_predicate( - matching.str_matches("mandatory*srcs"), + env.expect.that_target(target).default_outputs().contains( + "{package}/{test_name}_subject", ) _tests.append(_test_main_module_bootstrap_system_python) From 418a70c9a69e7b1c4d4bc797bbd90d1e74cdf26d Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Fri, 11 Jul 2025 10:41:45 -0700 Subject: [PATCH 3/3] Address feedback --- CHANGELOG.md | 2 +- tests/bootstrap_impls/BUILD.bazel | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a820f8272..c5c2ad1212 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -104,7 +104,7 @@ END_UNRELEASED_TEMPLATE * 3.12.11 * 3.13.5 * 3.14.0b3 -* (rules) `main_module` now works without needing to set `bootstrap_impl=script` +* (rules) {obj}`main_module` now works without needing to set {obj}`--bootstrap_impl=script` {#v0-0-0-removed} ### Removed diff --git a/tests/bootstrap_impls/BUILD.bazel b/tests/bootstrap_impls/BUILD.bazel index 836e7d7c63..5f3d1cde28 100644 --- a/tests/bootstrap_impls/BUILD.bazel +++ b/tests/bootstrap_impls/BUILD.bazel @@ -124,24 +124,25 @@ py_reconfig_test( main = "sys_path_order_test.py", ) -py_reconfig_test( - name = "main_module_test", +py_library( + name = "main_module_lib", srcs = ["main_module.py"], + imports = ["."], +) + +py_reconfig_test( + name = "main_module_script_test", bootstrap_impl = "script", main_module = "tests.bootstrap_impls.main_module", target_compatible_with = SUPPORTS_BOOTSTRAP_SCRIPT, -) - -py_library( - name = "main_module_system_python_lib", - srcs = ["main_module.py"], + deps = [":main_module_lib"], ) py_reconfig_test( name = "main_module_system_python_test", bootstrap_impl = "system_python", main_module = "tests.bootstrap_impls.main_module", - deps = [":main_module_system_python_lib"], + deps = [":main_module_lib"], ) sh_py_run_test( pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy