Skip to content

Commit acf4136

Browse files
committed
refactor: make bzlmod directly aware of created toolchain repo names
1 parent d6af2b7 commit acf4136

File tree

2 files changed

+64
-43
lines changed

2 files changed

+64
-43
lines changed

python/private/python.bzl

+47-32
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

+17-11
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)