@@ -267,11 +267,18 @@ def parse_modules(*, module_ctx, _fail = fail):
267
267
def _python_impl (module_ctx ):
268
268
py = parse_modules (module_ctx = module_ctx )
269
269
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
+
275
282
# Ensure that we pass the full version here.
276
283
full_python_version = full_version (
277
284
version = toolchain_info .python_version ,
@@ -286,12 +293,28 @@ def _python_impl(module_ctx):
286
293
kwargs .update (py .config .kwargs .get (toolchain_info .python_version , {}))
287
294
kwargs .update (py .config .kwargs .get (full_python_version , {}))
288
295
kwargs .update (py .config .default )
289
- toolchain_registered_platforms = python_register_toolchains (
296
+ register_result = python_register_toolchains (
290
297
name = toolchain_info .name ,
291
298
_internal_bzlmod_toolchain_call = True ,
292
299
** kwargs
293
300
)
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
+ ))
295
318
296
319
# List of the base names ("python_3_10") for the toolchain repos
297
320
base_toolchain_repo_names = []
@@ -329,31 +352,23 @@ def _python_impl(module_ctx):
329
352
330
353
# Split the toolchain info into separate objects so they can be passed onto
331
354
# 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
+ )
357
372
358
373
hub_repo (
359
374
name = "pythons_hub" ,
0 commit comments