1515"pip module extension for use with bzlmod"
1616
1717load ("@pythons_hub//:interpreters.bzl" , "DEFAULT_PYTHON_VERSION" , "INTERPRETER_LABELS" )
18- load ("//python:pip.bzl" , "whl_library_alias" )
1918load (
2019 "//python/pip_install:pip_repository.bzl" ,
2120 "locked_requirements_label" ,
2221 "pip_hub_repository_bzlmod" ,
2322 "pip_repository_attrs" ,
24- "pip_repository_bzlmod" ,
2523 "use_isolated" ,
2624 "whl_library" ,
2725)
2826load ("//python/pip_install:requirements_parser.bzl" , parse_requirements = "parse" )
27+ load ("//python/private:full_version.bzl" , "full_version" )
2928load ("//python/private:normalize_name.bzl" , "normalize_name" )
3029load ("//python/private:version_label.bzl" , "version_label" )
3130
@@ -78,11 +77,11 @@ You cannot use both the additive_build_content and additive_build_content_file a
7877 whl_mods = whl_mods ,
7978 )
8079
81- def _create_versioned_pip_and_whl_repos (module_ctx , pip_attr , whl_map ):
80+ def _create_whl_repos (module_ctx , pip_attr , whl_map ):
8281 python_interpreter_target = pip_attr .python_interpreter_target
8382
8483 # if we do not have the python_interpreter set in the attributes
85- # we programtically find it.
84+ # we programmatically find it.
8685 hub_name = pip_attr .hub_name
8786 if python_interpreter_target == None :
8887 python_name = "python_" + version_label (pip_attr .python_version , sep = "_" )
@@ -104,23 +103,12 @@ def _create_versioned_pip_and_whl_repos(module_ctx, pip_attr, whl_map):
104103 requrements_lock = locked_requirements_label (module_ctx , pip_attr )
105104
106105 # Parse the requirements file directly in starlark to get the information
107- # needed for the whl_libary declarations below. This is needed to contain
108- # the pip_repository logic to a single module extension.
106+ # needed for the whl_libary declarations below.
109107 requirements_lock_content = module_ctx .read (requrements_lock )
110108 parse_result = parse_requirements (requirements_lock_content )
111109 requirements = parse_result .requirements
112110 extra_pip_args = pip_attr .extra_pip_args + parse_result .options
113111
114- # Create the repository where users load the `requirement` macro. Under bzlmod
115- # this does not create the install_deps() macro.
116- # TODO: we may not need this repository once we have entry points
117- # supported. For now a user can access this repository and use
118- # the entrypoint functionality.
119- pip_repository_bzlmod (
120- name = pip_name ,
121- repo_name = pip_name ,
122- requirements_lock = pip_attr .requirements_lock ,
123- )
124112 if hub_name not in whl_map :
125113 whl_map [hub_name ] = {}
126114
@@ -157,12 +145,12 @@ def _create_versioned_pip_and_whl_repos(module_ctx, pip_attr, whl_map):
157145 if whl_name not in whl_map [hub_name ]:
158146 whl_map [hub_name ][whl_name ] = {}
159147
160- whl_map [hub_name ][whl_name ][pip_attr .python_version ] = pip_name + "_"
148+ whl_map [hub_name ][whl_name ][full_version ( pip_attr .python_version ) ] = pip_name + "_"
161149
162150def _pip_impl (module_ctx ):
163- """Implementation of a class tag that creates the pip hub(s) and corresponding pip spoke, alias and whl repositories.
151+ """Implementation of a class tag that creates the pip hub and corresponding pip spoke whl repositories.
164152
165- This implmentation iterates through all of the `pip.parse` calls and creates
153+ This implementation iterates through all of the `pip.parse` calls and creates
166154 different pip hub repositories based on the "hub_name". Each of the
167155 pip calls create spoke repos that uses a specific Python interpreter.
168156
@@ -196,52 +184,33 @@ def _pip_impl(module_ctx):
196184 Both of these pip spokes contain requirements files that includes websocket
197185 and its dependencies.
198186
199- Two different repositories are created for the two spokes:
200-
201- - @@rules_python~override~pip~pip_39
202- - @@rules_python~override~pip~pip_310
203-
204- The different spoke names are a combination of the hub_name and the Python version.
205- In the future we may remove this repository, but we do not support entry points.
206- yet, and that functionality exists in these repos.
207-
208187 We also need repositories for the wheels that the different pip spokes contain.
209188 For each Python version a different wheel repository is created. In our example
210- each pip spoke had a requirments file that contained websockets. We
189+ each pip spoke had a requirements file that contained websockets. We
211190 then create two different wheel repositories that are named the following.
212191
213192 - @@rules_python~override~pip~pip_39_websockets
214193 - @@rules_python~override~pip~pip_310_websockets
215194
216- And if the wheel has any other dependies subsequest wheels are created in the same fashion.
217-
218- We also create a repository for the wheel alias. We want to just use the syntax
219- 'requirement("websockets")' we need to have an alias repository that is named:
195+ And if the wheel has any other dependencies subsequent wheels are created in the same fashion.
220196
221- - @@rules_python~override~pip~pip_websockets
222-
223- This repository contains alias statements for the different wheel components (pkg, data, etc).
224- Each of those aliases has a select that resolves to a spoke repository depending on
225- the Python version.
197+ The hub repository has aliases for `pkg`, `data`, etc, which have a select that resolves to
198+ a spoke repository depending on the Python version.
226199
227200 Also we may have more than one hub as defined in a MODULES.bazel file. So we could have multiple
228201 hubs pointing to various different pip spokes.
229202
230- Some other business rules notes. A hub can only have one spoke per Python version. We cannot
203+ Some other business rules notes. A hub can only have one spoke per Python version. We cannot
231204 have a hub named "pip" that has two spokes that use the Python 3.9 interpreter. Second
232- we cannot have the same hub name used in submodules . The hub name has to be globally
205+ we cannot have the same hub name used in sub-modules . The hub name has to be globally
233206 unique.
234207
235- This implementation reuses elements of non-bzlmod code and also reuses the first implementation
236- of pip bzlmod, but adds the capability to have multiple pip.parse calls.
237-
238208 This implementation also handles the creation of whl_modification JSON files that are used
239- during the creation of wheel libraries. These JSON files used via the annotations argument
209+ during the creation of wheel libraries. These JSON files used via the annotations argument
240210 when calling wheel_installer.py.
241211
242212 Args:
243213 module_ctx: module contents
244-
245214 """
246215
247216 # Build all of the wheel modifications if the tag class is called.
@@ -259,63 +228,46 @@ def _pip_impl(module_ctx):
259228 for mod in module_ctx .modules :
260229 for pip_attr in mod .tags .parse :
261230 hub_name = pip_attr .hub_name
262- if hub_name in pip_hub_map :
263- # We cannot have two hubs with the same name in different
264- # modules.
265- if pip_hub_map [hub_name ].module_name != mod .name :
266- fail ((
267- "Duplicate cross-module pip hub named '{hub}': pip hub " +
268- "names must be unique across modules. First defined " +
269- "by module '{first_module}', second attempted by " +
270- "module '{second_module}'"
271- ).format (
272- hub = hub_name ,
273- first_module = pip_hub_map [hub_name ].module_name ,
274- second_module = mod .name ,
275- ))
276-
277- if pip_attr .python_version in pip_hub_map [hub_name ].python_versions :
278- fail ((
279- "Duplicate pip python version '{version}' for hub " +
280- "'{hub}' in module '{module}': the Python versions " +
281- "used for a hub must be unique"
282- ).format (
283- hub = hub_name ,
284- module = mod .name ,
285- version = pip_attr .python_version ,
286- ))
287- else :
288- pip_hub_map [pip_attr .hub_name ].python_versions .append (pip_attr .python_version )
289- else :
231+ if hub_name not in pip_hub_map :
290232 pip_hub_map [pip_attr .hub_name ] = struct (
291233 module_name = mod .name ,
292234 python_versions = [pip_attr .python_version ],
293235 )
236+ elif pip_hub_map [hub_name ].module_name != mod .name :
237+ # We cannot have two hubs with the same name in different
238+ # modules.
239+ fail ((
240+ "Duplicate cross-module pip hub named '{hub}': pip hub " +
241+ "names must be unique across modules. First defined " +
242+ "by module '{first_module}', second attempted by " +
243+ "module '{second_module}'"
244+ ).format (
245+ hub = hub_name ,
246+ first_module = pip_hub_map [hub_name ].module_name ,
247+ second_module = mod .name ,
248+ ))
294249
295- _create_versioned_pip_and_whl_repos (module_ctx , pip_attr , hub_whl_map )
250+ elif pip_attr .python_version in pip_hub_map [hub_name ].python_versions :
251+ fail ((
252+ "Duplicate pip python version '{version}' for hub " +
253+ "'{hub}' in module '{module}': the Python versions " +
254+ "used for a hub must be unique"
255+ ).format (
256+ hub = hub_name ,
257+ module = mod .name ,
258+ version = pip_attr .python_version ,
259+ ))
260+ else :
261+ pip_hub_map [pip_attr .hub_name ].python_versions .append (pip_attr .python_version )
262+
263+ _create_whl_repos (module_ctx , pip_attr , hub_whl_map )
296264
297265 for hub_name , whl_map in hub_whl_map .items ():
298- for whl_name , version_map in whl_map .items ():
299- if DEFAULT_PYTHON_VERSION in version_map :
300- whl_default_version = DEFAULT_PYTHON_VERSION
301- else :
302- whl_default_version = None
303-
304- # Create the alias repositories which contains different select
305- # statements These select statements point to the different pip
306- # whls that are based on a specific version of Python.
307- whl_library_alias (
308- name = hub_name + "_" + whl_name ,
309- wheel_name = whl_name ,
310- default_version = whl_default_version ,
311- version_map = version_map ,
312- )
313-
314- # Create the hub repository for pip.
315266 pip_hub_repository_bzlmod (
316267 name = hub_name ,
317268 repo_name = hub_name ,
318- whl_library_alias_names = whl_map .keys (),
269+ whl_map = whl_map ,
270+ default_version = full_version (DEFAULT_PYTHON_VERSION ),
319271 )
320272
321273def _pip_parse_ext_attrs ():
0 commit comments