Skip to content

Commit fa0dc38

Browse files
committed
feat(bzlmod): Allowing multiple python.toolchain extension calls
We do this work for two reasons. First, we must support Module dependencies and sub-modules using` python.toolchain`. Second, we needed this commit in order to support using multiple toolchains with bzlmod. This commit modifies the` python.toolchain` extension to handle being called multiple times. We are modeling how the multiple Python toolchains work. This is the same naming convention that python_register_multi_toolchains uses. See: https://github.com/bazelbuild/rules_python/blob/16126d0ebfee074a3a8fe216b20cc19e1b3603c1/python/repositories.bzl#L569 This commit also updates the two bzlmod examples.
1 parent 16126d0 commit fa0dc38

File tree

5 files changed

+61
-23
lines changed

5 files changed

+61
-23
lines changed

examples/bzlmod/MODULE.bazel

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,35 @@ local_path_override(
1010
path = "../..",
1111
)
1212

13+
PYTHON_NAME = "python3_9"
14+
PYTHON_TOOLCHAINS = PYTHON_NAME + "_toolchains"
1315
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
1416
python.toolchain(
15-
name = "python3_9",
17+
name = PYTHON_NAME,
1618
configure_coverage_tool = True,
1719
python_version = "3.9",
1820
)
19-
use_repo(python, "python3_9")
20-
use_repo(python, "python3_9_toolchains")
21+
use_repo(python, PYTHON_NAME)
22+
use_repo(python, PYTHON_TOOLCHAINS)
2123

2224
register_toolchains(
23-
"@python3_9_toolchains//:all",
25+
"@{}//:all".format(PYTHON_TOOLCHAINS),
2426
)
2527

28+
interpreter = use_extension("@rules_python//python/extensions:interpreter.bzl", "interpreter")
29+
interpreter.install(
30+
name = "interpreter_python_3_9",
31+
python_name = PYTHON_NAME,
32+
)
33+
use_repo(interpreter, "interpreter_python_3_9")
34+
35+
2636
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
2737
pip.parse(
2838
name = "pip",
2939
requirements_lock = "//:requirements_lock.txt",
3040
requirements_windows = "//:requirements_windows.txt",
41+
python_interpreter_target = "@interpreter_python_3_9//:python",
3142
)
3243
use_repo(pip, "pip")
3344

examples/bzlmod_build_file_generation/MODULE.bazel

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ python = use_extension("@rules_python//python/extensions:python.bzl", "python")
4747
# This name is passed into python.toolchain and it's use_repo statement.
4848
# We also use the same name for python.host_python_interpreter.
4949
PYTHON_NAME = "python3"
50+
PYTHON_TOOLCHAINS = PYTHON_NAME + "_toolchains"
5051

