@@ -70,6 +70,7 @@ def _create_whl_repos(
7070 * ,
7171 pip_attr ,
7272 whl_overrides ,
73+ config ,
7374 available_interpreters = INTERPRETER_LABELS ,
7475 minor_mapping = MINOR_MAPPING ,
7576 evaluate_markers = evaluate_markers_py ,
@@ -81,6 +82,7 @@ def _create_whl_repos(
8182 module_ctx: {type}`module_ctx`.
8283 pip_attr: {type}`struct` - the struct that comes from the tag class iteration.
8384 whl_overrides: {type}`dict[str, struct]` - per-wheel overrides.
85+ config: TODO.
8486 get_index_urls: A function used to get the index URLs
8587 available_interpreters: {type}`dict[str, Label]` The dictionary of available
8688 interpreters that have been registered using the `python` bzlmod extension.
@@ -104,6 +106,7 @@ def _create_whl_repos(
104106 """
105107 logger = repo_utils .logger (module_ctx , "pypi:create_whl_repos" )
106108 python_interpreter_target = pip_attr .python_interpreter_target
109+ platforms = config ["platforms" ]
107110
108111 # containers to aggregate outputs from this function
109112 whl_map = {}
@@ -199,6 +202,7 @@ def _create_whl_repos(
199202 srcs = pip_attr ._evaluate_markers_srcs ,
200203 logger = logger ,
201204 ),
205+ platforms = platforms ,
202206 logger = logger ,
203207 )
204208
@@ -364,6 +368,34 @@ def _whl_repos(*, requirement, whl_library_args, download_only, netrc, auth_patt
364368
365369 return ret
366370
371+ def _configure (config , * , platform , constraint_values , target_settings , override = False , ** values ):
372+ """Set the value in the config if the value is provided"""
373+ for key , value in values .items ():
374+ if not value :
375+ continue
376+
377+ if not override and config .get (key ):
378+ continue
379+
380+ config [key ] = value
381+
382+ config .setdefault ("platforms" , {})
383+ if not platform :
384+ if constraint_values or target_settings :
385+ fail ("`platform` name must be specified when specifying `constraint_values`, `target_settings` or `urls`" )
386+ elif constraint_values or target_settings :
387+ if not override and config .get ("platforms" , {}).get (platform ):
388+ return
389+
390+ config ["platforms" ][platform ] = struct (
391+ name = platform .replace ("-" , "_" ).lower (),
392+ constraint_values = constraint_values ,
393+ target_settings = target_settings ,
394+ env = struct (), # ...
395+ )
396+ else :
397+ config ["platforms" ].pop (platform )
398+
367399def parse_modules (
368400 module_ctx ,
369401 _fail = fail ,
@@ -380,6 +412,32 @@ def parse_modules(
380412 Returns:
381413 A struct with the following attributes:
382414 """
415+ defaults = {
416+ "platforms" : {},
417+ }
418+ for mod in module_ctx .modules :
419+ if not (mod .is_root or mod .name == "rules_python" ):
420+ continue
421+
422+ for tag in mod .tags .default :
423+ _configure (
424+ # TODO @aignas 2025-05-18: actually use all of this stuff
425+ defaults ,
426+ arch_name = tag .arch_name ,
427+ constraint_values = tag .constraint_values ,
428+ env_implementation_name = tag .env_implementation_name ,
429+ env_os_name = tag .env_os_name ,
430+ env_platform_machine = tag .env_platform_machine ,
431+ env_platform_release = tag .env_platform_release ,
432+ env_platform_system = tag .env_platform_system ,
433+ env_platform_version = tag .env_platform_version ,
434+ env_sys_platform = tag .env_sys_platform ,
435+ os_name = tag .os_name ,
436+ platform = tag .platform ,
437+ target_settings = tag .target_settings ,
438+ override = mod .is_root ,
439+ )
440+
383441 whl_mods = {}
384442 for mod in module_ctx .modules :
385443 for whl_mod in mod .tags .whl_mods :
@@ -526,6 +584,7 @@ You cannot use both the additive_build_content and additive_build_content_file a
526584 pip_attr = pip_attr ,
527585 get_index_urls = get_index_urls ,
528586 whl_overrides = whl_overrides ,
587+ config = defaults ,
529588 ** kwargs
530589 )
531590 hub_whl_map .setdefault (hub_name , {})
@@ -680,6 +739,35 @@ def _pip_impl(module_ctx):
680739 else :
681740 return None
682741
742+ _default_attrs = {
743+ "arch_name" : attr .string (),
744+ "constraint_values" : attr .label_list (),
745+ # The values for PEP508 env marker evaluation during the lock file parsing
746+ "env_implementation_name" : attr .string (),
747+ "env_os_name" : attr .string (doc = "default will be inferred from {obj}`os_name`" ),
748+ "env_platform_machine" : attr .string (doc = "default will be inferred from {obj}`arch_name`" ),
749+ "env_platform_release" : attr .string (),
750+ "env_platform_system" : attr .string (doc = "default will be inferred from {obj}`os_name`" ),
751+ "env_platform_version" : attr .string (),
752+ "env_sys_platform" : attr .string (),
753+ "extra_index_urls" : attr .string_list (),
754+ "index_url" : attr .string (),
755+ "os_name" : attr .string (),
756+ "platform" : attr .string (),
757+ "target_settings" : attr .label_list (
758+ doc = """\
759+ A list of config_settings that must be satisfied by the target configuration in order for this
760+ platform to be matched during analysis phase.
761+ """ ,
762+ ),
763+ }
764+
765+ _configure_attrs = _default_attrs | {
766+ "hub_name" : attr .string (),
767+ "python_version" : attr .string (),
768+ "requirements_txt" : attr .label (),
769+ }
770+
683771def _pip_parse_ext_attrs (** kwargs ):
684772 """Get the attributes for the pip extension.
685773
@@ -936,6 +1024,22 @@ the BUILD files for wheels.
9361024""" ,
9371025 implementation = _pip_impl ,
9381026 tag_classes = {
1027+ "configure" : tag_class (
1028+ attrs = _configure_attrs ,
1029+ doc = """\
1030+ This tag class allows for more customization of how the configuration for the hub repositories is built.
1031+
1032+ This is still experimental and may be changed or removed without any notice.
1033+ """ ,
1034+ ),
1035+ "default" : tag_class (
1036+ attrs = _default_attrs ,
1037+ doc = """\
1038+ This tag class allows for more customization of how the configuration for the hub repositories is built.
1039+
1040+ This is still experimental and may be changed or removed without any notice.
1041+ """ ,
1042+ ),
9391043 "override" : _override_tag ,
9401044 "parse" : tag_class (
9411045 attrs = _pip_parse_ext_attrs (),
0 commit comments