@@ -28,22 +28,21 @@ load(":util.bzl", "IS_BAZEL_6_4_OR_HIGHER")
2828_MAX_NUM_TOOLCHAINS = 9999
2929_TOOLCHAIN_INDEX_PAD_LENGTH = len (str (_MAX_NUM_TOOLCHAINS ))
3030
31- def _python_register_toolchains (name , toolchain_attr , module , ignore_root_user_error ):
32- """Calls python_register_toolchains and returns a struct used to collect the toolchains.
31+ def parse_modules (module_ctx ):
32+ """Parse the modules and return a struct for registrations.
33+
34+ Args:
35+ module_ctx: {type}`module_ctx` module context.
36+
37+ Returns:
38+ A struct with the following attributes:
39+ * `toolchains`: The list of toolchains to register. The last
40+ element is special and is treated as the default toolchain.
41+ * `defaults`: The default `kwargs` passed to
42+ {bzl:obj}`python_register_toolchains`.
43+ * `debug_info`: {type}`None | dict` extra information to be passed
44+ to the debug repo.
3345 """
34- python_register_toolchains (
35- name = name ,
36- python_version = toolchain_attr .python_version ,
37- register_coverage_tool = toolchain_attr .configure_coverage_tool ,
38- ignore_root_user_error = ignore_root_user_error ,
39- )
40- return struct (
41- python_version = toolchain_attr .python_version ,
42- name = name ,
43- module = struct (name = module .name , is_root = module .is_root ),
44- )
45-
46- def _python_impl (module_ctx ):
4746 if module_ctx .os .environ .get ("RULES_PYTHON_BZLMOD_DEBUG" , "0" ) == "1" :
4847 debug_info = {
4948 "toolchains_registered" : [],
@@ -61,7 +60,7 @@ def _python_impl(module_ctx):
6160 # This is a toolchain_info struct.
6261 default_toolchain = None
6362
64- # Map of string Major.Minor to the toolchain_info struct
63+ # Map of version string to the toolchain_info struct
6564 global_toolchain_versions = {}
6665
6766 ignore_root_user_error = None
@@ -139,11 +138,11 @@ def _python_impl(module_ctx):
139138 )
140139 toolchain_info = None
141140 else :
142- toolchain_info = _python_register_toolchains (
143- toolchain_name ,
144- toolchain_attr ,
145- module = mod ,
146- ignore_root_user_error = ignore_root_user_error ,
141+ toolchain_info = struct (
142+ python_version = toolchain_attr . python_version ,
143+ name = toolchain_name ,
144+ register_coverage_tool = toolchain_attr . configure_coverage_tool ,
145+ module = struct ( name = mod . name , is_root = mod . is_root ) ,
147146 )
148147 global_toolchain_versions [toolchain_version ] = toolchain_info
149148 if debug_info :
@@ -184,39 +183,67 @@ def _python_impl(module_ctx):
184183 if len (toolchains ) > _MAX_NUM_TOOLCHAINS :
185184 fail ("more than {} python versions are not supported" .format (_MAX_NUM_TOOLCHAINS ))
186185
186+ return struct (
187+ toolchains = [
188+ struct (
189+ python_version = t .python_version ,
190+ name = t .name ,
191+ register_coverage_tool = t .register_coverage_tool ,
192+ )
193+ for t in toolchains
194+ ],
195+ debug_info = debug_info ,
196+ default_python_version = toolchains [- 1 ].python_version ,
197+ defaults = {
198+ "ignore_root_user_error" : ignore_root_user_error ,
199+ },
200+ )
201+
202+ def _python_impl (module_ctx ):
203+ py = parse_modules (module_ctx )
204+
205+ for toolchain_info in py .toolchains :
206+ python_register_toolchains (
207+ name = toolchain_info .name ,
208+ python_version = toolchain_info .python_version ,
209+ register_coverage_tool = toolchain_info .register_coverage_tool ,
210+ ** py .defaults
211+ )
212+
187213 # Create the pythons_hub repo for the interpreter meta data and the
188214 # the various toolchains.
189215 hub_repo (
190216 name = "pythons_hub" ,
191- default_python_version = default_toolchain .python_version ,
217+ # Last toolchain is default
218+ default_python_version = py .default_python_version ,
192219 toolchain_prefixes = [
193220 render .toolchain_prefix (index , toolchain .name , _TOOLCHAIN_INDEX_PAD_LENGTH )
194- for index , toolchain in enumerate (toolchains )
221+ for index , toolchain in enumerate (py . toolchains )
195222 ],
196- toolchain_python_versions = [t .python_version for t in toolchains ],
223+ toolchain_python_versions = [t .python_version for t in py . toolchains ],
197224 # The last toolchain is the default; it can't have version constraints
198225 # Despite the implication of the arg name, the values are strs, not bools
199226 toolchain_set_python_version_constraints = [
200- "True" if i != len (toolchains ) - 1 else "False"
201- for i in range (len (toolchains ))
227+ "True" if i != len (py . toolchains ) - 1 else "False"
228+ for i in range (len (py . toolchains ))
202229 ],
203- toolchain_user_repository_names = [t .name for t in toolchains ],
230+ toolchain_user_repository_names = [t .name for t in py . toolchains ],
204231 )
205232
206233 # This is require in order to support multiple version py_test
207234 # and py_binary
208235 multi_toolchain_aliases (
209236 name = "python_versions" ,
210237 python_versions = {
211- version : toolchain .name
212- for version , toolchain in global_toolchain_versions . items ()
238+ toolchain . python_version : toolchain .name
239+ for toolchain in py . toolchains
213240 },
214241 )
215242
216- if debug_info != None :
243+ if py . debug_info != None :
217244 _debug_repo (
218245 name = "rules_python_bzlmod_debug" ,
219- debug_info = json .encode_indent (debug_info ),
246+ debug_info = json .encode_indent (py . debug_info ),
220247 )
221248
222249 if bazel_features .external_deps .extension_metadata_has_reproducible :
0 commit comments