@@ -267,11 +267,18 @@ def parse_modules(*, module_ctx, _fail = fail):
267267def _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" ,
0 commit comments