Skip to content

Commit 94428b0

Browse files
committed
feat: Support main_module with bootstrap_impl=system_python
1 parent 8f11a0f commit 94428b0

File tree

4 files changed

+44
-8
lines changed

4 files changed

+44
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ END_UNRELEASED_TEMPLATE
102102
* 3.12.11
103103
* 3.13.5
104104
* 3.14.0b3
105+
* (rules) `main_module` now works without needing to set `bootstrap_impl=script`
105106

106107
{#v0-0-0-removed}
107108
### Removed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ the [Breaking Changes](#breaking-changes) section for how to introduce breaking
122122
changes.
123123

124124
User visible changes, such as features, fixes, or notable refactors, should
125-
be documneted in CHANGELOG.md and their respective API doc. See [Documenting
125+
be documented in CHANGELOG.md and their respective API doc. See [Documenting
126126
changes] for how to do so.
127127

128128
Common `type`s:
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
"""
2+
A shim to get `main_module` working with `bootstrap_impl=system_python`.
3+
"""
4+
5+
import os
6+
import runpy
7+
8+
if __name__ == '__main__':
9+
runpy.run_module('%main_module%', run_name='__main__', alter_sys=True)

python/private/py_executable.bzl

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ accepting arbitrary Python versions.
194194
allow_single_file = True,
195195
default = "@bazel_tools//tools/python:python_bootstrap_template.txt",
196196
),
197+
"_main_module_entrypoint_template": lambda: attrb.Label(
198+
allow_single_file = True,
199+
default = "//python/private:main_module_entrypoint_template.py",
200+
),
197201
"_launcher": lambda: attrb.Label(
198202
cfg = "target",
199203
# NOTE: This is an executable, but is only used for Windows. It
@@ -360,9 +364,8 @@ def _create_executable(
360364
)
361365
else:
362366
stage2_bootstrap = None
363-
extra_runfiles = ctx.runfiles()
364367
zip_main = ctx.actions.declare_file(base_executable_name + ".temp", sibling = executable)
365-
_create_stage1_bootstrap(
368+
extra_runfiles = _create_stage1_bootstrap(
366369
ctx,
367370
output = zip_main,
368371
main_py = main_py,
@@ -426,16 +429,17 @@ def _create_executable(
426429
if bootstrap_output != None:
427430
fail("Should not occur: bootstrap_output should not be used " +
428431
"when creating an executable zip")
429-
_create_executable_zip_file(
432+
more_runfiles = _create_executable_zip_file(
430433
ctx,
431434
output = executable,
432435
zip_file = zip_file,
433436
stage2_bootstrap = stage2_bootstrap,
434437
runtime_details = runtime_details,
435438
venv = venv,
436439
)
440+
extra_runfiles = extra_runfiles.merge(more_runfiles)
437441
elif bootstrap_output:
438-
_create_stage1_bootstrap(
442+
more_runfiles = _create_stage1_bootstrap(
439443
ctx,
440444
output = bootstrap_output,
441445
stage2_bootstrap = stage2_bootstrap,
@@ -445,6 +449,7 @@ def _create_executable(
445449
main_py = main_py,
446450
venv = venv,
447451
)
452+
extra_runfiles = extra_runfiles.merge(more_runfiles)
448453
else:
449454
# Otherwise, this should be the Windows case of launcher + zip.
450455
# Double check this just to make sure.
@@ -796,6 +801,7 @@ def _create_stage1_bootstrap(
796801
is_for_zip,
797802
runtime_details,
798803
venv = None):
804+
extra_runfiles = ctx.runfiles()
799805
runtime = runtime_details.effective_runtime
800806

801807
if venv:
@@ -833,9 +839,10 @@ def _create_stage1_bootstrap(
833839
)
834840
template = runtime.bootstrap_template
835841
subs["%shebang%"] = runtime.stub_shebang
836-
elif not ctx.files.srcs:
837-
fail("mandatory 'srcs' files have not been provided")
838842
else:
843+
if not ctx.files.srcs and not ctx.attr.main_module:
844+
fail("mandatory 'srcs' files have not been provided")
845+
839846
if (ctx.configuration.coverage_enabled and
840847
runtime and
841848
runtime.coverage_tool):
@@ -855,6 +862,20 @@ def _create_stage1_bootstrap(
855862
subs["%coverage_tool%"] = coverage_tool_runfiles_path
856863
subs["%import_all%"] = ("True" if ctx.fragments.bazel_py.python_import_all_repositories else "False")
857864
subs["%imports%"] = ":".join(imports.to_list())
865+
866+
if ctx.attr.main_module:
867+
main_module_entrypoint = ctx.actions.declare_file("main_module_entrypoint.py")
868+
ctx.actions.expand_template(
869+
template = ctx.file._main_module_entrypoint_template,
870+
output = main_module_entrypoint,
871+
substitutions = {"%main_module%": ctx.attr.main_module}
872+
)
873+
main_py = main_module_entrypoint
874+
extra_runfiles = extra_runfiles.merge(ctx.runfiles([main_module_entrypoint]))
875+
else:
876+
# shouldn't happen
877+
fail("Neither main nor main_module was provided")
878+
858879
subs["%main%"] = "{}/{}".format(ctx.workspace_name, main_py.short_path)
859880

860881
ctx.actions.expand_template(
@@ -863,6 +884,8 @@ def _create_stage1_bootstrap(
863884
substitutions = subs,
864885
)
865886

887+
return extra_runfiles
888+
866889
def _create_windows_exe_launcher(
867890
ctx,
868891
*,
@@ -985,7 +1008,7 @@ def _create_executable_zip_file(
9851008
sibling = output,
9861009
)
9871010
if stage2_bootstrap:
988-
_create_stage1_bootstrap(
1011+
extra_runfiles = _create_stage1_bootstrap(
9891012
ctx,
9901013
output = prelude,
9911014
stage2_bootstrap = stage2_bootstrap,
@@ -994,6 +1017,7 @@ def _create_executable_zip_file(
9941017
venv = venv,
9951018
)
9961019
else:
1020+
extra_runfiles = ctx.runfiles()
9971021
ctx.actions.write(prelude, "#!/usr/bin/env python3\n")
9981022

9991023
ctx.actions.run_shell(
@@ -1009,6 +1033,8 @@ def _create_executable_zip_file(
10091033
progress_message = "Build Python zip executable: %{label}",
10101034
)
10111035

1036+
return extra_runfiles
1037+
10121038
def _get_cc_details_for_binary(ctx, extra_deps):
10131039
cc_info = collect_cc_info(ctx, extra_deps = extra_deps)
10141040
return create_cc_details_struct(

0 commit comments

Comments
 (0)