Skip to content

Commit 9de326e

Browse files
authored
refactor: make bzlmod directly aware of created toolchain repo names (#2885)
This makes python_register_toolchains return the repo names it created, which allows the bzlmod code to be directly aware of the repos that were created instead of having to rely on assuming the names via the platform keys. This is to facilitate python_register_toolchains creating a more arbitrary subset of platform-specific repos. Work towards #2081
1 parent 6ffeff6 commit 9de326e

File tree

2 files changed

+64
-43
lines changed

2 files changed

+64
-43
lines changed

python/private/python.bzl

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -267,11 +267,18 @@ def parse_modules(*, module_ctx, _fail = fail):
267267
def _python_impl(module_ctx):
268268
py = parse_modules(module_ctx = module_ctx)
269269

270-
# dict[str version, list[str] platforms]; where version is full
271-
# python version string ("3.4.5"), and platforms are keys from
272-
# the PLATFORMS global.
273-
loaded_platforms = {}
274-
for toolchain_info in py.toolchains:
270+
# list of structs; see inline struct call within the loop below.
271+
toolchain_impls = []
272+
273+
# list[str] of the base names of toolchain repos
274+
base_toolchain_repo_names = []
275+
276+
# Create the underlying python_repository repos that contain the
277+
# python runtimes and their toolchain implementation definitions.
278+
for i, toolchain_info in enumerate(py.toolchains):
279+
is_last = (i + 1) == len(py.toolchains)
280+
base_toolchain_repo_names.append(toolchain_info.name)
281+
275282
# Ensure that we pass the full version here.
276283
full_python_version = full_version(
277284
version = toolchain_info.python_version,
@@ -286,12 +293,28 @@ def _python_impl(module_ctx):
286293
kwargs.update(py.config.kwargs.get(toolchain_info.python_version, {}))
287294
kwargs.update(py.config.kwargs.get(full_python_version, {}))
288295
kwargs.update(py.config.default)
289-
toolchain_registered_platforms = python_register_toolchains(
296+
register_result = python_register_toolchains(
290297
name = toolchain_info.name,
291298
_internal_bzlmod_toolchain_call = True,
292299
**kwargs
293300
)
294-
loaded_platforms[full_python_version] = toolchain_registered_platforms
301+
for repo_name, (platform_name, platform_info) in register_result.impl_repos.items():
302+
toolchain_impls.append(struct(
303+
# str: The base name to use for the toolchain() target
304+
name = repo_name,
305+
# str: The repo name the toolchain() target points to.
306+
impl_repo_name = repo_name,
307+
# str: platform key in the passed-in platforms dict
308+
platform_name = platform_name,
309+
# struct: platform_info() struct
310+
platform = platform_info,
311+
# str: Major.Minor.Micro python version
312+
full_python_version = full_python_version,
313+
# bool: whether to implicitly add the python version constraint
314+
# to the toolchain's target_settings.
315+
# The last toolchain is the default; it can't have version constraints
316+
set_python_version_constraint = is_last,
317+
))
295318

296319
# List of the base names ("python_3_10") for the toolchain repos
297320
base_toolchain_repo_names = []
@@ -329,31 +352,23 @@ def _python_impl(module_ctx):
329352

330353
# Split the toolchain info into separate objects so they can be passed onto
331354
# the repository rule.
332-
for i, t in enumerate(py.toolchains):
333-
is_last = (i + 1) == len(py.toolchains)
334-
base_name = t.name
335-
base_toolchain_repo_names.append(base_name)
336-
fv = full_version(version = t.python_version, minor_mapping = py.config.minor_mapping)
337-
platforms = loaded_platforms[fv]
338-
for platform_name, platform_info in platforms.items():
339-
key = str(len(toolchain_names))
340-
341-
full_name = "{}_{}".format(base_name, platform_name)
342-
toolchain_names.append(full_name)
343-
toolchain_repo_names[key] = full_name
344-
toolchain_tcw_map[key] = platform_info.compatible_with
345-
346-
# The target_settings attribute may not be present for users
347-
# patching python/versions.bzl.
348-
toolchain_ts_map[key] = getattr(platform_info, "target_settings", [])
349-
toolchain_platform_keys[key] = platform_name
350-
toolchain_python_versions[key] = fv
351-
352-
# The last toolchain is the default; it can't have version constraints
353-
# Despite the implication of the arg name, the values are strs, not bools
354-
toolchain_set_python_version_constraints[key] = (
355-
"True" if not is_last else "False"
356-
)
355+
for entry in toolchain_impls:
356+
key = str(len(toolchain_names))
357+
358+
toolchain_names.append(entry.name)
359+
toolchain_repo_names[key] = entry.impl_repo_name
360+
toolchain_tcw_map[key] = entry.platform.compatible_with
361+
362+
# The target_settings attribute may not be present for users
363+
# patching python/versions.bzl.
364+
toolchain_ts_map[key] = getattr(entry.platform, "target_settings", [])
365+
toolchain_platform_keys[key] = entry.platform_name
366+
toolchain_python_versions[key] = entry.full_python_version
367+
368+
# Repo rules can't accept dict[str, bool], so encode them as a string value.
369+
toolchain_set_python_version_constraints[key] = (
370+
"True" if entry.set_python_version_constraint else "False"
371+
)
357372

358373
hub_repo(
359374
name = "pythons_hub",

python/private/python_register_toolchains.bzl

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,17 @@ def python_register_toolchains(
111111
))
112112
register_coverage_tool = False
113113

114-
loaded_platforms = {}
115-
for platform in platforms.keys():
114+
# list[str] of the platform names that were used
115+
loaded_platforms = []
116+
117+
# dict[str repo name, tuple[str, platform_info]]
118+
impl_repos = {}
119+
for platform, platform_info in platforms.items():
116120
sha256 = tool_versions[python_version]["sha256"].get(platform, None)
117121
if not sha256:
118122
continue
119123

120-
loaded_platforms[platform] = platforms[platform]
124+
loaded_platforms.append(platform)
121125
(release_filename, urls, strip_prefix, patches, patch_strip) = get_release_info(platform, python_version, base_url, tool_versions)
122126

123127
# allow passing in a tool version
@@ -137,11 +141,10 @@ def python_register_toolchains(
137141
)],
138142
)
139143

144+
impl_repo_name = "{}_{}".format(name, platform)
145+
impl_repos[impl_repo_name] = (platform, platform_info)
140146
python_repository(
141-
name = "{name}_{platform}".format(
142-
name = name,
143-
platform = platform,
144-
),
147+
name = impl_repo_name,
145148
sha256 = sha256,
146149
patches = patches,
147150
patch_strip = patch_strip,
@@ -169,26 +172,29 @@ def python_register_toolchains(
169172

170173
host_toolchain(
171174
name = name + "_host",
172-
platforms = loaded_platforms.keys(),
175+
platforms = loaded_platforms,
173176
python_version = python_version,
174177
)
175178

176179
toolchain_aliases(
177180
name = name,
178181
python_version = python_version,
179182
user_repository_name = name,
180-
platforms = loaded_platforms.keys(),
183+
platforms = loaded_platforms,
181184
)
182185

183186
# in bzlmod we write out our own toolchain repos
184187
if bzlmod_toolchain_call:
185-
return loaded_platforms
188+
return struct(
189+
# dict[str name, tuple[str platform_name, platform_info]]
190+
impl_repos = impl_repos,
191+
)
186192

187193
toolchains_repo(
188194
name = toolchain_repo_name,
189195
python_version = python_version,
190196
set_python_version_constraint = set_python_version_constraint,
191197
user_repository_name = name,
192-
platforms = loaded_platforms.keys(),
198+
platforms = loaded_platforms,
193199
)
194200
return None

0 commit comments

Comments
 (0)