Skip to content

Commit b228f60

Browse files
authored
fix(bzlmod)!: Remove ability to specify toolchain repo name. (#1258)
The main reasons this is removed is because if modules choose different names for the same toolchain, only one of the two toolchains (which are, hopefully, identical) will be used. Which toolchain is used depends on the module graph dependency ordering. Furthermore, as of #1238, only one repo per version is created; others are ignored. This means a module doesn't know if the name it chooses will result in a repo being created with that name. Instead, the toolchain repos are named by rules_python: `python_{major}_{minor}`. These repo names are currently part of the public API, since they end up referenced in MODULE config (to wire the toolchain interpreter to pip). BREAKING CHANGES This removes the `name` arg from `python.toolchain()`. Users will need to remove such usages from their `MODULE.bazel` and update their `use_repo()` statements. If keeping the custom repo name is necessary, then repo mappings can be used. See #1232 for additional migration steps, commands, and information.
1 parent 9374021 commit b228f60

File tree

9 files changed

+27
-74
lines changed

9 files changed

+27
-74
lines changed

.bazelignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ bazel-rules_python
66
bazel-bin
77
bazel-out
88
bazel-testlogs
9+
examples/bzlmod/bazel-bzlmod
10+
examples/bzlmod_build_file_generation/bazel-bzlmod_build_file_generation
11+
examples/py_proto_library/bazel-py_proto_library

examples/bzlmod/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
# names. Those names are defined in the MODULES.bazel file.
88
load("@bazel_skylib//rules:build_test.bzl", "build_test")
99
load("@pip//:requirements.bzl", "all_requirements", "all_whl_requirements", "requirement")
10-
load("@python_39//:defs.bzl", py_test_with_transition = "py_test")
10+
load("@python_3_9//:defs.bzl", py_test_with_transition = "py_test")
1111
load("@rules_python//python:defs.bzl", "py_binary", "py_library", "py_test")
1212
load("@rules_python//python:pip.bzl", "compile_pip_requirements")
1313

examples/bzlmod/MODULE.bazel

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,20 @@ local_path_override(
1111
path = "../..",
1212
)
1313

14-
# This name is passed into python.toolchain and it's use_repo statement.
15-
# We also use the same value in the python.host_python_interpreter call.
16-
PYTHON_NAME_39 = "python_39"
14+
# This name is generated by python.toolchain(), and is later passed
15+
# to use_repo() and interpreter.install().
16+
PYTHON_NAME_39 = "python_3_9"
1717

1818
INTERPRETER_NAME_39 = "interpreter_39"
1919

20-
PYTHON_NAME_310 = "python_310"
20+
PYTHON_NAME_310 = "python_3_10"
2121

2222
INTERPRETER_NAME_310 = "interpreter_310"
2323

2424
# We next initialize the python toolchain using the extension.
2525
# You can set different Python versions in this block.
2626
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
2727
python.toolchain(
28-
# This name is used in the various use_repo statements
29-
# below, and in the local extension that is in this
30-
# example.
31-
name = PYTHON_NAME_39,
3228
configure_coverage_tool = True,
3329
# Only set when you have mulitple toolchain versions.
3430
is_default = True,
@@ -41,7 +37,6 @@ python.toolchain(
4137
# Note: we do not supporting using multiple pip extensions, this is
4238
# work in progress.
4339
python.toolchain(
44-
name = PYTHON_NAME_310,
4540
configure_coverage_tool = True,
4641
python_version = "3.10",
4742
)

examples/bzlmod/other_module/MODULE.bazel

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,16 @@ bazel_dep(name = "rules_python", version = "")
1010
# a submodule. This code only exists to test that
1111
# we support doing this. This code is only for rules_python
1212
# testing purposes.
13-
PYTHON_NAME_39 = "python_39"
13+
PYTHON_NAME_39 = "python_3_9"
1414

15-
PYTHON_NAME_311 = "python_311"
15+
PYTHON_NAME_311 = "python_3_11"
1616

1717
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
1818
python.toolchain(
19-
# This name is used in the various use_repo statements
20-
# below, and in the local extension that is in this
21-
# example.
22-
name = PYTHON_NAME_39,
2319
configure_coverage_tool = True,
2420
python_version = "3.9",
2521
)
2622
python.toolchain(
27-
# This name is used in the various use_repo statements
28-
# below, and in the local extension that is in this
29-
# example.
30-
name = PYTHON_NAME_311,
3123
configure_coverage_tool = True,
3224
# In a submodule this is ignored
3325
is_default = True,

examples/bzlmod/other_module/other_module/pkg/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
load("@python_311//:defs.bzl", py_binary_311 = "py_binary")
1+
load("@python_3_11//:defs.bzl", py_binary_311 = "py_binary")
22
load("@rules_python//python:defs.bzl", "py_library")
33

44
py_library(

examples/bzlmod_build_file_generation/MODULE.bazel

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,13 @@ python = use_extension("@rules_python//python/extensions:python.bzl", "python")
4646

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.
49-
PYTHON_NAME = "python"
49+
PYTHON_NAME = "python_3_9"
5050

5151
INTERPRETER_NAME = "interpreter"
5252

5353
# We next initialize the python toolchain using the extension.
5454
# You can set different Python versions in this block.
5555
python.toolchain(
56-
name = PYTHON_NAME,
5756
configure_coverage_tool = True,
5857
is_default = True,
5958
python_version = "3.9",

examples/py_proto_library/MODULE.bazel

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@ local_path_override(
1414

1515
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
1616
python.toolchain(
17-
name = "python3_9",
1817
configure_coverage_tool = True,
1918
python_version = "3.9",
2019
)
21-
use_repo(python, "python3_9")
20+
use_repo(python, "python_3_9")
2221

2322
# We are using rules_proto to define rules_proto targets to be consumed by py_proto_library.
2423
bazel_dep(name = "rules_proto", version = "5.3.0-21.7")

python/extensions/interpreter.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def _interpreter_repo_impl(rctx):
5353

5454
actual_interpreter_label = INTERPRETER_LABELS.get(rctx.attr.python_name)
5555
if actual_interpreter_label == None:
56-
fail("Unable to find interpreter with name {}".format(rctx.attr.python_name))
56+
fail("Unable to find interpreter with name '{}'".format(rctx.attr.python_name))
5757

5858
rctx.symlink(actual_interpreter_label, "python")
5959

python/extensions/python.bzl

Lines changed: 13 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ def _left_pad_zero(index, length):
4343
def _print_warn(msg):
4444
print("WARNING:", msg)
4545

46-
def _python_register_toolchains(toolchain_attr, version_constraint):
46+
def _python_register_toolchains(name, toolchain_attr, version_constraint):
4747
"""Calls python_register_toolchains and returns a struct used to collect the toolchains.
4848
"""
4949
python_register_toolchains(
50-
name = toolchain_attr.name,
50+
name = name,
5151
python_version = toolchain_attr.python_version,
5252
register_coverage_tool = toolchain_attr.configure_coverage_tool,
5353
ignore_root_user_error = toolchain_attr.ignore_root_user_error,
@@ -56,7 +56,7 @@ def _python_register_toolchains(toolchain_attr, version_constraint):
5656
return struct(
5757
python_version = toolchain_attr.python_version,
5858
set_python_version_constraint = str(version_constraint),
59-
name = toolchain_attr.name,
59+
name = name,
6060
)
6161

6262
def _python_impl(module_ctx):
@@ -67,38 +67,17 @@ def _python_impl(module_ctx):
6767
# toolchain added to toolchains.
6868
default_toolchain = None
6969

70-
# Map of toolchain name to registering module
71-
global_toolchain_names = {}
72-
7370
# Map of string Major.Minor to the toolchain name and module name
7471
global_toolchain_versions = {}
7572

7673
for mod in module_ctx.modules:
77-
module_toolchain_names = []
7874
module_toolchain_versions = []
7975

8076
for toolchain_attr in mod.tags.toolchain:
81-
toolchain_name = toolchain_attr.name
82-
83-
# Duplicate names within a module indicate a misconfigured module.
84-
if toolchain_name in module_toolchain_names:
85-
_fail_duplicate_module_toolchain_name(mod.name, toolchain_name)
86-
module_toolchain_names.append(toolchain_name)
87-
88-
# Ignore name collisions in the global scope because there isn't
89-
# much else that can be done. Modules don't know and can't control
90-
# what other modules do, so the first in the dependency graph wins.
91-
if toolchain_name in global_toolchain_names:
92-
_warn_duplicate_global_toolchain_name(
93-
toolchain_name,
94-
first_module = global_toolchain_names[toolchain_name],
95-
second_module = mod.name,
96-
)
97-
continue
98-
global_toolchain_names[toolchain_name] = mod.name
77+
toolchain_version = toolchain_attr.python_version
78+
toolchain_name = "python_" + toolchain_version.replace(".", "_")
9979

10080
# Duplicate versions within a module indicate a misconfigured module.
101-
toolchain_version = toolchain_attr.python_version
10281
if toolchain_version in module_toolchain_versions:
10382
_fail_duplicate_module_toolchain_version(toolchain_version, mod.name)
10483
module_toolchain_versions.append(toolchain_version)
@@ -137,6 +116,7 @@ def _python_impl(module_ctx):
137116
)
138117

139118
toolchain_info = _python_register_toolchains(
119+
toolchain_name,
140120
toolchain_attr,
141121
version_constraint = not is_default,
142122
)
@@ -182,23 +162,6 @@ def _python_impl(module_ctx):
182162
},
183163
)
184164

185-
def _fail_duplicate_module_toolchain_name(module_name, toolchain_name):
186-
fail(("Duplicate module toolchain name: module '{module}' attempted " +
187-
"to use the name '{toolchain}' multiple times in itself").format(
188-
toolchain = toolchain_name,
189-
module = module_name,
190-
))
191-
192-
def _warn_duplicate_global_toolchain_name(name, first_module, second_module):
193-
_print_warn((
194-
"Ignoring toolchain '{name}' from module '{second_module}': " +
195-
"Toolchain with the same name from module '{first_module}' has precedence"
196-
).format(
197-
name = name,
198-
first_module = first_module,
199-
second_module = second_module,
200-
))
201-
202165
def _fail_duplicate_module_toolchain_version(version, module):
203166
fail(("Duplicate module toolchain version: module '{module}' attempted " +
204167
"to use version '{version}' multiple times in itself").format(
@@ -256,6 +219,12 @@ if the sub module toolchain is marked as the default version. If you have
256219
more than one toolchain in your root module, you need to set one of the
257220
toolchains as the default version. If there is only one toolchain it
258221
is set as the default toolchain.
222+
223+
Toolchain repository name
224+
225+
A toolchain's repository name uses the format `python_{major}_{minor}`, e.g.
226+
`python_3_10`. The `major` and `minor` components are
227+
`major` and `minor` are the Python version from the `python_version` attribute.
259228
""",
260229
attrs = {
261230
"configure_coverage_tool": attr.bool(
@@ -271,13 +240,9 @@ is set as the default toolchain.
271240
mandatory = False,
272241
doc = "Whether the toolchain is the default version",
273242
),
274-
"name": attr.string(
275-
mandatory = True,
276-
doc = "Name of the toolchain",
277-
),
278243
"python_version": attr.string(
279244
mandatory = True,
280-
doc = "The Python version that we are creating the toolchain for.",
245+
doc = "The Python version, in `major.minor` format, e.g '3.12', to create a toolchain for.",
281246
),
282247
},
283248
),

0 commit comments

Comments
 (0)