@@ -22,15 +22,9 @@ load(":python_register_toolchains.bzl", "python_register_toolchains")
2222load (":pythons_hub.bzl" , "hub_repo" )
2323load (":repo_utils.bzl" , "repo_utils" )
2424load (":semver.bzl" , "semver" )
25- load (":text_util.bzl" , "render" )
2625load (":toolchains_repo.bzl" , "multi_toolchain_aliases" )
2726load (":util.bzl" , "IS_BAZEL_6_4_OR_HIGHER" )
2827
29- # This limit can be increased essentially arbitrarily, but doing so will cause a rebuild of all
30- # targets using any of these toolchains due to the changed repository name.
31- _MAX_NUM_TOOLCHAINS = 9999
32- _TOOLCHAIN_INDEX_PAD_LENGTH = len (str (_MAX_NUM_TOOLCHAINS ))
33-
3428def parse_modules (* , module_ctx , _fail = fail ):
3529 """Parse the modules and return a struct for registrations.
3630
@@ -240,9 +234,6 @@ def parse_modules(*, module_ctx, _fail = fail):
240234 # toolchain. We need the default last.
241235 toolchains .append (default_toolchain )
242236
243- if len (toolchains ) > _MAX_NUM_TOOLCHAINS :
244- fail ("more than {} python versions are not supported" .format (_MAX_NUM_TOOLCHAINS ))
245-
246237 # sort the toolchains so that the toolchain versions that are in the
247238 # `minor_mapping` are coming first. This ensures that `python_version =
248239 # "3.X"` transitions work as expected.
@@ -275,6 +266,9 @@ def parse_modules(*, module_ctx, _fail = fail):
275266def _python_impl (module_ctx ):
276267 py = parse_modules (module_ctx = module_ctx )
277268
269+ # dict[str version, list[str] platforms]; where version is full
270+ # python version string ("3.4.5"), and platforms are keys from
271+ # the PLATFORMS global.
278272 loaded_platforms = {}
279273 for toolchain_info in py .toolchains :
280274 # Ensure that we pass the full version here.
@@ -297,30 +291,82 @@ def _python_impl(module_ctx):
297291 ** kwargs
298292 )
299293
300- # Create the pythons_hub repo for the interpreter meta data and the
301- # the various toolchains.
294+ # List of the base names ("python_3_10") for the toolchain repos
295+ base_toolchain_repo_names = []
296+
297+ # list[str] The infix to use for the resulting toolchain() `name` arg.
298+ toolchain_names = []
299+
300+ # dict[str i, str repo]; where repo is the full repo name
301+ # ("python_3_10_unknown-linux-x86_64") for the toolchain
302+ # i corresponds to index `i` in toolchain_names
303+ toolchain_repo_names = {}
304+
305+ # dict[str i, list[str] constraints]; where constraints is a list
306+ # of labels for target_compatible_with
307+ # i corresponds to index `i` in toolchain_names
308+ toolchain_tcw_map = {}
309+
310+ # dict[str i, list[str] settings]; where settings is a list
311+ # of labels for target_settings
312+ # i corresponds to index `i` in toolchain_names
313+ toolchain_ts_map = {}
314+
315+ # dict[str i, str set_constraint]; where set_constraint is the string
316+ # "True" or "False".
317+ # i corresponds to index `i` in toolchain_names
318+ toolchain_set_python_version_constraints = {}
319+
320+ # dict[str i, str python_version]; where python_version is the full
321+ # python version ("3.4.5").
322+ toolchain_python_versions = {}
323+
324+ # dict[str i, str platform_key]; where platform_key is the key within
325+ # the PLATFORMS global for this toolchain
326+ toolchain_platform_keys = {}
327+
328+ # Split the toolchain info into separate objects so they can be passed onto
329+ # the repository rule.
330+ for i , t in enumerate (py .toolchains ):
331+ is_last = (i + 1 ) == len (py .toolchains )
332+ base_name = t .name
333+ base_toolchain_repo_names .append (base_name )
334+ 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
338+ key = str (len (toolchain_names ))
339+
340+ full_name = "{}_{}" .format (base_name , platform )
341+ toolchain_names .append (full_name )
342+ toolchain_repo_names [key ] = full_name
343+ toolchain_tcw_map [key ] = PLATFORMS [platform ].compatible_with
344+
345+ # The target_settings attribute may not be present for users
346+ # patching python/versions.bzl.
347+ toolchain_ts_map [key ] = getattr (PLATFORMS [platform ], "target_settings" , [])
348+ toolchain_platform_keys [key ] = platform
349+ toolchain_python_versions [key ] = fv
350+
351+ # The last toolchain is the default; it can't have version constraints
352+ # Despite the implication of the arg name, the values are strs, not bools
353+ toolchain_set_python_version_constraints [key ] = (
354+ "True" if not is_last else "False"
355+ )
356+
302357 hub_repo (
303358 name = "pythons_hub" ,
304- # Last toolchain is default
359+ toolchain_names = toolchain_names ,
360+ toolchain_repo_names = toolchain_repo_names ,
361+ toolchain_target_compatible_with_map = toolchain_tcw_map ,
362+ toolchain_target_settings_map = toolchain_ts_map ,
363+ toolchain_platform_keys = toolchain_platform_keys ,
364+ toolchain_python_versions = toolchain_python_versions ,
365+ toolchain_set_python_version_constraints = toolchain_set_python_version_constraints ,
366+ base_toolchain_repo_names = [t .name for t in py .toolchains ],
305367 default_python_version = py .default_python_version ,
306368 minor_mapping = py .config .minor_mapping ,
307369 python_versions = list (py .config .default ["tool_versions" ].keys ()),
308- toolchain_prefixes = [
309- render .toolchain_prefix (index , toolchain .name , _TOOLCHAIN_INDEX_PAD_LENGTH )
310- for index , toolchain in enumerate (py .toolchains )
311- ],
312- toolchain_python_versions = [
313- full_version (version = t .python_version , minor_mapping = py .config .minor_mapping )
314- for t in py .toolchains
315- ],
316- # The last toolchain is the default; it can't have version constraints
317- # Despite the implication of the arg name, the values are strs, not bools
318- toolchain_set_python_version_constraints = [
319- "True" if i != len (py .toolchains ) - 1 else "False"
320- for i in range (len (py .toolchains ))
321- ],
322- toolchain_user_repository_names = [t .name for t in py .toolchains ],
323- loaded_platforms = loaded_platforms ,
324370 )
325371
326372 # This is require in order to support multiple version py_test
0 commit comments