Skip to content

Commit aa0d16c

Browse files
aignasrickeylev
andauthored
fix(rules): make the srcs trully optional (bazel-contrib#2768)
With this PR we mark the srcs attribute as optional as we can leverage the `main_module` to just run things from the deps. This also removes a long-standing `TODO` note. Fixes bazel-contrib#2765 --------- Co-authored-by: Richard Levasseur <[email protected]>
1 parent 84351d4 commit aa0d16c

File tree

4 files changed

+53
-25
lines changed

4 files changed

+53
-25
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ Unreleased changes template.
7676
* (pypi) The PyPI extension will no longer write the lock file entries as the
7777
extension has been marked reproducible.
7878
Fixes [#2434](https://github.com/bazel-contrib/rules_python/issues/2434).
79+
* (rules) {attr}`py_binary.srcs` and {attr}`py_test.srcs` is no longer mandatory when
80+
`main_module` is specified (for `--bootstrap_impl=script`)
7981

8082
[20250317]: https://github.com/astral-sh/python-build-standalone/releases/tag/20250317
8183

python/private/py_executable.bzl

+2-1
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,8 @@ def _create_stage1_bootstrap(
786786
)
787787
template = runtime.bootstrap_template
788788
subs["%shebang%"] = runtime.stub_shebang
789+
elif not ctx.files.srcs:
790+
fail("mandatory 'srcs' files have not been provided")
789791
else:
790792
if (ctx.configuration.coverage_enabled and
791793
runtime and
@@ -1888,7 +1890,6 @@ def create_executable_rule_builder(implementation, **kwargs):
18881890
),
18891891
**kwargs
18901892
)
1891-
builder.attrs.get("srcs").set_mandatory(True)
18921893
return builder
18931894

18941895
def cc_configure_features(

tests/base_rules/py_executable_base_tests.bzl

+48-24
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ load("//python/private:util.bzl", "IS_BAZEL_7_OR_HIGHER") # buildifier: disable
2424
load("//tests/base_rules:base_tests.bzl", "create_base_tests")
2525
load("//tests/base_rules:util.bzl", "WINDOWS_ATTR", pt_util = "util")
2626
load("//tests/support:py_executable_info_subject.bzl", "PyExecutableInfoSubject")
27-
load("//tests/support:support.bzl", "CC_TOOLCHAIN", "CROSSTOOL_TOP", "LINUX_X86_64", "WINDOWS_X86_64")
27+
load("//tests/support:support.bzl", "BOOTSTRAP_IMPL", "CC_TOOLCHAIN", "CROSSTOOL_TOP", "LINUX_X86_64", "WINDOWS_X86_64")
2828

2929
_tests = []
3030

@@ -342,6 +342,53 @@ def _test_name_cannot_end_in_py_impl(env, target):
342342
matching.str_matches("name must not end in*.py"),
343343
)
344344

345+
def _test_main_module_bootstrap_system_python(name, config):
346+
rt_util.helper_target(
347+
config.rule,
348+
name = name + "_subject",
349+
main_module = "dummy",
350+
)
351+
analysis_test(
352+
name = name,
353+
impl = _test_main_module_bootstrap_system_python_impl,
354+
target = name + "_subject",
355+
config_settings = {
356+
BOOTSTRAP_IMPL: "system_python",
357+
"//command_line_option:platforms": [LINUX_X86_64],
358+
},
359+
expect_failure = True,
360+
)
361+
362+
def _test_main_module_bootstrap_system_python_impl(env, target):
363+
env.expect.that_target(target).failures().contains_predicate(
364+
matching.str_matches("mandatory*srcs"),
365+
)
366+
367+
_tests.append(_test_main_module_bootstrap_system_python)
368+
369+
def _test_main_module_bootstrap_script(name, config):
370+
rt_util.helper_target(
371+
config.rule,
372+
name = name + "_subject",
373+
main_module = "dummy",
374+
)
375+
analysis_test(
376+
name = name,
377+
impl = _test_main_module_bootstrap_script_impl,
378+
target = name + "_subject",
379+
config_settings = {
380+
BOOTSTRAP_IMPL: "script",
381+
"//command_line_option:platforms": [LINUX_X86_64],
382+
},
383+
)
384+
385+
def _test_main_module_bootstrap_script_impl(env, target):
386+
env.expect.that_target(target).default_outputs().contains(
387+
"{package}/{test_name}_subject",
388+
)
389+
390+
_tests.append(_test_main_module_bootstrap_script)
391+
345392
def _test_py_runtime_info_provided(name, config):
346393
rt_util.helper_target(
347394
config.rule,
@@ -365,29 +412,6 @@ def _test_py_runtime_info_provided_impl(env, target):
365412

366413
_tests.append(_test_py_runtime_info_provided)
367414

368-
# Can't test this -- mandatory validation happens before analysis test
369-
# can intercept it
370-
# TODO(#1069): Once re-implemented in Starlark, modify rule logic to make this
371-
# testable.
372-
# def _test_srcs_is_mandatory(name, config):
373-
# rt_util.helper_target(
374-
# config.rule,
375-
# name = name + "_subject",
376-
# )
377-
# analysis_test(
378-
# name = name,
379-
# impl = _test_srcs_is_mandatory,
380-
# target = name + "_subject",
381-
# expect_failure = True,
382-
# )
383-
#
384-
# _tests.append(_test_srcs_is_mandatory)
385-
#
386-
# def _test_srcs_is_mandatory_impl(env, target):
387-
# env.expect.that_target(target).failures().contains_predicate(
388-
# matching.str_matches("mandatory*srcs"),
389-
# )
390-
391415
# =====
392416
# You were gonna add a test at the end, weren't you?
393417
# Nope. Please keep them sorted; put it in its alphabetical location.

tests/support/support.bzl

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ CROSSTOOL_TOP = Label("//tests/support/cc_toolchains:cc_toolchain_suite")
3535
# str() around Label() is necessary because rules_testing's config_settings
3636
# doesn't accept yet Label objects.
3737
ADD_SRCS_TO_RUNFILES = str(Label("//python/config_settings:add_srcs_to_runfiles"))
38+
BOOTSTRAP_IMPL = str(Label("//python/config_settings:bootstrap_impl"))
3839
EXEC_TOOLS_TOOLCHAIN = str(Label("//python/config_settings:exec_tools_toolchain"))
3940
PRECOMPILE = str(Label("//python/config_settings:precompile"))
4041
PRECOMPILE_SOURCE_RETENTION = str(Label("//python/config_settings:precompile_source_retention"))

0 commit comments

Comments
 (0)