Skip to content

Commit 4e70959

Browse files
rickeylevaignas
andauthored
feat: add runtime_env toolchain suite to replace "autodetecting" toolchain (#2018)
This adds a more comprehensive replacement for the "autodetecting" toolchain. Specifically, it defines all our toolchain types so that they take precedence when specified. This prevents the hermetic toolchains (registered by default) from accidentally being used when undesired. To keep the behavior backwards compatible, an alias is added for the autodetecting toolchain with a deprecation notice. The name `runtime_env` was chosen instead of "autodetecting" so that it's more clear these toolchains are not "automatic" or "detecting" anything -- they're just taking a value from the runtime environment and using it. --------- Co-authored-by: Ignas Anikevicius <[email protected]>
1 parent 11133b3 commit 4e70959

18 files changed

+363
-95
lines changed

.bazelci/presubmit.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ tasks:
182182
platform: rbe_ubuntu1604
183183
test_flags:
184184
- "--test_tag_filters=-integration-test,-acceptance-test"
185+
- "--extra_toolchains=@buildkite_config//config:cc-toolchain"
185186

186187
integration_test_build_file_generation_ubuntu_minimum_supported_workspace:
187188
<<: *minimum_supported_version

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ A brief description of the categories of changes:
3131
* (toolchains) The exec tools toolchain now finds its interpreter by reusing
3232
the regular interpreter toolchain. This avoids having to duplicate specifying
3333
where the runtime for the exec tools toolchain is.
34+
* (toolchains) ({obj}`//python:autodetecting_toolchain`) is deprecated. It is
35+
replaced by {obj}`//python/runtime_env_toolchains:all`. The old target will be
36+
removed in a future release.
3437

3538
### Fixed
3639
* (bzlmod): Targets in `all_requirements` now use the same form as targets returned by the `requirement` macro.
@@ -47,6 +50,10 @@ A brief description of the categories of changes:
4750
* (rules) The first element of the default outputs is now the executable again.
4851
* (pip) Fixed crash when pypi packages lacked a sha (e.g. yanked packages)
4952

53+
### Added
54+
* (toolchains) {obj}`//python/runtime_env_toolchains:all`, which is a drop-in
55+
replacement for the "autodetecting" toolchain.
56+
5057
### Removed
5158
* (pip): Removes the `entrypoint` macro that was replaced by `py_console_script_binary` in 0.26.0.
5259

docs/sphinx/api/python/index.md

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,11 @@ provides:
2626

2727
::::{target} autodetecting_toolchain
2828

29-
A simple toolchain that simply uses `python3` from the runtime environment.
29+
Legacy toolchain; despite its name, it doesn't autodetect anything.
3030

31-
Note that this toolchain provides no build-time information, which makes it of
32-
limited utility.
31+
:::{deprecated} 0.34.0
3332

34-
This is only provided to aid migration off the builtin Bazel toolchain
35-
(`@bazel_tools//python:autodetecting_toolchain`), and is largely only applicable
36-
to WORKSPACE builds.
37-
38-
:::{deprecated} unspecified
39-
40-
Switch to using a hermetic toolchain or manual toolchain configuration instead.
33+
Use {obj}`@rules_python//python/runtime_env_toolchain:all` instead.
4134
:::
42-
4335
::::
36+
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
:::{default-domain} bzl
2+
:::
3+
:::{bzl:currentfile} //python/runtime_env_toolchain:BUILD.bazel
4+
:::
5+
6+
# //python/runtime_env_toolchain
7+
8+
::::{target} all
9+
10+
A set of toolchains that invoke `python3` from the runtime environment.
11+
12+
Note that this toolchain provides no build-time information, which makes it of
13+
limited utility. This is because the invocation of `python3` is done when a
14+
program is run, not at build time.
15+
16+
This is only provided to aid migration off the builtin Bazel toolchain
17+
(`@bazel_tools//python:autodetecting_toolchain`), and is largely only applicable
18+
to WORKSPACE builds.
19+
20+
To use this target, register it as a toolchain in WORKSPACE or MODULE.bazel:
21+
22+
:::
23+
register_toolchains("@rules_python//python/runtime_env_toolchains:all")
24+
:::
25+
26+
The benefit of this target over the legacy targets is this defines additional
27+
toolchain types that rules_python needs. This prevents toolchain resolution from
28+
continuing to search elsewhere (e.g. potentially incurring a download of the
29+
hermetic runtimes when they won't be used).
30+
31+
:::{deprecated} 0.34.0
32+
33+
Switch to using a hermetic toolchain or manual toolchain configuration instead.
34+
:::
35+
36+
:::{versionadded} 0.34.0
37+
:::
38+
::::

docs/sphinx/toolchains.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,5 +240,5 @@ automatically registers a higher-priority toolchain; it won't be used unless
240240
there is a toolchain misconfiguration somewhere.
241241

242242
To aid migration off the Bazel-builtin toolchain, rules_python provides
243-
{obj}`@rules_python//python:autodetecting_toolchain`. This is an equivalent
243+
{obj}`@rules_python//python/runtime_env_toolchains:all`. This is an equivalent
244244
toolchain, but is implemented using rules_python's objects.

python/BUILD.bazel

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ that @rules_python//python is only concerned with the core rules.
2424
"""
2525

2626
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
27-
load("//python/private:autodetecting_toolchain.bzl", "define_autodetecting_toolchain")
2827
load(":current_py_toolchain.bzl", "current_py_toolchain")
2928

3029
package(default_visibility = ["//visibility:public"])
@@ -320,11 +319,16 @@ toolchain_type(
320319
# safe if you know for a fact that your build is completely compatible with the
321320
# version of the `python` command installed on the target platform.
322321

323-
define_autodetecting_toolchain(name = "autodetecting_toolchain")
322+
alias(
323+
name = "autodetecting_toolchain",
324+
actual = "//python/runtime_env_toolchains:runtime_env_toolchain",
325+
deprecation = "Use //python/runtime_env_toolchains:all instead",
326+
)
324327

325328
alias(
326329
name = "autodetecting_toolchain_nonstrict",
327-
actual = ":autodetecting_toolchain",
330+
actual = "//python/runtime_env_toolchains:runtime_env_toolchain",
331+
deprecation = "Use //python/runtime_env_toolchains:all instead",
328332
)
329333

330334
# ========= Packaging rules =========

python/private/BUILD.bazel

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414

1515
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
16+
load("@bazel_skylib//rules:common_settings.bzl", "bool_setting")
1617
load("//python:py_binary.bzl", "py_binary")
1718
load("//python:py_library.bzl", "py_library")
1819
load("//python:versions.bzl", "print_toolchains_checksums")
@@ -58,9 +59,10 @@ bzl_library(
5859
)
5960

6061
bzl_library(
61-
name = "autodetecting_toolchain_bzl",
62-
srcs = ["autodetecting_toolchain.bzl"],
62+
name = "runtime_env_toolchain_bzl",
63+
srcs = ["runtime_env_toolchain.bzl"],
6364
deps = [
65+
":py_exec_tools_toolchain_bzl",
6466
":toolchain_types_bzl",
6567
"//python:py_runtime_bzl",
6668
"//python:py_runtime_pair_bzl",
@@ -140,6 +142,7 @@ bzl_library(
140142
":py_cc_toolchain_info_bzl",
141143
":rules_cc_srcs_bzl",
142144
":util_bzl",
145+
"@bazel_skylib//rules:common_settings",
143146
],
144147
)
145148

@@ -164,7 +167,11 @@ bzl_library(
164167
bzl_library(
165168
name = "py_exec_tools_toolchain_bzl",
166169
srcs = ["py_exec_tools_toolchain.bzl"],
167-
deps = ["//python/private/common:providers_bzl"],
170+
deps = [
171+
":toolchain_types_bzl",
172+
"//python/private/common:providers_bzl",
173+
"@bazel_skylib//rules:common_settings",
174+
],
168175
)
169176

170177
bzl_library(
@@ -192,6 +199,7 @@ bzl_library(
192199
deps = [
193200
"//python:py_runtime_bzl",
194201
"//python:py_runtime_info_bzl",
202+
"@bazel_skylib//rules:common_settings",
195203
],
196204
)
197205

@@ -365,6 +373,15 @@ config_setting(
365373
},
366374
)
367375

376+
# This should only be set by analysis tests to expose additional metadata to
377+
# aid testing, so a setting instead of a flag.
378+
bool_setting(
379+
name = "visible_for_testing",
380+
build_setting_default = False,
381+
# This is only because it is an implicit dependency by the toolchains.
382+
visibility = ["//visibility:public"],
383+
)
384+
368385
print_toolchains_checksums(name = "print_toolchains_checksums")
369386

370387
# Used for py_console_script_gen rule

python/private/autodetecting_toolchain.bzl

Lines changed: 0 additions & 71 deletions
This file was deleted.

python/private/py_cc_toolchain_rule.bzl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ NOTE: This is a beta-quality feature. APIs subject to change until
1818
https://github.com/bazelbuild/rules_python/issues/824 is considered done.
1919
"""
2020

21+
load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")
2122
load("@rules_cc//cc:defs.bzl", "CcInfo")
2223
load(":py_cc_toolchain_info.bzl", "PyCcToolchainInfo")
2324

@@ -37,8 +38,12 @@ def _py_cc_toolchain_impl(ctx):
3738
),
3839
python_version = ctx.attr.python_version,
3940
)
41+
extra_kwargs = {}
42+
if ctx.attr._visible_for_testing[BuildSettingInfo].value:
43+
extra_kwargs["toolchain_label"] = ctx.label
4044
return [platform_common.ToolchainInfo(
4145
py_cc_toolchain = py_cc_toolchain,
46+
**extra_kwargs
4247
)]
4348

