Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .bazelignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ gazelle/examples/bzlmod_build_file_generation/bazel-bzlmod_build_file_generation
gazelle/examples/bzlmod_build_file_generation/bazel-out
gazelle/examples/bzlmod_build_file_generation/bazel-testlog
sphinxdocs
tests/integration/bootstrap_impl_exec_config/bazel-bootstrap_impl_exec_config
tests/integration/bzlmod_lockfile/bazel-bzlmod_lockfile
tests/integration/compile_pip_requirements/bazel-compile_pip_requirements
tests/integration/local_toolchains/bazel-local_toolchains
Expand Down
1 change: 1 addition & 0 deletions .bazelrc.deleted_packages
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ common --deleted_packages=gazelle/modules_mapping
common --deleted_packages=gazelle/python
common --deleted_packages=gazelle/python/private
common --deleted_packages=gazelle/pythonconfig
common --deleted_packages=tests/integration/bootstrap_impl_exec_config
common --deleted_packages=tests/integration/bzlmod_lockfile
common --deleted_packages=tests/integration/compile_pip_requirements
common --deleted_packages=tests/integration/compile_pip_requirements_test_from_external_repo
Expand Down
4 changes: 4 additions & 0 deletions docs/api/rules_python/python/config_settings/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,10 @@ instead.
:::{versionadded} 0.33.0
:::

:::{versionchanged} VERSION_NEXT_PATCH
The flag also applies to tools built in the exec configuration under Bazel 10.
:::

::::

::::{bzl:flag} current_config
Expand Down
3 changes: 3 additions & 0 deletions news/bootstrap-impl-exec-config.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fixed {obj}`--bootstrap_impl` resetting to `system_python` for build tools,
such as a `py_binary` run by a `genrule`, under Bazel 10. Tools no longer need
a system `python3` when `--bootstrap_impl=script` is set.
6 changes: 6 additions & 0 deletions python/config_settings/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ rp_string_flag(
":_is_windows": BootstrapImplFlag.SYSTEM_PYTHON,
"//conditions:default": "",
}),
# Propagate the flag into exec configurations so that tools, e.g. a
# py_binary run by a genrule, use the same bootstrap as the target
# configuration. Bazel 10 resets Starlark flags in exec configurations
# unless they have universal scope
# (https://github.com/bazelbuild/bazel/issues/26909).
scope = "universal",

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do if maintainers agree.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes please, a test for this would be good.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

values = sorted(BootstrapImplFlag.__members__.values()),
# NOTE: Only public because it's an implicit dependency
visibility = NOT_ACTUALLY_PUBLIC,
Expand Down
5 changes: 5 additions & 0 deletions python/private/flags.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ string_flag = rule(
build_setting = config.string(flag = True),
attrs = {
"override": attr.string(),
# Read by Bazel, not the implementation, to decide whether the flag
# propagates into exec configurations. No default because Bazel only
# honors an explicitly set value
# (https://github.com/bazelbuild/bazel/issues/31806).
"scope": attr.string(),
"values": attr.string_list(),
},
)
Expand Down
5 changes: 5 additions & 0 deletions tests/integration/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ default_test_runner(
visibility = ["//visibility:public"],
)

rules_python_integration_test(
name = "bootstrap_impl_exec_config_test",
py_main = "bootstrap_impl_exec_config_test.py",
)

rules_python_integration_test(
name = "bzlmod_lockfile_test",
bazel_versions = ["9.3.1"],
Expand Down
7 changes: 7 additions & 0 deletions tests/integration/bootstrap_impl_exec_config/.bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
common --lockfile_mode=off
test --test_output=errors
build --enable_runfiles
# Mitigate transient CI network failures via mirror fallback and retries.
common --experimental_downloader_config=../../../downloader_config.cfg
common --http_timeout_scaling=10.0
common --experimental_repository_downloader_retries=10
15 changes: 15 additions & 0 deletions tests/integration/bootstrap_impl_exec_config/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
load("@rules_python//python:py_binary.bzl", "py_binary")

py_binary(
name = "tool",
srcs = ["tool.py"],
)

# Records the first line of the launcher of :tool as built for the exec
# configuration, which shows the bootstrap it uses.
genrule(
name = "tool_launcher",
outs = ["tool_launcher.txt"],
cmd = "head -n 1 $(execpath :tool) > $@",
tools = [":tool"],
)
10 changes: 10 additions & 0 deletions tests/integration/bootstrap_impl_exec_config/MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module(name = "bootstrap_impl_exec_config")

bazel_dep(name = "rules_python", version = "0.0.0")
local_path_override(
module_name = "rules_python",
path = "../../..",
)

python = use_extension("@rules_python//python/extensions:python.bzl", "python")
python.toolchain(python_version = "3.13")
Empty file.
1 change: 1 addition & 0 deletions tests/integration/bootstrap_impl_exec_config/WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Intentionally blank; bzlmod is used.
Empty file.
1 change: 1 addition & 0 deletions tests/integration/bootstrap_impl_exec_config/tool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
print("tool")
34 changes: 34 additions & 0 deletions tests/integration/bootstrap_impl_exec_config_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""Integration test for --bootstrap_impl in the exec configuration.

Verifies that a py_binary run by a genrule uses the bootstrap set with
--bootstrap_impl on the command line. Bazel 10 resets Starlark flags in the
exec configuration unless they have universal scope.
"""

import pathlib
import unittest

from tests.integration import runner


class BootstrapImplExecConfigTest(runner.TestCase):
def test_genrule_tool_uses_bootstrap_script(self):
"""The launcher of the genrule tool is the script bootstrap."""
self.run_bazel(
"build",
"--@rules_python//python/config_settings:bootstrap_impl=script",
"//:tool_launcher",
)
execution_root = self.run_bazel("info", "execution_root").stdout.strip()
result = self.run_bazel(
"cquery",
"--@rules_python//python/config_settings:bootstrap_impl=script",
"--output=files",
"//:tool_launcher",
)
launcher = pathlib.Path(execution_root, result.stdout.strip())
self.assertEqual(launcher.read_text().strip(), "#!/usr/bin/env bash")


if __name__ == "__main__":
unittest.main()