@@ -67,20 +67,17 @@ def _create_whl_repos(
67
67
* ,
68
68
pip_attr ,
69
69
whl_overrides ,
70
- simpleapi_cache ,
71
70
evaluate_markers = evaluate_markers ,
72
71
available_interpreters = INTERPRETER_LABELS ,
73
- simpleapi_download = simpleapi_download ):
72
+ get_index_urls = None ):
74
73
"""create all of the whl repositories
75
74
76
75
Args:
77
76
module_ctx: {type}`module_ctx`.
78
77
pip_attr: {type}`struct` - the struct that comes from the tag class iteration.
79
78
whl_overrides: {type}`dict[str, struct]` - per-wheel overrides.
80
- simpleapi_cache: {type}`dict` - an opaque dictionary used for caching the results from calling
81
- SimpleAPI evaluating all of the tag class invocations {bzl:obj}`pip.parse`.
82
79
evaluate_markers: the function to use to evaluate markers.
83
- simpleapi_download: Used for testing overrides
80
+ get_index_urls: A function used to get the index URLs
84
81
available_interpreters: {type}`dict[str, Label]` The dictionary of available
85
82
interpreters that have been registered using the `python` bzlmod extension.
86
83
The keys are in the form `python_{snake_case_version}_host`. This is to be
@@ -96,12 +93,9 @@ def _create_whl_repos(
96
93
aparent repository names for the hub repo and the values are the
97
94
arguments that will be passed to {bzl:obj}`whl_library` repository
98
95
rule.
99
- is_reproducible: {type}`bool` set to True if does not make calls to the
100
- internet to evaluate the requirements files.
101
96
"""
102
97
logger = repo_utils .logger (module_ctx , "pypi:create_whl_repos" )
103
98
python_interpreter_target = pip_attr .python_interpreter_target
104
- is_reproducible = True
105
99
106
100
# containers to aggregate outputs from this function
107
101
whl_map = {}
@@ -158,26 +152,6 @@ def _create_whl_repos(
158
152
whl_group_mapping = {}
159
153
requirement_cycles = {}
160
154
161
- # Create a new wheel library for each of the different whls
162
-
163
- get_index_urls = None
164
- if pip_attr .experimental_index_url :
165
- get_index_urls = lambda ctx , distributions : simpleapi_download (
166
- ctx ,
167
- attr = struct (
168
- index_url = pip_attr .experimental_index_url ,
169
- extra_index_urls = pip_attr .experimental_extra_index_urls or [],
170
- index_url_overrides = pip_attr .experimental_index_url_overrides or {},
171
- sources = distributions ,
172
- envsubst = pip_attr .envsubst ,
173
- # Auth related info
174
- netrc = pip_attr .netrc ,
175
- auth_patterns = pip_attr .auth_patterns ,
176
- ),
177
- cache = simpleapi_cache ,
178
- parallel_download = pip_attr .parallel_download ,
179
- )
180
-
181
155
requirements_by_platform = parse_requirements (
182
156
module_ctx ,
183
157
requirements_by_platform = requirements_files_by_platform (
@@ -258,77 +232,27 @@ def _create_whl_repos(
258
232
if v != default
259
233
})
260
234
261
- # TODO @aignas 2024-05-26: move to a separate function
262
235
for requirement in requirements :
263
- dists = requirement .whls
264
- if not pip_attr .download_only and requirement .sdist :
265
- dists = dists + [requirement .sdist ]
266
-
267
- for distribution in dists :
268
- args = dict (whl_library_args )
269
- if pip_attr .netrc :
270
- args ["netrc" ] = pip_attr .netrc
271
- if pip_attr .auth_patterns :
272
- args ["auth_patterns" ] = pip_attr .auth_patterns
273
-
274
- if not distribution .filename .endswith (".whl" ):
275
- # pip is not used to download wheels and the python
276
- # `whl_library` helpers are only extracting things, however
277
- # for sdists, they will be built by `pip`, so we still
278
- # need to pass the extra args there.
279
- args ["extra_pip_args" ] = requirement .extra_pip_args
280
-
281
- # This is no-op because pip is not used to download the wheel.
282
- args .pop ("download_only" , None )
283
-
284
- repo_name = whl_repo_name (pip_name , distribution .filename , distribution .sha256 )
285
- args ["requirement" ] = requirement .srcs .requirement
286
- args ["urls" ] = [distribution .url ]
287
- args ["sha256" ] = distribution .sha256
288
- args ["filename" ] = distribution .filename
289
- args ["experimental_target_platforms" ] = requirement .target_platforms
290
-
291
- # Pure python wheels or sdists may need to have a platform here
292
- target_platforms = None
293
- if distribution .filename .endswith ("-any.whl" ) or not distribution .filename .endswith (".whl" ):
294
- if len (requirements ) > 1 :
295
- target_platforms = requirement .target_platforms
236
+ for repo_name , (args , config_setting ) in _whl_repos (
237
+ requirement = requirement ,
238
+ whl_library_args = whl_library_args ,
239
+ download_only = pip_attr .download_only ,
240
+ netrc = pip_attr .netrc ,
241
+ auth_patterns = pip_attr .auth_patterns ,
242
+ python_version = major_minor ,
243
+ multiple_requirements_for_whl = len (requirements ) > 1. ,
244
+ ).items ():
245
+ repo_name = "{}_{}" .format (pip_name , repo_name )
246
+ if repo_name in whl_libraries :
247
+ fail ("Attempting to creating a duplicate library {} for {}" .format (
248
+ repo_name ,
249
+ whl_name ,
250
+ ))
296
251
297
252
whl_libraries [repo_name ] = args
298
-
299
- whl_map .setdefault (whl_name , {})[whl_config_setting (
300
- version = major_minor ,
301
- filename = distribution .filename ,
302
- target_platforms = target_platforms ,
303
- )] = repo_name
304
-
305
- if dists :
306
- is_reproducible = False
307
- continue
308
-
309
- # Fallback to a pip-installed wheel
310
- args = dict (whl_library_args ) # make a copy
311
- args ["requirement" ] = requirement .srcs .requirement_line
312
- if requirement .extra_pip_args :
313
- args ["extra_pip_args" ] = requirement .extra_pip_args
314
-
315
- if pip_attr .download_only :
316
- args .setdefault ("experimental_target_platforms" , requirement .target_platforms )
317
-
318
- target_platforms = requirement .target_platforms if len (requirements ) > 1 else []
319
- repo_name = pypi_repo_name (
320
- pip_name ,
321
- whl_name ,
322
- * target_platforms
323
- )
324
- whl_libraries [repo_name ] = args
325
- whl_map .setdefault (whl_name , {})[whl_config_setting (
326
- version = major_minor ,
327
- target_platforms = target_platforms or None ,
328
- )] = repo_name
253
+ whl_map .setdefault (whl_name , {})[config_setting ] = repo_name
329
254
330
255
return struct (
331
- is_reproducible = is_reproducible ,
332
256
whl_map = whl_map ,
333
257
exposed_packages = {
334
258
whl_name : None
@@ -339,11 +263,88 @@ def _create_whl_repos(
339
263
whl_libraries = whl_libraries ,
340
264
)
341
265
342
- def parse_modules (module_ctx , _fail = fail , ** kwargs ):
266
+ def _whl_repos (* , requirement , whl_library_args , download_only , netrc , auth_patterns , multiple_requirements_for_whl = False , python_version ):
267
+ ret = {}
268
+
269
+ dists = requirement .whls
270
+ if not download_only and requirement .sdist :
271
+ dists = dists + [requirement .sdist ]
272
+
273
+ for distribution in dists :
274
+ args = dict (whl_library_args )
275
+ if netrc :
276
+ args ["netrc" ] = netrc
277
+ if auth_patterns :
278
+ args ["auth_patterns" ] = auth_patterns
279
+
280
+ if not distribution .filename .endswith (".whl" ):
281
+ # pip is not used to download wheels and the python
282
+ # `whl_library` helpers are only extracting things, however
283
+ # for sdists, they will be built by `pip`, so we still
284
+ # need to pass the extra args there.
285
+ args ["extra_pip_args" ] = requirement .extra_pip_args
286
+
287
+ # This is no-op because pip is not used to download the wheel.
288
+ args .pop ("download_only" , None )
289
+
290
+ args ["requirement" ] = requirement .srcs .requirement
291
+ args ["urls" ] = [distribution .url ]
292
+ args ["sha256" ] = distribution .sha256
293
+ args ["filename" ] = distribution .filename
294
+ args ["experimental_target_platforms" ] = requirement .target_platforms
295
+
296
+ # Pure python wheels or sdists may need to have a platform here
297
+ target_platforms = None
298
+ if distribution .filename .endswith ("-any.whl" ) or not distribution .filename .endswith (".whl" ):
299
+ if multiple_requirements_for_whl :
300
+ target_platforms = requirement .target_platforms
301
+
302
+ repo_name = whl_repo_name (
303
+ distribution .filename ,
304
+ distribution .sha256 ,
305
+ )
306
+ ret [repo_name ] = (
307
+ args ,
308
+ whl_config_setting (
309
+ version = python_version ,
310
+ filename = distribution .filename ,
311
+ target_platforms = target_platforms ,
312
+ ),
313
+ )
314
+
315
+ if ret :
316
+ return ret
317
+
318
+ # Fallback to a pip-installed wheel
319
+ args = dict (whl_library_args ) # make a copy
320
+ args ["requirement" ] = requirement .srcs .requirement_line
321
+ if requirement .extra_pip_args :
322
+ args ["extra_pip_args" ] = requirement .extra_pip_args
323
+
324
+ if download_only :
325
+ args .setdefault ("experimental_target_platforms" , requirement .target_platforms )
326
+
327
+ target_platforms = requirement .target_platforms if multiple_requirements_for_whl else []
328
+ repo_name = pypi_repo_name (
329
+ normalize_name (requirement .distribution ),
330
+ * target_platforms
331
+ )
332
+ ret [repo_name ] = (
333
+ args ,
334
+ whl_config_setting (
335
+ version = python_version ,
336
+ target_platforms = target_platforms or None ,
337
+ ),
338
+ )
339
+
340
+ return ret
341
+
342
+ def parse_modules (module_ctx , _fail = fail , simpleapi_download = simpleapi_download , ** kwargs ):
343
343
"""Implementation of parsing the tag classes for the extension and return a struct for registering repositories.
344
344
345
345
Args:
346
346
module_ctx: {type}`module_ctx` module context.
347
+ simpleapi_download: Used for testing overrides
347
348
_fail: {type}`function` the failure function, mainly for testing.
348
349
**kwargs: Extra arguments passed to the layers below.
349
350
@@ -460,10 +461,29 @@ You cannot use both the additive_build_content and additive_build_content_file a
460
461
else :
461
462
pip_hub_map [pip_attr .hub_name ].python_versions .append (pip_attr .python_version )
462
463
464
+ get_index_urls = None
465
+ if pip_attr .experimental_index_url :
466
+ is_reproducible = False
467
+ get_index_urls = lambda ctx , distributions : simpleapi_download (
468
+ ctx ,
469
+ attr = struct (
470
+ index_url = pip_attr .experimental_index_url ,
471
+ extra_index_urls = pip_attr .experimental_extra_index_urls or [],
472
+ index_url_overrides = pip_attr .experimental_index_url_overrides or {},
473
+ sources = distributions ,
474
+ envsubst = pip_attr .envsubst ,
475
+ # Auth related info
476
+ netrc = pip_attr .netrc ,
477
+ auth_patterns = pip_attr .auth_patterns ,
478
+ ),
479
+ cache = simpleapi_cache ,
480
+ parallel_download = pip_attr .parallel_download ,
481
+ )
482
+
463
483
out = _create_whl_repos (
464
484
module_ctx ,
465
485
pip_attr = pip_attr ,
466
- simpleapi_cache = simpleapi_cache ,
486
+ get_index_urls = get_index_urls ,
467
487
whl_overrides = whl_overrides ,
468
488
** kwargs
469
489
)
@@ -476,7 +496,6 @@ You cannot use both the additive_build_content and additive_build_content_file a
476
496
extra_aliases [hub_name ].setdefault (whl_name , {}).update (aliases )
477
497
exposed_packages .setdefault (hub_name , {}).update (out .exposed_packages )
478
498
whl_libraries .update (out .whl_libraries )
479
- is_reproducible = is_reproducible and out .is_reproducible
480
499
481
500
# TODO @aignas 2024-04-05: how do we support different requirement
482
501
# cycles for different abis/oses? For now we will need the users to
0 commit comments