4449
py_cc_toolchain = rule(
@@ -60,6 +65,9 @@ py_cc_toolchain = rule(
6065
doc = "The Major.minor Python version, e.g. 3.11",
6166
mandatory = True,
6267
),
68+
"_visible_for_testing": attr.label(
69+
default = "//python/private:visible_for_testing",
70+
),
6371
},
6472
doc = """\
6573
A toolchain for a Python runtime's C/C++ information (e.g. headers)

python/private/py_exec_tools_toolchain.bzl

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,22 @@
1414

1515
"""Rule that defines a toolchain for build tools."""
1616

17+
load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")
1718
load("//python/private:toolchain_types.bzl", "TARGET_TOOLCHAIN_TYPE")
1819
load(":py_exec_tools_info.bzl", "PyExecToolsInfo")
1920

2021
def _py_exec_tools_toolchain_impl(ctx):
21-
return [platform_common.ToolchainInfo(exec_tools = PyExecToolsInfo(
22-
exec_interpreter = ctx.attr.exec_interpreter,
23-
precompiler = ctx.attr.precompiler,
24-
))]
22+
extra_kwargs = {}
23+
if ctx.attr._visible_for_testing[BuildSettingInfo].value:
24+
extra_kwargs["toolchain_label"] = ctx.label
25+
26+
return [platform_common.ToolchainInfo(
27+
exec_tools = PyExecToolsInfo(
28+
exec_interpreter = ctx.attr.exec_interpreter,
29+
precompiler = ctx.attr.precompiler,
30+
),
31+
**extra_kwargs
32+
)]
2533

2634
py_exec_tools_toolchain = rule(
2735
implementation = _py_exec_tools_toolchain_impl,
@@ -36,6 +44,9 @@ py_exec_tools_toolchain = rule(
3644
cfg = "exec",
3745
doc = "See PyExecToolsInfo.precompiler",
3846
),
47+
"_visible_for_testing": attr.label(
48+
default = "//python/private:visible_for_testing",
49+
),
3950
},
4051
)
4152

python/private/py_runtime_pair_rule.bzl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
"""Implementation of py_runtime_pair."""
1616

17+
load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")
1718
load("//python:py_runtime_info.bzl", "PyRuntimeInfo")
1819
load("//python/private:reexports.bzl", "BuiltinPyRuntimeInfo")
1920
load("//python/private:util.bzl", "IS_BAZEL_7_OR_HIGHER")
@@ -40,9 +41,14 @@ def _py_runtime_pair_impl(ctx):
4041
# fail("Using Python 2 is not supported and disabled; see " +
4142
# "https://github.com/bazelbuild/bazel/issues/15684")
4243

44+
extra_kwargs = {}
45+
if ctx.attr._visible_for_testing[BuildSettingInfo].value:
46+
extra_kwargs["toolchain_label"] = ctx.label
47+
4348
return [platform_common.ToolchainInfo(
4449
py2_runtime = py2_runtime,
4550
py3_runtime = py3_runtime,
51+
**extra_kwargs
4652
)]
4753

4854
def _get_py_runtime_info(target):
@@ -85,6 +91,9 @@ The runtime to use for Python 3 targets. Must have `python_version` set to
8591
`PY3`.
8692
""",
8793
),
94+
"_visible_for_testing": attr.label(
95+
default = "//python/private:visible_for_testing",
96+
),
8897
},
8998
fragments = ["py"],
9099
doc = """\

0 commit comments

Comments
 (0)