Skip to content

Commit d6af2b7

Browse files
authored
refactor: have bzlmod pass platforms to python_register_toolchains (#2884)
This is to facilitate eventually allowing overrides to add additional platforms. Instead of the PLATFORMS global being used, the python bzlmod extension passing the mapping directly to python_register_toolchains, then receives back the subset of platforms that had repos defined. That subset is then later used when (re)constructing the list of repo names for the toolchains.
1 parent 50d59e5 commit d6af2b7

File tree

3 files changed

+53
-23
lines changed

3 files changed

+53
-23
lines changed

python/private/python.bzl

+38-16
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,13 @@ def parse_modules(*, module_ctx, _fail = fail):
3434
3535
Returns:
3636
A struct with the following attributes:
37-
* `toolchains`: The list of toolchains to register. The last
38-
element is special and is treated as the default toolchain.
39-
* `defaults`: The default `kwargs` passed to
40-
{bzl:obj}`python_register_toolchains`.
41-
* `debug_info`: {type}`None | dict` extra information to be passed
42-
to the debug repo.
37+
* `toolchains`: The list of toolchains to register. The last
38+
element is special and is treated as the default toolchain.
39+
* `config`: Various toolchain config, see `_get_toolchain_config`.
40+
* `debug_info`: {type}`None | dict` extra information to be passed
41+
to the debug repo.
42+
* `platforms`: {type}`dict[str, platform_info]` of the base set of
43+
platforms toolchains should be created for, if possible.
4344
"""
4445
if module_ctx.os.environ.get("RULES_PYTHON_BZLMOD_DEBUG", "0") == "1":
4546
debug_info = {
@@ -285,11 +286,12 @@ def _python_impl(module_ctx):
285286
kwargs.update(py.config.kwargs.get(toolchain_info.python_version, {}))
286287
kwargs.update(py.config.kwargs.get(full_python_version, {}))
287288
kwargs.update(py.config.default)
288-
loaded_platforms[full_python_version] = python_register_toolchains(
289+
toolchain_registered_platforms = python_register_toolchains(
289290
name = toolchain_info.name,
290291
_internal_bzlmod_toolchain_call = True,
291292
**kwargs
292293
)
294+
loaded_platforms[full_python_version] = toolchain_registered_platforms
293295

294296
# List of the base names ("python_3_10") for the toolchain repos
295297
base_toolchain_repo_names = []
@@ -332,20 +334,19 @@ def _python_impl(module_ctx):
332334
base_name = t.name
333335
base_toolchain_repo_names.append(base_name)
334336
fv = full_version(version = t.python_version, minor_mapping = py.config.minor_mapping)
335-
for platform in loaded_platforms[fv]:
336-
if platform not in PLATFORMS:
337-
continue
337+
platforms = loaded_platforms[fv]
338+
for platform_name, platform_info in platforms.items():
338339
key = str(len(toolchain_names))
339340

340-
full_name = "{}_{}".format(base_name, platform)
341+
full_name = "{}_{}".format(base_name, platform_name)
341342
toolchain_names.append(full_name)
342343
toolchain_repo_names[key] = full_name
343-
toolchain_tcw_map[key] = PLATFORMS[platform].compatible_with
344+
toolchain_tcw_map[key] = platform_info.compatible_with
344345

345346
# The target_settings attribute may not be present for users
346347
# patching python/versions.bzl.
347-
toolchain_ts_map[key] = getattr(PLATFORMS[platform], "target_settings", [])
348-
toolchain_platform_keys[key] = platform
348+
toolchain_ts_map[key] = getattr(platform_info, "target_settings", [])
349+
toolchain_platform_keys[key] = platform_name
349350
toolchain_python_versions[key] = fv
350351

351352
# The last toolchain is the default; it can't have version constraints
@@ -483,9 +484,9 @@ def _process_single_version_overrides(*, tag, _fail = fail, default):
483484
return
484485

485486
for platform in (tag.sha256 or []):
486-
if platform not in PLATFORMS:
487+
if platform not in default["platforms"]:
487488
_fail("The platform must be one of {allowed} but got '{got}'".format(
488-
allowed = sorted(PLATFORMS),
489+
allowed = sorted(default["platforms"]),
489490
got = platform,
490491
))
491492
return
@@ -602,6 +603,26 @@ def _override_defaults(*overrides, modules, _fail = fail, default):
602603
override.fn(tag = tag, _fail = _fail, default = default)
603604

604605
def _get_toolchain_config(*, modules, _fail = fail):
606+
"""Computes the configs for toolchains.
607+
608+
Args:
609+
modules: The modules from module_ctx
610+
_fail: Function to call for failing; only used for testing.
611+
612+
Returns:
613+
A struct with the following:
614+
* `kwargs`: {type}`dict[str, dict[str, object]` custom kwargs to pass to
615+
`python_register_toolchains`, keyed by python version.
616+
The first key is either a Major.Minor or Major.Minor.Patch
617+
string.
618+
* `minor_mapping`: {type}`dict[str, str]` the mapping of Major.Minor
619+
to Major.Minor.Patch.
620+
* `default`: {type}`dict[str, object]` of kwargs passed along to
621+
`python_register_toolchains`. These keys take final precedence.
622+
* `register_all_versions`: {type}`bool` whether all known versions
623+
should be registered.
624+
"""
625+
605626
# Items that can be overridden
606627
available_versions = {
607628
version: {
@@ -621,6 +642,7 @@ def _get_toolchain_config(*, modules, _fail = fail):
621642
}
622643
default = {
623644
"base_url": DEFAULT_RELEASE_BASE_URL,
645+
"platforms": dict(PLATFORMS), # Copy so it's mutable.
624646
"tool_versions": available_versions,
625647
}
626648

python/private/python_register_toolchains.bzl

+14-7
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ def python_register_toolchains(
4141
register_coverage_tool = False,
4242
set_python_version_constraint = False,
4343
tool_versions = None,
44+
platforms = PLATFORMS,
4445
minor_mapping = None,
4546
**kwargs):
4647
"""Convenience macro for users which does typical setup.
@@ -70,12 +71,18 @@ def python_register_toolchains(
7071
tool_versions: {type}`dict` contains a mapping of version with SHASUM
7172
and platform info. If not supplied, the defaults in
7273
python/versions.bzl will be used.
74+
platforms: {type}`dict[str, platform_info]` platforms to create toolchain
75+
repositories for. Note that only a subset is created, depending
76+
on what's available in `tool_versions`.
7377
minor_mapping: {type}`dict[str, str]` contains a mapping from `X.Y` to `X.Y.Z`
7478
version.
7579
**kwargs: passed to each {obj}`python_repository` call.
7680
7781
Returns:
78-
On bzlmod this returns the loaded platform labels. Otherwise None.
82+
On workspace, returns None.
83+
84+
On bzlmod, returns a `dict[str, platform_info]`, which is the
85+
subset of `platforms` that it created repositories for.
7986
"""
8087
bzlmod_toolchain_call = kwargs.pop("_internal_bzlmod_toolchain_call", False)
8188
if bzlmod_toolchain_call:
@@ -104,13 +111,13 @@ def python_register_toolchains(
104111
))
105112
register_coverage_tool = False
106113

107-
loaded_platforms = []
108-
for platform in PLATFORMS.keys():
114+
loaded_platforms = {}
115+
for platform in platforms.keys():
109116
sha256 = tool_versions[python_version]["sha256"].get(platform, None)
110117
if not sha256:
111118
continue
112119

113-
loaded_platforms.append(platform)
120+
loaded_platforms[platform] = platforms[platform]
114121
(release_filename, urls, strip_prefix, patches, patch_strip) = get_release_info(platform, python_version, base_url, tool_versions)
115122

116123
# allow passing in a tool version
@@ -162,15 +169,15 @@ def python_register_toolchains(
162169

163170
host_toolchain(
164171
name = name + "_host",
165-
platforms = loaded_platforms,
172+
platforms = loaded_platforms.keys(),
166173
python_version = python_version,
167174
)
168175

169176
toolchain_aliases(
170177
name = name,
171178
python_version = python_version,
172179
user_repository_name = name,
173-
platforms = loaded_platforms,
180+
platforms = loaded_platforms.keys(),
174181
)
175182

176183
# in bzlmod we write out our own toolchain repos
@@ -182,6 +189,6 @@ def python_register_toolchains(
182189
python_version = python_version,
183190
set_python_version_constraint = set_python_version_constraint,
184191
user_repository_name = name,
185-
platforms = loaded_platforms,
192+
platforms = loaded_platforms.keys(),
186193
)
187194
return None

tests/python/python_tests.bzl

+1
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ def _test_default(env):
149149
"base_url",
150150
"ignore_root_user_error",
151151
"tool_versions",
152+
"platforms",
152153
])
153154
env.expect.that_bool(py.config.default["ignore_root_user_error"]).equals(True)
154155
env.expect.that_str(py.default_python_version).equals("3.11")

0 commit comments

Comments
 (0)