5152
# We next initialize the python toolchain using the extension.
5253
# You can set different Python versions in this block.
@@ -63,12 +64,12 @@ python.toolchain(
6364
# into the scope of the current module.
6465
# All of the python3 repositories use the PYTHON_NAME as there prefix. They
6566
# are not catenated for ease of reading.
66-
use_repo(python, PYTHON_NAME, "python3_toolchains")
67+
use_repo(python, PYTHON_NAME, PYTHON_TOOLCHAINS)
6768

6869
# Register an already-defined toolchain so that Bazel can use it during
6970
# toolchain resolution.
7071
register_toolchains(
71-
"@python3_toolchains//:all",
72+
"@{}//:all".format(PYTHON_TOOLCHAINS),
7273
)
7374

7475
# The interpreter extension discovers the platform specific Python binary.

python/extensions/interpreter.bzl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,11 @@ in the MODULES.bazel file.
5151
def _interpreter_repo_impl(rctx):
5252
rctx.file("BUILD.bazel", "")
5353

54-
actual_interpreter_label = INTERPRETER_LABELS.get(rctx.attr.python_name)
54+
name = rctx.attr.python_name
55+
actual_interpreter_label = INTERPRETER_LABELS.get(name)
56+
5557
if actual_interpreter_label == None:
56-
fail("Unable to find interpreter with name {}".format(rctx.attr.python_name))
58+
fail("Unable to find interpreter with name {}".format(name))
5759

5860
rctx.symlink(actual_interpreter_label, "python")
5961

python/extensions/python.bzl

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,40 @@
1717
load("@rules_python//python:repositories.bzl", "python_register_toolchains")
1818
load("@rules_python//python/extensions/private:interpreter_hub.bzl", "hub_repo")
1919

20+
def _python_register_toolchains(toolchain_attr, version_constraint):
21+
python_register_toolchains(
22+
name = toolchain_attr.name,
23+
python_version = toolchain_attr.python_version,
24+
register_coverage_tool = toolchain_attr.configure_coverage_tool,
25+
ignore_root_user_error = toolchain_attr.ignore_root_user_error,
26+
set_python_version_constraint = version_constraint,
27+
)
28+
2029
def _python_impl(module_ctx):
30+
# We collect all of the toolchain names to create
31+
# the INTERPRETER_LABELS map. This is used
32+
# by interpreter_extensions.bzl
2133
toolchains = []
34+
default_toolchain = None
2235
for mod in module_ctx.modules:
2336
for toolchain_attr in mod.tags.toolchain:
24-
python_register_toolchains(
25-
name = toolchain_attr.name,
26-
python_version = toolchain_attr.python_version,
27-
bzlmod = True,
28-
# Toolchain registration in bzlmod is done in MODULE file
29-
register_toolchains = False,
30-
register_coverage_tool = toolchain_attr.configure_coverage_tool,
31-
ignore_root_user_error = toolchain_attr.ignore_root_user_error,
32-
)
33-
34-
# We collect all of the toolchain names to create
35-
# the INTERPRETER_LABELS map. This is used
36-
# by interpreter_extensions.bzl
3737
toolchains.append(toolchain_attr.name)
3838

39+
# We register the default toolchain last
40+
# And if we only have one toolchain we register it as the default
41+
# TODO see if we are in the root module
42+
if toolchain_attr.default_version or len(mod.tags.toolchain) == 1:
43+
default_toolchain = toolchain_attr
44+
continue
45+
46+
# We are suffixing with the version in order to handle multiple
47+
# toolchains.
48+
_python_register_toolchains(toolchain_attr, True)
49+
50+
if default_toolchain:
51+
_python_register_toolchains(default_toolchain, False)
52+
53+
# create the hub for the different interpreter versions
3954
hub_repo(
4055
name = "pythons_hub",
4156
toolchains = toolchains,
@@ -51,6 +66,10 @@ python = module_extension(
5166
mandatory = False,
5267
doc = "Whether or not to configure the default coverage tool for the toolchains.",
5368
),
69+
"default_version": attr.bool(
70+
mandatory = False,
71+
doc = "Whether the toolchain is the default version",
72+
),
5473
"ignore_root_user_error": attr.bool(
5574
default = False,
5675
doc = "Whether the check for root should be ignored or not. This causes cache misses with .pyc files.",

python/repositories.bzl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,6 @@ def python_register_toolchains(
457457
register_coverage_tool = False,
458458
set_python_version_constraint = False,
459459
tool_versions = TOOL_VERSIONS,
460-
bzlmod = False,
461460
**kwargs):
462461
"""Convenience macro for users which does typical setup.
463462
@@ -480,9 +479,15 @@ def python_register_toolchains(
480479
set_python_version_constraint: When set to true, target_compatible_with for the toolchains will include a version constraint.
481480
tool_versions: a dict containing a mapping of version with SHASUM and platform info. If not supplied, the defaults
482481
in python/versions.bzl will be used.
483-
bzlmod: Whether this rule is being run under a bzlmod module extension.
484482
**kwargs: passed to each python_repositories call.
485483
"""
484+
485+
# If we have @@ we have bzlmod
486+
bzlmod = str(Label("//:distribution")).startswith("@@")
487+
if bzlmod:
488+
# you cannot used native.register_toolchains when using bzlmod.
489+
register_toolchains = False
490+
486491
base_url = kwargs.pop("base_url", DEFAULT_RELEASE_BASE_URL)
487492

488493
if python_version in MINOR_MAPPING:

0 commit comments

Comments
 (0)
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