@@ -20,20 +20,21 @@ that matches the target platform. We can leverage this fact to ensure that the
20
20
most specialized wheels are used by default with the users being able to
21
21
configure string_flag values to select the less specialized ones.
22
22
23
- The list of specialization of the dists goes like follows:
23
+ The list of specialization of the dists goes like follows (cpxyt stands for freethreaded
24
+ environments):
24
25
* sdist
25
26
* py*-none-any.whl
26
27
* py*-abi3-any.whl
27
- * py*-cpxy-any.whl
28
+ * py*-cpxy-any.whl or py*-cpxyt-any.whl
28
29
* cp*-none-any.whl
29
30
* cp*-abi3-any.whl
30
- * cp*-cpxy-plat .whl
31
+ * cp*-cpxy-any.whl or cp*-cpxyt-any .whl
31
32
* py*-none-plat.whl
32
33
* py*-abi3-plat.whl
33
- * py*-cpxy-plat.whl
34
+ * py*-cpxy-plat.whl or py*-cpxyt-plat.whl
34
35
* cp*-none-plat.whl
35
36
* cp*-abi3-plat.whl
36
- * cp*-cpxy-plat.whl
37
+ * cp*-cpxy-plat.whl or cp*-cpxyt-plat.whl
37
38
38
39
Note, that here the specialization of musl vs manylinux wheels is the same in
39
40
order to ensure that the matching fails if the user requests for `musl` and we don't have it or vice versa.
@@ -46,19 +47,24 @@ FLAGS = struct(
46
47
** {
47
48
f : str (Label ("//python/config_settings:" + f ))
48
49
for f in [
49
- "python_version" ,
50
+ "is_pip_whl_auto" ,
51
+ "is_pip_whl_no" ,
52
+ "is_pip_whl_only" ,
53
+ "is_py_freethreaded" ,
54
+ "is_py_non_freethreaded" ,
50
55
"pip_whl_glibc_version" ,
51
56
"pip_whl_muslc_version" ,
52
57
"pip_whl_osx_arch" ,
53
58
"pip_whl_osx_version" ,
54
59
"py_linux_libc" ,
55
- "is_pip_whl_no" ,
56
- "is_pip_whl_only" ,
57
- "is_pip_whl_auto" ,
60
+ "python_version" ,
58
61
]
59
62
}
60
63
)
61
64
65
+ _DEFAULT = "//conditions:default"
66
+ _INCOMPATIBLE = "@platforms//:incompatible"
67
+
62
68
# Here we create extra string flags that are just to work with the select
63
69
# selecting the most specialized match. We don't allow the user to change
64
70
# them.
@@ -170,52 +176,70 @@ def _dist_config_settings(*, suffix, plat_flag_values, **kwargs):
170
176
** kwargs
171
177
)
172
178
173
- for name , f in [
174
- ("py_none" , _flags .whl_py2_py3 ),
175
- ("py3_none" , _flags .whl_py3 ),
176
- ("py3_abi3" , _flags .whl_py3_abi3 ),
177
- ("cp3x_none" , _flags .whl_pycp3x ),
178
- ("cp3x_abi3" , _flags .whl_pycp3x_abi3 ),
179
- ("cp3x_cp" , _flags .whl_pycp3x_abicp ),
179
+ used_flags = {}
180
+
181
+ # NOTE @aignas 2024-12-01: the abi3 is not compatible with freethreaded
182
+ # builds as per PEP703 (https://peps.python.org/pep-0703/#backwards-compatibility)
183
+ #
184
+ # The discussion here also reinforces this notion:
185
+ # https://discuss.python.org/t/pep-703-making-the-global-interpreter-lock-optional-3-12-updates/26503/99
186
+
187
+ for name , f , abi in [
188
+ ("py_none" , _flags .whl_py2_py3 , None ),
189
+ ("py3_none" , _flags .whl_py3 , None ),
190
+ ("py3_abi3" , _flags .whl_py3_abi3 , (FLAGS .is_py_non_freethreaded ,)),
191
+ ("cp3x_none" , _flags .whl_pycp3x , None ),
192
+ ("cp3x_abi3" , _flags .whl_pycp3x_abi3 , (FLAGS .is_py_non_freethreaded ,)),
193
+ # The below are not specializations of one another, they are variants
194
+ ("cp3x_cp" , _flags .whl_pycp3x_abicp , (FLAGS .is_py_non_freethreaded ,)),
195
+ ("cp3x_cpt" , _flags .whl_pycp3x_abicp , (FLAGS .is_py_freethreaded ,)),
180
196
]:
181
- if f in flag_values :
197
+ if ( f , abi ) in used_flags :
182
198
# This should never happen as all of the different whls should have
183
- # unique flag values.
199
+ # unique flag values
184
200
fail ("BUG: the flag {} is attempted to be added twice to the list" .format (f ))
185
201
else :
186
202
flag_values [f ] = ""
203
+ used_flags [(f , abi )] = True
187
204
188
205
_dist_config_setting (
189
206
name = "{}_any{}" .format (name , suffix ),
190
207
flag_values = flag_values ,
191
208
is_pip_whl = FLAGS .is_pip_whl_only ,
209
+ abi = abi ,
192
210
** kwargs
193
211
)
194
212
195
213
generic_flag_values = flag_values
214
+ generic_used_flags = used_flags
196
215
197
216
for (suffix , flag_values ) in plat_flag_values :
217
+ used_flags = {(f , None ): True for f in flag_values } | generic_used_flags
198
218
flag_values = flag_values | generic_flag_values
199
219
200
- for name , f in [
201
- ("py_none" , _flags .whl_plat ),
202
- ("py3_none" , _flags .whl_plat_py3 ),
203
- ("py3_abi3" , _flags .whl_plat_py3_abi3 ),
204
- ("cp3x_none" , _flags .whl_plat_pycp3x ),
205
- ("cp3x_abi3" , _flags .whl_plat_pycp3x_abi3 ),
206
- ("cp3x_cp" , _flags .whl_plat_pycp3x_abicp ),
220
+ for name , f , abi in [
221
+ ("py_none" , _flags .whl_plat , None ),
222
+ ("py3_none" , _flags .whl_plat_py3 , None ),
223
+ ("py3_abi3" , _flags .whl_plat_py3_abi3 , (FLAGS .is_py_non_freethreaded ,)),
224
+ ("cp3x_none" , _flags .whl_plat_pycp3x , None ),
225
+ ("cp3x_abi3" , _flags .whl_plat_pycp3x_abi3 , (FLAGS .is_py_non_freethreaded ,)),
226
+ # The below are not specializations of one another, they are variants
227
+ ("cp3x_cp" , _flags .whl_plat_pycp3x_abicp , (FLAGS .is_py_non_freethreaded ,)),
228
+ ("cp3x_cpt" , _flags .whl_plat_pycp3x_abicp , (FLAGS .is_py_freethreaded ,)),
207
229
]:
208
- if f in flag_values :
230
+ if ( f , abi ) in used_flags :
209
231
# This should never happen as all of the different whls should have
210
232
# unique flag values.
211
233
fail ("BUG: the flag {} is attempted to be added twice to the list" .format (f ))
212
234
else :
213
235
flag_values [f ] = ""
236
+ used_flags [(f , abi )] = True
214
237
215
238
_dist_config_setting (
216
239
name = "{}_{}" .format (name , suffix ),
217
240
flag_values = flag_values ,
218
241
is_pip_whl = FLAGS .is_pip_whl_only ,
242
+ abi = abi ,
219
243
** kwargs
220
244
)
221
245
@@ -285,7 +309,7 @@ def _plat_flag_values(os, cpu, osx_versions, glibc_versions, muslc_versions):
285
309
286
310
return ret
287
311
288
- def _dist_config_setting (* , name , is_python , python_version , is_pip_whl = None , native = native , ** kwargs ):
312
+ def _dist_config_setting (* , name , is_python , python_version , is_pip_whl = None , abi = None , native = native , ** kwargs ):
289
313
"""A macro to create a target that matches is_pip_whl_auto and one more value.
290
314
291
315
Args:
@@ -294,6 +318,10 @@ def _dist_config_setting(*, name, is_python, python_version, is_pip_whl = None,
294
318
`is_pip_whl_auto` when evaluating the config setting.
295
319
is_python: The python version config_setting to match.
296
320
python_version: The python version name.
321
+ abi: {type}`tuple[Label]` A collection of ABI config settings that are
322
+ compatible with the given dist config setting. For example, if only
323
+ non-freethreaded python builds are allowed, add
324
+ FLAGS.is_py_non_freethreaded here.
297
325
native (struct): The struct containing alias and config_setting rules
298
326
to use for creating the objects. Can be overridden for unit tests
299
327
reasons.
@@ -306,9 +334,9 @@ def _dist_config_setting(*, name, is_python, python_version, is_pip_whl = None,
306
334
native .alias (
307
335
name = "is_cp{}_{}" .format (python_version , name ) if python_version else "is_{}" .format (name ),
308
336
actual = select ({
309
- # First match by the python version
310
- is_python : _name ,
311
- "//conditions:default" : is_python ,
337
+ # First match by the python version and then by ABI
338
+ is_python : _name + ( "_abi" if abi else "" ) ,
339
+ _DEFAULT : _INCOMPATIBLE ,
312
340
}),
313
341
visibility = visibility ,
314
342
)
@@ -325,12 +353,23 @@ def _dist_config_setting(*, name, is_python, python_version, is_pip_whl = None,
325
353
config_setting_name = _name + "_setting"
326
354
native .config_setting (name = config_setting_name , ** kwargs )
327
355
356
+ if abi :
357
+ native .alias (
358
+ name = _name + "_abi" ,
359
+ actual = select (
360
+ {k : _name for k in abi } | {
361
+ _DEFAULT : _INCOMPATIBLE ,
362
+ },
363
+ ),
364
+ visibility = visibility ,
365
+ )
366
+
328
367
# Next match by the `pip_whl` flag value and then match by the flags that
329
368
# are intrinsic to the distribution.
330
369
native .alias (
331
370
name = _name ,
332
371
actual = select ({
333
- "//conditions:default" : FLAGS . is_pip_whl_auto ,
372
+ _DEFAULT : _INCOMPATIBLE ,
334
373
FLAGS .is_pip_whl_auto : config_setting_name ,
335
374
is_pip_whl : config_setting_name ,
336
375
}),
0 commit comments