@@ -39,12 +39,10 @@ Note, that here the specialization of musl vs manylinux wheels is the same in
39
39
order to ensure that the matching fails if the user requests for `musl` and we don't have it or vice versa.
40
40
"""
41
41
42
- load (":config_settings.bzl" , "is_python_config_setting" )
43
42
load (
44
43
":pip_flags.bzl" ,
45
44
"INTERNAL_FLAGS" ,
46
45
"UniversalWhlFlag" ,
47
- "UseWhlFlag" ,
48
46
"WhlLibcFlag" ,
49
47
)
50
48
@@ -53,12 +51,14 @@ FLAGS = struct(
53
51
f : str (Label ("//python/config_settings:" + f ))
54
52
for f in [
55
53
"python_version" ,
56
- "pip_whl" ,
57
54
"pip_whl_glibc_version" ,
58
55
"pip_whl_muslc_version" ,
59
56
"pip_whl_osx_arch" ,
60
57
"pip_whl_osx_version" ,
61
58
"py_linux_libc" ,
59
+ "is_pip_whl_no" ,
60
+ "is_pip_whl_only" ,
61
+ "is_pip_whl_auto" ,
62
62
]
63
63
}
64
64
)
@@ -82,8 +82,7 @@ def pip_config_settings(
82
82
target_platforms = [],
83
83
name = None ,
84
84
visibility = None ,
85
- alias_rule = None ,
86
- config_setting_rule = None ):
85
+ native = native ):
87
86
"""Generate all of the pip config settings.
88
87
89
88
Args:
@@ -100,10 +99,9 @@ def pip_config_settings(
100
99
constraint values for each condition.
101
100
visibility (list[str], optional): The visibility to be passed to the
102
101
exposed labels. All other labels will be private.
103
- alias_rule (rule): The alias rule to use for creating the
104
- objects. Can be overridden for unit tests reasons.
105
- config_setting_rule (rule): The config setting rule to use for creating the
106
- objects. Can be overridden for unit tests reasons.
102
+ native (struct): The struct containing alias and config_setting rules
103
+ to use for creating the objects. Can be overridden for unit tests
104
+ reasons.
107
105
"""
108
106
109
107
glibc_versions = ["" ] + glibc_versions
@@ -114,43 +112,25 @@ def pip_config_settings(
114
112
for t in target_platforms
115
113
]
116
114
117
- alias_rule = alias_rule or native .alias
118
-
119
- for version in python_versions :
120
- is_python = "is_python_{}" .format (version )
121
- alias_rule (
115
+ for python_version in ["" ] + python_versions :
116
+ is_python = "is_python_{}" .format (python_version or "version_unset" )
117
+ native .alias (
122
118
name = is_python ,
123
119
actual = Label ("//python/config_settings:" + is_python ),
124
120
visibility = visibility ,
125
121
)
126
122
127
- for os , cpu in target_platforms :
128
- constraint_values = []
129
- suffix = ""
130
- if os :
131
- constraint_values .append ("@platforms//os:" + os )
132
- suffix += "_" + os
133
- if cpu :
134
- constraint_values .append ("@platforms//cpu:" + cpu )
135
- suffix += "_" + cpu
136
-
137
- _sdist_config_setting (
138
- name = "sdist" + suffix ,
139
- constraint_values = constraint_values ,
140
- visibility = visibility ,
141
- config_setting_rule = config_setting_rule ,
142
- )
143
- for python_version in python_versions :
144
- _sdist_config_setting (
145
- name = "cp{}_sdist{}" .format (python_version , suffix ),
146
- python_version = python_version ,
147
- constraint_values = constraint_values ,
148
- visibility = visibility ,
149
- config_setting_rule = config_setting_rule ,
150
- )
151
-
152
- for python_version in ["" ] + python_versions :
153
- _whl_config_settings (
123
+ for os , cpu in target_platforms :
124
+ constraint_values = []
125
+ suffix = ""
126
+ if os :
127
+ constraint_values .append ("@platforms//os:" + os )
128
+ suffix += "_" + os
129
+ if cpu :
130
+ constraint_values .append ("@platforms//cpu:" + cpu )
131
+ suffix += "_" + cpu
132
+
133
+ _dist_config_settings (
154
134
suffix = suffix ,
155
135
plat_flag_values = _plat_flag_values (
156
136
os = os ,
@@ -161,34 +141,45 @@ def pip_config_settings(
161
141
),
162
142
constraint_values = constraint_values ,
163
143
python_version = python_version ,
144
+ is_python = is_python ,
164
145
visibility = visibility ,
165
- config_setting_rule = config_setting_rule ,
146
+ native = native ,
166
147
)
167
148
168
- def _whl_config_settings (* , suffix , plat_flag_values , ** kwargs ):
169
- # With the following three we cover different per-version wheels
170
- python_version = kwargs .get ("python_version" )
171
- py = "cp{}_py" .format (python_version ) if python_version else "py"
172
- pycp = "cp{}_cp3x" .format (python_version ) if python_version else "cp3x"
173
-
174
- flag_values = {}
175
-
176
- for n , f in {
177
- "{}_none_any{}" .format (py , suffix ): None ,
178
- "{}3_none_any{}" .format (py , suffix ): _flags .whl_py3 ,
179
- "{}3_abi3_any{}" .format (py , suffix ): _flags .whl_py3_abi3 ,
180
- "{}_none_any{}" .format (pycp , suffix ): _flags .whl_pycp3x ,
181
- "{}_abi3_any{}" .format (pycp , suffix ): _flags .whl_pycp3x_abi3 ,
182
- "{}_cp_any{}" .format (pycp , suffix ): _flags .whl_pycp3x_abicp ,
183
- }.items ():
184
- if f and f in flag_values :
185
- fail ("BUG" )
186
- elif f :
149
+ def _dist_config_settings (* , suffix , plat_flag_values , ** kwargs ):
150
+ flag_values = {_flags .dist : "" }
151
+
152
+ # First create an sdist, we will be building upon the flag values, which
153
+ # will ensure that each sdist config setting is the least specialized of
154
+ # all. However, we need at least one flag value to cover the case where we
155
+ # have `sdist` for any platform, hence we have a non-empty `flag_values`
156
+ # here.
157
+ _dist_config_setting (
158
+ name = "sdist{}" .format (suffix ),
159
+ flag_values = flag_values ,
160
+ is_pip_whl = FLAGS .is_pip_whl_no ,
161
+ ** kwargs
162
+ )
163
+
164
+ for name , f in [
165
+ ("py_none" , _flags .whl_py2_py3 ),
166
+ ("py3_none" , _flags .whl_py3 ),
167
+ ("py3_abi3" , _flags .whl_py3_abi3 ),
168
+ ("cp3x_none" , _flags .whl_pycp3x ),
169
+ ("cp3x_abi3" , _flags .whl_pycp3x_abi3 ),
170
+ ("cp3x_cp" , _flags .whl_pycp3x_abicp ),
171
+ ]:
172
+ if f in flag_values :
173
+ # This should never happen as all of the different whls should have
174
+ # unique flag values.
175
+ fail ("BUG: the flag {} is attempted to be added twice to the list" .format (f ))
176
+ else :
187
177
flag_values [f ] = ""
188
178
189
- _whl_config_setting (
190
- name = n ,
179
+ _dist_config_setting (
180
+ name = "{}_any{}" . format ( name , suffix ) ,
191
181
flag_values = flag_values ,
182
+ is_pip_whl = FLAGS .is_pip_whl_only ,
192
183
** kwargs
193
184
)
194
185
@@ -197,22 +188,25 @@ def _whl_config_settings(*, suffix, plat_flag_values, **kwargs):
197
188
for (suffix , flag_values ) in plat_flag_values :
198
189
flag_values = flag_values | generic_flag_values
199
190
200
- for n , f in {
201
- "{}_none_{}" .format (py , suffix ): _flags .whl_plat ,
202
- "{}3_none_{}" .format (py , suffix ): _flags .whl_plat_py3 ,
203
- "{}3_abi3_{}" .format (py , suffix ): _flags .whl_plat_py3_abi3 ,
204
- "{}_none_{}" .format (pycp , suffix ): _flags .whl_plat_pycp3x ,
205
- "{}_abi3_{}" .format (pycp , suffix ): _flags .whl_plat_pycp3x_abi3 ,
206
- "{}_cp_{}" .format (pycp , suffix ): _flags .whl_plat_pycp3x_abicp ,
207
- }.items ():
208
- if f and f in flag_values :
209
- fail ("BUG" )
210
- elif f :
191
+ for name , f in [
192
+ ("py_none" , _flags .whl_plat ),
193
+ ("py3_none" , _flags .whl_plat_py3 ),
194
+ ("py3_abi3" , _flags .whl_plat_py3_abi3 ),
195
+ ("cp3x_none" , _flags .whl_plat_pycp3x ),
196
+ ("cp3x_abi3" , _flags .whl_plat_pycp3x_abi3 ),
197
+ ("cp3x_cp" , _flags .whl_plat_pycp3x_abicp ),
198
+ ]:
199
+ if f in flag_values :
200
+ # This should never happen as all of the different whls should have
201
+ # unique flag values.
202
+ fail ("BUG: the flag {} is attempted to be added twice to the list" .format (f ))
203
+ else :
211
204
flag_values [f ] = ""
212
205
213
- _whl_config_setting (
214
- name = n ,
206
+ _dist_config_setting (
207
+ name = "{}_{}" . format ( name , suffix ) ,
215
208
flag_values = flag_values ,
209
+ is_pip_whl = FLAGS .is_pip_whl_only ,
216
210
** kwargs
217
211
)
218
212
@@ -282,85 +276,50 @@ def _plat_flag_values(os, cpu, osx_versions, glibc_versions, muslc_versions):
282
276
283
277
return ret
284
278
285
- def _whl_config_setting (* , name , flag_values , visibility , config_setting_rule = None , ** kwargs ):
286
- config_setting_rule = config_setting_rule or _config_setting_or
287
- config_setting_rule (
288
- name = "is_" + name ,
289
- flag_values = flag_values | {
290
- FLAGS .pip_whl : UseWhlFlag .ONLY ,
291
- },
292
- default = flag_values | {
293
- _flags .whl_py2_py3 : "" ,
294
- FLAGS .pip_whl : UseWhlFlag .AUTO ,
295
- },
296
- visibility = visibility ,
297
- ** kwargs
298
- )
299
-
300
- def _sdist_config_setting (* , name , visibility , config_setting_rule = None , ** kwargs ):
301
- config_setting_rule = config_setting_rule or _config_setting_or
302
- config_setting_rule (
303
- name = "is_" + name ,
304
- flag_values = {FLAGS .pip_whl : UseWhlFlag .NO },
305
- default = {FLAGS .pip_whl : UseWhlFlag .AUTO },
306
- visibility = visibility ,
307
- ** kwargs
308
- )
279
+ def _dist_config_setting (* , name , is_pip_whl , is_python , python_version , native = native , ** kwargs ):
280
+ """A macro to create a target that matches is_pip_whl_auto and one more value.
309
281
310
- def _config_setting_or (* , name , flag_values , default , visibility , ** kwargs ):
311
- match_name = "_{}" .format (name )
312
- default_name = "_{}_default" .format (name )
282
+ Args:
283
+ name: The name of the public target.
284
+ is_pip_whl: The config setting to match in addition to
285
+ `is_pip_whl_auto` when evaluating the config setting.
286
+ is_python: The python version config_setting to match.
287
+ python_version: The python version name.
288
+ native (struct): The struct containing alias and config_setting rules
289
+ to use for creating the objects. Can be overridden for unit tests
290
+ reasons.
291
+ **kwargs: The kwargs passed to the config_setting rule. Visibility of
292
+ the main alias target is also taken from the kwargs.
293
+ """
294
+ _name = "_is_" + name
313
295
296
+ visibility = kwargs .get ("visibility" )
314
297
native .alias (
315
- name = name ,
298
+ name = "is_cp{}_{}" . format ( python_version , name ) if python_version else "is_{}" . format ( name ) ,
316
299
actual = select ({
317
- "//conditions:default" : default_name ,
318
- match_name : match_name ,
300
+ # First match by the python version
301
+ is_python : _name ,
302
+ "//conditions:default" : is_python ,
319
303
}),
320
304
visibility = visibility ,
321
305
)
322
306
323
- _config_setting (
324
- name = match_name ,
325
- flag_values = flag_values ,
326
- visibility = visibility ,
327
- ** kwargs
328
- )
329
- _config_setting (
330
- name = default_name ,
331
- flag_values = default ,
307
+ if python_version :
308
+ # Reuse the config_setting targets that we use with the default
309
+ # `python_version` setting.
310
+ return
311
+
312
+ config_setting_name = _name + "_setting"
313
+ native .config_setting (name = config_setting_name , ** kwargs )
314
+
315
+ # Next match by the `pip_whl` flag value and then match by the flags that
316
+ # are intrinsic to the distribution.
317
+ native .alias (
318
+ name = _name ,
319
+ actual = select ({
320
+ "//conditions:default" : FLAGS .is_pip_whl_auto ,
321
+ FLAGS .is_pip_whl_auto : config_setting_name ,
322
+ is_pip_whl : config_setting_name ,
323
+ }),
332
324
visibility = visibility ,
333
- ** kwargs
334
325
)
335
-
336
- def _config_setting (python_version = "" , ** kwargs ):
337
- if python_version :
338
- # NOTE @aignas 2024-05-26: with this we are getting about 24k internal
339
- # config_setting targets in our unit tests. Whilst the number of the
340
- # external dependencies does not dictate this number, it does mean that
341
- # bazel will take longer to parse stuff. This would be especially
342
- # noticeable in repos, which use multiple hub repos within a single
343
- # workspace.
344
- #
345
- # A way to reduce the number of targets would be:
346
- # * put them to a central location and teach this code to just alias them,
347
- # maybe we should create a pip_config_settings repo within the pip
348
- # extension, which would collect config settings for all hub_repos.
349
- # * put them in rules_python - this has the drawback of exposing things like
350
- # is_cp3.10_linux and users may start depending upon the naming
351
- # convention and this API is very unstable.
352
- is_python_config_setting (
353
- python_version = python_version ,
354
- ** kwargs
355
- )
356
- else :
357
- # We need this to ensure that there are no ambiguous matches when python_version
358
- # is unset, which usually happens when we are not using the python version aware
359
- # rules.
360
- flag_values = kwargs .pop ("flag_values" , {}) | {
361
- FLAGS .python_version : "" ,
362
- }
363
- native .config_setting (
364
- flag_values = flag_values ,
365
- ** kwargs
366
- )
0 commit comments