Skip to content

Commit f2a4dd5

Browse files
authored
refactor(bzlmod)!: simplify pip.parse repository layout (#1395)
Before this PR we would generate extra `alias` repos and the extra `hub` repo for the `entry_point` macro usage. This PR removes the extras and delegates the creation of version-aware aliases to the `render_pkg_aliases` internal function. This reduces the number of repositories created by the `pip.parse` extension. Fixes #1255. BREAKING CHANGE: Note that this only affects bzlmod support, which is still beta. * Bzlmod `pip.parse` no longer generates `{hub_name}_{py_version}` hub repos. * Bzlmod `pip.parse` no longer generates `{hub_name}_{distribution}` hub repos. These repos aren't part of a public API, but were typically used for the `entry_point` macros. Instead, use `py_console_script_binary`, which is the supported replacement for entry points under bzlmod. Directly referencing the underlying distribution repos remains unsupported.
1 parent 7bb1f4a commit f2a4dd5

File tree

6 files changed

+72
-209
lines changed

6 files changed

+72
-209
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ A brief description of the categories of changes:
5858
* (bzlmod) The `entry_point` macro is no longer supported and has been removed
5959
in favour of the `py_console_script_binary` macro for `bzlmod` users.
6060

61+
* (bzlmod) The `pip.parse` no longer generates `{hub_name}_{py_version}` hub repos
62+
as the `entry_point` macro has been superseded by `py_console_script_binary`.
63+
64+
* (bzlmod) The `pip.parse` no longer generates `{hub_name}_{distribution}` hub repos.
65+
6166
### Fixed
6267

6368
* (whl_library) No longer restarts repository rule when fetching external

docs/pip_repository.md

Lines changed: 3 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

python/extensions/pip.bzl

Lines changed: 44 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,16 @@
1515
"pip module extension for use with bzlmod"
1616

1717
load("@pythons_hub//:interpreters.bzl", "DEFAULT_PYTHON_VERSION", "INTERPRETER_LABELS")
18-
load("//python:pip.bzl", "whl_library_alias")
1918
load(
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
)
2826
load("//python/pip_install:requirements_parser.bzl", parse_requirements = "parse")
27+
load("//python/private:full_version.bzl", "full_version")
2928
load("//python/private:normalize_name.bzl", "normalize_name")
3029
load("//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

162150
def _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

321273
def _pip_parse_ext_attrs():

python/pip_install/pip_hub_repository_requirements_bzlmod.bzl.tmpl

Lines changed: 0 additions & 29 deletions
This file was deleted.

0 commit comments

Comments
 (0)