@@ -23,54 +23,12 @@ Definitions:
23
23
:suffix: Can be either empty or `_<os>_<suffix>`, which is usually used to distinguish multiple versions used for different target platforms.
24
24
:os: OS identifier that exists in `@platforms//os:<os>`.
25
25
:cpu: CPU architecture identifier that exists in `@platforms//cpu:<cpu>`.
26
- :python_tag: The Python tag as defined by the [Python Packaging Authority][packaging_spec]. E.g. `py2.py3`, `py3`, `py311`, `cp311`.
27
- :abi_tag: The ABI tag as defined by the [Python Packaging Authority][packaging_spec]. E.g. `none`, `abi3`, `cp311`, `cp311t`.
28
- :platform_tag: The Platform tag as defined by the [Python Packaging Authority][packaging_spec]. E.g. `manylinux_2_17_x86_64`.
29
- :platform_suffix: is a derivative of the `platform_tag` and is used to implement selection based on `libc` or `osx` version.
30
26
31
27
All of the config settings used by this macro are generated by
32
28
{obj}`config_settings`, for more detailed documentation on what each config
33
29
setting maps to and their precedence, refer to documentation on that page.
34
30
35
- The first group of config settings that are as follows:
36
-
37
- * `//_config:is_cp3<minor_version><suffix>` is used to select legacy `pip`
38
- based `whl` and `sdist` {obj}`whl_library` instances. Whereas other config
39
- settings are created when {obj}`pip.parse.experimental_index_url` is used.
40
- * `//_config:is_cp3<minor_version>_sdist<suffix>` is for wheels built from
41
- `sdist` in {obj}`whl_library`.
42
- * `//_config:is_cp3<minor_version>_py_<abi_tag>_any<suffix>` for wheels with
43
- `py2.py3` `python_tag` value.
44
- * `//_config:is_cp3<minor_version>_py3_<abi_tag>_any<suffix>` for wheels with
45
- `py3` `python_tag` value.
46
- * `//_config:is_cp3<minor_version>_<abi_tag>_any<suffix>` for any other wheels.
47
- * `//_config:is_cp3<minor_version>_py_<abi_tag>_<platform_suffix>` for
48
- platform-specific wheels with `py2.py3` `python_tag` value.
49
- * `//_config:is_cp3<minor_version>_py3_<abi_tag>_<platform_suffix>` for
50
- platform-specific wheels with `py3` `python_tag` value.
51
- * `//_config:is_cp3<minor_version>_<abi_tag>_<platform_suffix>` for any other
52
- platform-specific wheels.
53
-
54
- Note that wheels with `abi3` or `none` `abi_tag` values and `python_tag` values
55
- other than `py2.py3` or `py3` are compatible with the python version that is
56
- equal or higher than the one denoted in the `python_tag`. For example: `py37`
57
- and `cp37` wheels are compatible with Python 3.7 and above and in the case of
58
- the target python version being `3.11`, `rules_python` will use
59
- `//_config:is_cp311_<abi_tag>_any<suffix>` config settings.
60
-
61
- For platform-specific wheels, i.e. the ones that have their `platform_tag` as
62
- something else than `any`, we treat them as below:
63
- * `linux_<cpu>` tags assume that the target `libc` flavour is `glibc`, so this
64
- is in many ways equivalent to it being `manylinux`, but with an unspecified
65
- `libc` version.
66
- * For `osx` and `linux` OSes wheel filename will be mapped to multiple config settings:
67
- * `osx_<cpu>` and `osx_<major_version>_<minor_version>_<cpu>` where
68
- `major_version` and `minor_version` are the compatible OSX versions.
69
- * `<many|musl>linux_<cpu>` and
70
- `<many|musl>linux_<major_version>_<minor_version>_<cpu>` where the version
71
- identifiers are the compatible libc versions.
72
-
73
- [packaging_spec]: https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/
31
+ `//_config:is_cp3<minor_version><suffix>` is used to select any target platforms.
74
32
"""
75
33
76
34
load ("@bazel_skylib//lib:selects.bzl" , "selects" )
85
43
"WHEEL_FILE_IMPL_LABEL" ,
86
44
"WHEEL_FILE_PUBLIC_LABEL" ,
87
45
)
88
- load (":parse_whl_name.bzl" , "parse_whl_name" )
89
- load (":whl_target_platforms.bzl" , "whl_target_platforms" )
90
-
91
- # This value is used as sentinel value in the alias/config setting machinery
92
- # for libc and osx versions. If we encounter this version in this part of the
93
- # code, then it means that we have a bug in rules_python and that we should fix
94
- # it. It is more of an internal consistency check.
95
- _VERSION_NONE = (0 , 0 )
96
46
97
47
_NO_MATCH_ERROR_TEMPLATE = """\
98
48
No matching wheel for current configuration's Python version.
@@ -137,7 +87,7 @@ def pkg_aliases(
137
87
to bazel skylib's `selects.with_or`, so they can be tuples as well.
138
88
group_name: {type}`str` The group name that the pkg belongs to.
139
89
extra_aliases: {type}`list[str]` The extra aliases to be created.
140
- **kwargs: extra kwargs to pass to {bzl:obj}`get_filename_config_settings `.
90
+ **kwargs: extra kwargs to pass to {bzl:obj}`get_config_settings `.
141
91
"""
142
92
alias = kwargs .pop ("native" , native ).alias
143
93
select = kwargs .pop ("select" , selects .with_or )
@@ -219,21 +169,9 @@ def pkg_aliases(
219
169
actual = "//_groups:{}_whl" .format (group_name ),
220
170
)
221
171
222
- def _normalize_versions (name , versions ):
223
- if not versions :
224
- return []
225
-
226
- if _VERSION_NONE in versions :
227
- fail ("a sentinel version found in '{}', check render_pkg_aliases for bugs" .format (name ))
228
-
229
- return sorted (versions )
230
-
231
172
def multiplatform_whl_aliases (
232
173
* ,
233
- aliases = [],
234
- glibc_versions = [],
235
- muslc_versions = [],
236
- osx_versions = []):
174
+ aliases = []):
237
175
"""convert a list of aliases from filename to config_setting ones.
238
176
239
177
Exposed only for unit tests.
@@ -243,12 +181,6 @@ def multiplatform_whl_aliases(
243
181
to process. Any aliases that have the filename set will be
244
182
converted to a dict of config settings to repo names. The
245
183
struct is created by {func}`whl_config_setting`.
246
- glibc_versions: {type}`list[tuple[int, int]]` list of versions that can be
247
- used in this hub repo.
248
- muslc_versions: {type}`list[tuple[int, int]]` list of versions that can be
249
- used in this hub repo.
250
- osx_versions: {type}`list[tuple[int, int]]` list of versions that can be
251
- used in this hub repo.
252
184
253
185
Returns:
254
186
A dict with of config setting labels to repo names or the repo name itself.
@@ -258,207 +190,54 @@ def multiplatform_whl_aliases(
258
190
# We don't have any aliases, this is a repo name
259
191
return aliases
260
192
261
- # TODO @aignas 2024-11-17: we might be able to use FeatureFlagInfo and some
262
- # code gen to create a version_lt_x target, which would allow us to check
263
- # if the libc version is in a particular range.
264
- glibc_versions = _normalize_versions ("glibc_versions" , glibc_versions )
265
- muslc_versions = _normalize_versions ("muslc_versions" , muslc_versions )
266
- osx_versions = _normalize_versions ("osx_versions" , osx_versions )
267
-
268
193
ret = {}
269
- versioned_additions = {}
270
194
for alias , repo in aliases .items ():
271
195
if type (alias ) != "struct" :
272
196
ret [alias ] = repo
273
197
continue
274
- elif not (alias .filename or alias .target_platforms ):
275
- # This is an internal consistency check
276
- fail ("Expected to have either 'filename' or 'target_platforms' set, got: {}" .format (alias ))
277
198
278
- config_settings , all_versioned_settings = get_filename_config_settings (
279
- filename = alias .filename or "" ,
199
+ config_settings = get_config_settings (
280
200
target_platforms = alias .target_platforms ,
281
201
python_version = alias .version ,
282
- # If we have multiple platforms but no wheel filename, lets use different
283
- # config settings.
284
- non_whl_prefix = "sdist" if alias .filename else "" ,
285
- glibc_versions = glibc_versions ,
286
- muslc_versions = muslc_versions ,
287
- osx_versions = osx_versions ,
288
202
)
289
203
290
204
for setting in config_settings :
291
205
ret ["//_config" + setting ] = repo
292
206
293
- # Now for the versioned platform config settings, we need to select one
294
- # that best fits the bill and if there are multiple wheels, e.g.
295
- # manylinux_2_17_x86_64 and manylinux_2_28_x86_64, then we need to select
296
- # the former when the glibc is in the range of [2.17, 2.28) and then chose
297
- # the later if it is [2.28, ...). If the 2.28 wheel was not present in
298
- # the hub, then we would need to use 2.17 for all the glibc version
299
- # configurations.
300
- #
301
- # Here we add the version settings to a dict where we key the range of
302
- # versions that the whl spans. If the wheel supports musl and glibc at
303
- # the same time, we do this for each supported platform, hence the
304
- # double dict.
305
- for default_setting , versioned in all_versioned_settings .items ():
306
- versions = sorted (versioned )
307
- min_version = versions [0 ]
308
- max_version = versions [- 1 ]
309
-
310
- versioned_additions .setdefault (default_setting , {})[(min_version , max_version )] = struct (
311
- repo = repo ,
312
- settings = versioned ,
313
- )
314
-
315
- versioned = {}
316
- for default_setting , candidates in versioned_additions .items ():
317
- # Sort the candidates by the range of versions the span, so that we
318
- # start with the lowest version.
319
- for _ , candidate in sorted (candidates .items ()):
320
- # Set the default with the first candidate, which gives us the highest
321
- # compatibility. If the users want to use a higher-version than the default
322
- # they can configure the glibc_version flag.
323
- versioned .setdefault ("//_config" + default_setting , candidate .repo )
324
-
325
- # We will be overwriting previously added entries, but that is intended.
326
- for _ , setting in candidate .settings .items ():
327
- versioned ["//_config" + setting ] = candidate .repo
328
-
329
- ret .update (versioned )
330
207
return ret
331
208
332
- def get_filename_config_settings (
209
+ def get_config_settings (
333
210
* ,
334
- filename ,
335
211
target_platforms ,
336
- python_version ,
337
- glibc_versions = None ,
338
- muslc_versions = None ,
339
- osx_versions = None ,
340
- non_whl_prefix = "sdist" ):
212
+ python_version ):
341
213
"""Get the filename config settings.
342
214
343
215
Exposed only for unit tests.
344
216
345
217
Args:
346
- filename: the distribution filename (can be a whl or an sdist).
347
218
target_platforms: list[str], target platforms in "{abi}_{os}_{cpu}" format.
348
- glibc_versions: list[tuple[int, int]], list of versions.
349
- muslc_versions: list[tuple[int, int]], list of versions.
350
- osx_versions: list[tuple[int, int]], list of versions.
351
219
python_version: the python version to generate the config_settings for.
352
- non_whl_prefix: the prefix of the config setting when the whl we don't have
353
- a filename ending with ".whl".
354
220
355
221
Returns:
356
222
A tuple:
357
223
* A list of config settings that are generated by ./pip_config_settings.bzl
358
224
* The list of default version settings.
359
225
"""
360
- prefixes = []
361
- suffixes = []
362
- setting_supported_versions = {}
363
-
364
- if filename .endswith (".whl" ):
365
- parsed = parse_whl_name (filename )
366
- if parsed .python_tag == "py2.py3" :
367
- py = "py_"
368
- elif parsed .python_tag == "py3" :
369
- py = "py3_"
370
- elif parsed .python_tag .startswith ("cp" ):
371
- py = ""
372
- else :
373
- py = "py3_"
374
226
375
- abi = parsed .abi_tag
376
-
377
- # TODO @aignas 2025-04-20: test
378
- abi , _ , _ = abi .partition ("." )
379
-
380
- if parsed .platform_tag == "any" :
381
- prefixes = ["{}{}_any" .format (py , abi )]
382
- else :
383
- prefixes = ["{}{}" .format (py , abi )]
384
- suffixes = _whl_config_setting_suffixes (
385
- platform_tag = parsed .platform_tag ,
386
- glibc_versions = glibc_versions ,
387
- muslc_versions = muslc_versions ,
388
- osx_versions = osx_versions ,
389
- setting_supported_versions = setting_supported_versions ,
390
- )
391
- else :
392
- prefixes = [non_whl_prefix or "" ]
393
-
394
- py = "cp{}" .format (python_version ).replace ("." , "" )
395
227
prefixes = [
396
- "{}_{}" .format (py , prefix ) if prefix else py
397
- for prefix in prefixes
228
+ "cp{}" .format (python_version ).replace ("." , "" ),
398
229
]
399
230
400
- versioned = {
401
- ":is_{}_{}" .format (prefix , suffix ): {
402
- version : ":is_{}_{}" .format (prefix , setting )
403
- for version , setting in versions .items ()
404
- }
405
- for prefix in prefixes
406
- for suffix , versions in setting_supported_versions .items ()
407
- }
408
-
409
- if suffixes or target_platforms or versioned :
231
+ if target_platforms :
410
232
target_platforms = target_platforms or []
411
- suffixes = suffixes or [_non_versioned_platform (p ) for p in target_platforms ]
233
+ suffixes = [_non_versioned_platform (p ) for p in target_platforms ]
412
234
return [
413
235
":is_{}_{}" .format (prefix , suffix )
414
236
for prefix in prefixes
415
237
for suffix in suffixes
416
- ], versioned
238
+ ]
417
239
else :
418
- return [":is_{}" .format (p ) for p in prefixes ], setting_supported_versions
419
-
420
- def _whl_config_setting_suffixes (
421
- platform_tag ,
422
- glibc_versions ,
423
- muslc_versions ,
424
- osx_versions ,
425
- setting_supported_versions ):
426
- suffixes = []
427
- for platform_tag in platform_tag .split ("." ):
428
- for p in whl_target_platforms (platform_tag ):
429
- prefix = p .os
430
- suffix = p .cpu
431
- if "manylinux" in platform_tag :
432
- prefix = "manylinux"
433
- versions = glibc_versions
434
- elif "musllinux" in platform_tag :
435
- prefix = "musllinux"
436
- versions = muslc_versions
437
- elif p .os in ["linux" , "windows" ]:
438
- versions = [(0 , 0 )]
439
- elif p .os == "osx" :
440
- versions = osx_versions
441
- if "universal2" in platform_tag :
442
- suffix = "universal2"
443
- else :
444
- fail ("Unsupported whl os: {}" .format (p .os ))
445
-
446
- default_version_setting = "{}_{}" .format (prefix , suffix )
447
- supported_versions = {}
448
- for v in versions :
449
- if v == (0 , 0 ):
450
- suffixes .append (default_version_setting )
451
- elif v >= p .version :
452
- supported_versions [v ] = "{}_{}_{}_{}" .format (
453
- prefix ,
454
- v [0 ],
455
- v [1 ],
456
- suffix ,
457
- )
458
- if supported_versions :
459
- setting_supported_versions [default_version_setting ] = supported_versions
460
-
461
- return suffixes
240
+ return [":is_{}" .format (p ) for p in prefixes ]
462
241
463
242
def _non_versioned_platform (p , * , strict = False ):
464
243
"""A small utility function that converts 'cp311_linux_x86_64' to 'linux_x86_64'.
0 commit comments