@@ -72,15 +72,25 @@ def _platforms(*, python_version, minor_mapping, config):
72
72
version = python_version ,
73
73
minor_mapping = minor_mapping ,
74
74
)
75
- abi = "cp3{}" .format (python_version [2 :])
76
75
77
76
for platform , values in config .platforms .items ():
77
+ implementation = values .env ["implementation_name" ][:2 ].lower ()
78
+ abi = "{}3{}" .format (implementation , python_version [2 :])
78
79
key = "{}_{}" .format (abi , platform )
79
- platforms [key ] = env (struct (
80
+
81
+ env_ = env (struct (
80
82
abi = abi ,
81
83
os = values .os_name ,
82
84
arch = values .arch_name ,
83
85
)) | values .env
86
+ platforms [key ] = struct (
87
+ env = env_ ,
88
+ want_abis = [
89
+ v .format (* python_version .split ("." ))
90
+ for v in values .want_abis
91
+ ],
92
+ platform_tags = values .platform_tags ,
93
+ )
84
94
return platforms
85
95
86
96
def _create_whl_repos (
@@ -152,6 +162,8 @@ def _create_whl_repos(
152
162
))
153
163
python_interpreter_target = available_interpreters [python_name ]
154
164
165
+ # TODO @aignas 2025-06-29: we should not need the version in the pip_name if
166
+ # we are using pipstar and we are downloading the wheel using the downloader
155
167
pip_name = "{}_{}" .format (
156
168
hub_name ,
157
169
version_label (pip_attr .python_version ),
@@ -184,11 +196,15 @@ def _create_whl_repos(
184
196
elif config .enable_pipstar :
185
197
evaluate_markers = lambda _ , requirements : evaluate_markers_star (
186
198
requirements = requirements ,
187
- platforms = _platforms (
188
- python_version = pip_attr .python_version ,
189
- minor_mapping = minor_mapping ,
190
- config = config ,
191
- ),
199
+ platforms = {
200
+ k : p .env
201
+ # TODO @aignas 2025-07-05: update evaluate_markers_star
202
+ for k , p in _platforms (
203
+ python_version = pip_attr .python_version ,
204
+ minor_mapping = minor_mapping ,
205
+ config = config ,
206
+ ).items ()
207
+ },
192
208
)
193
209
else :
194
210
# NOTE @aignas 2024-08-02: , we will execute any interpreter that we find either
@@ -230,6 +246,11 @@ def _create_whl_repos(
230
246
),
231
247
logger = logger ,
232
248
),
249
+ platforms = _platforms (
250
+ python_version = pip_attr .python_version ,
251
+ minor_mapping = minor_mapping ,
252
+ config = config ,
253
+ ),
233
254
extra_pip_args = pip_attr .extra_pip_args ,
234
255
get_index_urls = get_index_urls ,
235
256
evaluate_markers = evaluate_markers ,
@@ -359,24 +380,16 @@ def _whl_repo(*, src, whl_library_args, is_multiple_versions, download_only, net
359
380
for p in src .target_platforms
360
381
]
361
382
362
- # Pure python wheels or sdists may need to have a platform here
363
- target_platforms = None
364
- if is_whl and not src .filename .endswith ("-any.whl" ):
365
- pass
366
- elif is_multiple_versions :
367
- target_platforms = src .target_platforms
368
-
369
383
return struct (
370
384
repo_name = whl_repo_name (src .filename , src .sha256 ),
371
385
args = args ,
372
386
config_setting = whl_config_setting (
373
387
version = python_version ,
374
- filename = src .filename ,
375
- target_platforms = target_platforms ,
388
+ target_platforms = src .target_platforms ,
376
389
),
377
390
)
378
391
379
- def _configure (config , * , platform , os_name , arch_name , config_settings , env = {}, override = False ):
392
+ def _configure (config , * , platform , os_name , arch_name , config_settings , env = {}, want_abis , platform_tags , override = False ):
380
393
"""Set the value in the config if the value is provided"""
381
394
config .setdefault ("platforms" , {})
382
395
if platform :
@@ -393,12 +406,25 @@ def _configure(config, *, platform, os_name, arch_name, config_settings, env = {
393
406
if not arch_name :
394
407
fail ("'arch_name' is required" )
395
408
409
+ if platform_tags and "any" not in platform_tags :
410
+ # the lowest priority one needs to be the first one
411
+ platform_tags = ["any" ] + platform_tags
412
+
396
413
config ["platforms" ][platform ] = struct (
397
414
name = platform .replace ("-" , "_" ).lower (),
398
415
os_name = os_name ,
399
416
arch_name = arch_name ,
400
417
config_settings = config_settings ,
401
- env = env ,
418
+ want_abis = want_abis or [
419
+ "cp{0}{1}" ,
420
+ "abi3" ,
421
+ "none" ,
422
+ ],
423
+ platform_tags = platform_tags ,
424
+ env = {
425
+ # default to this
426
+ "implementation_name" : "cpython" ,
427
+ } | env ,
402
428
)
403
429
else :
404
430
config ["platforms" ].pop (platform )
@@ -424,28 +450,42 @@ def _create_config(defaults):
424
450
arch_name = cpu ,
425
451
os_name = "linux" ,
426
452
platform = "linux_{}" .format (cpu ),
453
+ want_abis = [],
427
454
config_settings = [
428
455
"@platforms//os:linux" ,
429
456
"@platforms//cpu:{}" .format (cpu ),
430
457
],
431
- env = {"platform_version" : "0" },
458
+ platform_tags = [
459
+ "linux_*_{}" .format (cpu ),
460
+ "manylinux_*_{}" .format (cpu ),
461
+ ],
462
+ env = {
463
+ "platform_version" : "0" ,
464
+ },
432
465
)
433
- for cpu in [
434
- "aarch64" ,
435
- "x86_64" ,
436
- ] :
466
+ for cpu , platform_tag_cpus in {
467
+ "aarch64" : [ "universal2" , "arm64" ] ,
468
+ "x86_64" : [ "universal2" , "x86_64" ] ,
469
+ }. items () :
437
470
_configure (
438
471
defaults ,
439
472
arch_name = cpu ,
440
- # We choose the oldest non-EOL version at the time when we release `rules_python`.
441
- # See https://endoflife.date/macos
442
473
os_name = "osx" ,
443
474
platform = "osx_{}" .format (cpu ),
444
475
config_settings = [
445
476
"@platforms//os:osx" ,
446
477
"@platforms//cpu:{}" .format (cpu ),
447
478
],
448
- env = {"platform_version" : "14.0" },
479
+ want_abis = [],
480
+ platform_tags = [
481
+ "macosx_*_{}" .format (suffix )
482
+ for suffix in platform_tag_cpus
483
+ ],
484
+ # We choose the oldest non-EOL version at the time when we release `rules_python`.
485
+ # See https://endoflife.date/macos
486
+ env = {
487
+ "platform_version" : "14.0" ,
488
+ },
449
489
)
450
490
451
491
_configure (
@@ -457,7 +497,11 @@ def _create_config(defaults):
457
497
"@platforms//os:windows" ,
458
498
"@platforms//cpu:x86_64" ,
459
499
],
460
- env = {"platform_version" : "0" },
500
+ want_abis = [],
501
+ platform_tags = ["win_amd64" ],
502
+ env = {
503
+ "platform_version" : "0" ,
504
+ },
461
505
)
462
506
return struct (** defaults )
463
507
@@ -527,14 +571,15 @@ You cannot use both the additive_build_content and additive_build_content_file a
527
571
env = tag .env ,
528
572
os_name = tag .os_name ,
529
573
platform = tag .platform ,
574
+ platform_tags = tag .platform_tags ,
575
+ want_abis = tag .want_abis ,
530
576
override = mod .is_root ,
531
577
# TODO @aignas 2025-05-19: add more attr groups:
532
578
# * for AUTH - the default `netrc` usage could be configured through a common
533
579
# attribute.
534
580
# * for index/downloader config. This includes all of those attributes for
535
581
# overrides, etc. Index overrides per platform could be also used here.
536
- # * for whl selection - selecting preferences of which `platform_tag`s we should use
537
- # for what. We could also model the `cp313t` freethreaded as separate platforms.
582
+ # * for whl selection - We could also model the `cp313t` freethreaded as separate platforms.
538
583
)
539
584
540
585
config = _create_config (defaults )
@@ -666,7 +711,14 @@ You cannot use both the additive_build_content and additive_build_content_file a
666
711
for whl_name , aliases in out .extra_aliases .items ():
667
712
extra_aliases [hub_name ].setdefault (whl_name , {}).update (aliases )
668
713
exposed_packages .setdefault (hub_name , {}).update (out .exposed_packages )
669
- whl_libraries .update (out .whl_libraries )
714
+ for whl_name , lib in out .whl_libraries .items ():
715
+ if enable_pipstar :
716
+ whl_libraries .setdefault (whl_name , lib )
717
+ elif whl_name in lib :
718
+ fail ("'{}' already in created" .format (whl_name ))
719
+ else :
720
+ # replicate whl_libraries.update(out.whl_libraries)
721
+ whl_libraries [whl_name ] = lib
670
722
671
723
# TODO @aignas 2024-04-05: how do we support different requirement
672
724
# cycles for different abis/oses? For now we will need the users to
@@ -829,25 +881,6 @@ The list of labels to `config_setting` targets that need to be matched for the p
829
881
selected.
830
882
""" ,
831
883
),
832
- "os_name" : attr .string (
833
- doc = """\
834
- The OS name to be used.
835
-
836
- :::{note}
837
- Either this or the appropriate `env` keys should be specified.
838
- :::
839
- """ ,
840
- ),
841
- "platform" : attr .string (
842
- doc = """\
843
- A platform identifier which will be used as the unique identifier within the extension evaluation.
844
- If you are defining custom platforms in your project and don't want things to clash, use extension
845
- [isolation] feature.
846
-
847
- [isolation]: https://bazel.build/rules/lib/globals/module#use_extension.isolate
848
- """ ,
849
- ),
850
- } | {
851
884
"env" : attr .string_dict (
852
885
doc = """\
853
886
The values to use for environment markers when evaluating an expression.
@@ -873,6 +906,40 @@ This is only used if the {envvar}`RULES_PYTHON_ENABLE_PIPSTAR` is enabled.
873
906
""" ,
874
907
),
875
908
# The values for PEP508 env marker evaluation during the lock file parsing
909
+ "os_name" : attr .string (
910
+ doc = """\
911
+ The OS name to be used.
912
+
913
+ :::{note}
914
+ Either this or the appropriate `env` keys should be specified.
915
+ :::
916
+ """ ,
917
+ ),
918
+ "platform" : attr .string (
919
+ doc = """\
920
+ A platform identifier which will be used as the unique identifier within the extension evaluation.
921
+ If you are defining custom platforms in your project and don't want things to clash, use extension
922
+ [isolation] feature.
923
+
924
+ [isolation]: https://bazel.build/rules/lib/globals/module#use_extension.isolate
925
+ """ ,
926
+ ),
927
+ "platform_tags" : attr .string_list (
928
+ doc = """\
929
+ A list of `platform_tag` matchers so that we can select the best wheel based on the user
930
+ preference. Per platform we will select a single wheel and the last match from this list will
931
+ take precedence.
932
+
933
+ The items in this list can contain a single `*` character that is equivalent to `.*` regex match.
934
+ """ ,
935
+ ),
936
+ "want_abis" : attr .string_list (
937
+ doc = """\
938
+ A list of ABIs to select wheels for. The values can be either strings or include template
939
+ parameters like `{0}` which will be replaced with python version parts. e.g. `cp{0}{1}` will
940
+ result in `cp313` given the full python version is `3.13.5`.
941
+ """ ,
942
+ ),
876
943
}
877
944
878
945
_SUPPORTED_PEP508_KEYS = [
0 commit comments