Skip to content

Commit 13d160b

Browse files
committed
fix(pip.parse): allow users to add extra aliases to the hub repo.
Fixes bazel-contrib#2187
1 parent 163f5c0 commit 13d160b

File tree

8 files changed

+71
-30
lines changed

8 files changed

+71
-30
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ A brief description of the categories of changes:
5858
and one extra file `requirements_universal.txt` if you prefer a single file.
5959
The `requirements.txt` file may be removed in the future.
6060
* The rules_python version is now reported in `//python/features.bzl#features.version`
61+
* (pip.parse) {attr}`pip.parse.extra_hub_aliases` can now be used to expose extra
62+
targets created by annotations in whl repositories.
63+
Fixes [#2187](https://github.com/bazelbuild/rules_python/issues/2187).
6164

6265
{#v0-0-0-removed}
6366
### Removed

examples/bzlmod/BUILD.bazel

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,24 @@ py_test_with_transition(
6969
# to run some of the tests.
7070
# See: https://github.com/bazelbuild/bazel-skylib/blob/main/docs/build_test_doc.md
7171
build_test(
72-
name = "all_wheels",
72+
name = "all_wheels_build_test",
7373
targets = all_whl_requirements,
7474
)
7575

7676
build_test(
77-
name = "all_data_requirements",
77+
name = "all_data_requirements_build_test",
7878
targets = all_data_requirements,
7979
)
8080

8181
build_test(
82-
name = "all_requirements",
82+
name = "all_requirements_build_test",
8383
targets = all_requirements,
8484
)
85+
86+
# Check the annotations API
87+
build_test(
88+
name = "extra_annotation_targets_build_test",
89+
targets = [
90+
"@pip//wheel:generated_file",
91+
],
92+
)

examples/bzlmod/MODULE.bazel

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,9 @@ pip.parse(
183183
"cp39_linux_*",
184184
"cp39_*",
185185
],
186+
extra_hub_aliases = {
187+
"wheel": ["generated_file"],
188+
},
186189
hub_name = "pip",
187190
python_version = "3.9",
188191
requirements_lock = "requirements_lock_3_9.txt",

examples/bzlmod/MODULE.bazel.lock

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

python/private/pypi/extension.bzl

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ def _create_whl_repos(
6868
pip_attr,
6969
whl_overrides,
7070
simpleapi_cache,
71-
whl_mods,
7271
available_interpreters = INTERPRETER_LABELS,
7372
simpleapi_download = simpleapi_download):
7473
"""create all of the whl repositories
@@ -105,7 +104,10 @@ def _create_whl_repos(
105104
# containers to aggregate outputs from this function
106105
whl_map = {}
107106
exposed_packages = {}
108-
extra_aliases = {}
107+
extra_aliases = {
108+
whl_name: {alias: True for alias in aliases}
109+
for whl_name, aliases in pip_attr.extra_hub_aliases.items()
110+
}
109111
whl_libraries = {}
110112

111113
# if we do not have the python_interpreter set in the attributes
@@ -140,14 +142,6 @@ def _create_whl_repos(
140142
for mod, whl_name in pip_attr.whl_modifications.items():
141143
whl_modifications[normalize_name(whl_name)] = mod
142144

143-
annotation = json.decode(module_ctx.read(mod))
144-
if annotation.additive_build_content:
145-
extra_aliases.setdefault(whl_name, {}).update({
146-
line.partition("name = ")[-1].strip("\"',"): True
147-
for line in annotation.build_content.split("\n")
148-
if line.lstrip().beginswith("name = ")
149-
})
150-
151145
if pip_attr.experimental_requirement_cycles:
152146
requirement_cycles = {
153147
name: [normalize_name(whl_name) for whl_name in whls]
@@ -489,15 +483,14 @@ You cannot use both the additive_build_content and additive_build_content_file a
489483
pip_attr = pip_attr,
490484
simpleapi_cache = simpleapi_cache,
491485
whl_overrides = whl_overrides,
492-
whl_mods = whl_mods,
493486
**kwargs
494487
)
495488
hub_whl_map.setdefault(hub_name, {})
496489
for key, settings in out.whl_map.items():
497490
hub_whl_map[hub_name].setdefault(key, []).extend(settings)
498491
extra_aliases.setdefault(hub_name, {})
499-
for whl_name, extra_aliases in out.extra_aliases.items():
500-
extra_aliases[hub_name].setdefault(whl_name, {}).update(extra_aliases)
492+
for whl_name, aliases in out.extra_aliases.items():
493+
extra_aliases[hub_name].setdefault(whl_name, {}).update(aliases)
501494
exposed_packages.setdefault(hub_name, {}).update(out.exposed_packages)
502495
whl_libraries.update(out.whl_libraries)
503496
is_reproducible = is_reproducible and out.is_reproducible
@@ -617,6 +610,7 @@ def _pip_impl(module_ctx):
617610
hub_repository(
618611
name = hub_name,
619612
repo_name = hub_name,
613+
extra_hub_aliases = mods.extra_aliases.get(hub_name, {}),
620614
whl_map = {
621615
key: json.encode(value)
622616
for key, value in whl_map.items()
@@ -703,6 +697,16 @@ The indexes must support Simple API as described here:
703697
https://packaging.python.org/en/latest/specifications/simple-repository-api/
704698
""",
705699
),
700+
"extra_hub_aliases": attr.string_list_dict(
701+
doc = """\
702+
Extra aliases to make for specific wheels in the hub repo. This is useful when
703+
paired with the {attr}`whl_modifications`.
704+
705+
:::{versionadded} 0.38.0
706+
:::
707+
""",
708+
mandatory = False,
709+
),
706710
"hub_name": attr.string(
707711
mandatory = True,
708712
doc = """

python/private/pypi/hub_repository.bzl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def _impl(rctx):
3535
key: [whl_alias(**v) for v in json.decode(values)]
3636
for key, values in rctx.attr.whl_map.items()
3737
},
38+
extra_hub_aliases = rctx.attr.extra_hub_aliases,
3839
requirement_cycles = rctx.attr.groups,
3940
)
4041
for path, contents in aliases.items():
@@ -65,6 +66,10 @@ def _impl(rctx):
6566

6667
hub_repository = repository_rule(
6768
attrs = {
69+
"extra_hub_aliases": attr.string_list_dict(
70+
doc = "Extra aliases to make for specific wheels in the hub repo.",
71+
mandatory = True,
72+
),
6873
"groups": attr.string_list_dict(
6974
mandatory = False,
7075
),

python/private/pypi/render_pkg_aliases.bzl

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ def _render_whl_library_alias(
117117
**kwargs
118118
)
119119

120-
def _render_common_aliases(*, name, aliases, group_name = None):
120+
def _render_common_aliases(*, name, aliases, extra_aliases = [], group_name = None):
121121
lines = [
122122
"""load("@bazel_skylib//lib:selects.bzl", "selects")""",
123123
"""package(default_visibility = ["//visibility:public"])""",
@@ -153,12 +153,17 @@ def _render_common_aliases(*, name, aliases, group_name = None):
153153
target_name = target_name,
154154
visibility = ["//_groups:__subpackages__"] if name.startswith("_") else None,
155155
)
156-
for target_name, name in {
157-
PY_LIBRARY_PUBLIC_LABEL: PY_LIBRARY_IMPL_LABEL if group_name else PY_LIBRARY_PUBLIC_LABEL,
158-
WHEEL_FILE_PUBLIC_LABEL: WHEEL_FILE_IMPL_LABEL if group_name else WHEEL_FILE_PUBLIC_LABEL,
159-
DATA_LABEL: DATA_LABEL,
160-
DIST_INFO_LABEL: DIST_INFO_LABEL,
161-
}.items()
156+
for target_name, name in (
157+
{
158+
PY_LIBRARY_PUBLIC_LABEL: PY_LIBRARY_IMPL_LABEL if group_name else PY_LIBRARY_PUBLIC_LABEL,
159+
WHEEL_FILE_PUBLIC_LABEL: WHEEL_FILE_IMPL_LABEL if group_name else WHEEL_FILE_PUBLIC_LABEL,
160+
DATA_LABEL: DATA_LABEL,
161+
DIST_INFO_LABEL: DIST_INFO_LABEL,
162+
} | {
163+
x: x
164+
for x in extra_aliases
165+
}
166+
).items()
162167
],
163168
)
164169
if group_name:
@@ -177,7 +182,7 @@ def _render_common_aliases(*, name, aliases, group_name = None):
177182

178183
return "\n\n".join(lines)
179184

180-
def render_pkg_aliases(*, aliases, requirement_cycles = None):
185+
def render_pkg_aliases(*, aliases, requirement_cycles = None, extra_hub_aliases = {}):
181186
"""Create alias declarations for each PyPI package.
182187
183188
The aliases should be appended to the pip_repository BUILD.bazel file. These aliases
@@ -188,6 +193,8 @@ def render_pkg_aliases(*, aliases, requirement_cycles = None):
188193
aliases: dict, the keys are normalized distribution names and values are the
189194
whl_alias instances.
190195
requirement_cycles: any package groups to also add.
196+
extra_hub_aliases: The list of extra aliases for each whl to be added
197+
in addition to the default ones.
191198
192199
Returns:
193200
A dict of file paths and their contents.
@@ -215,6 +222,7 @@ def render_pkg_aliases(*, aliases, requirement_cycles = None):
215222
"{}/BUILD.bazel".format(normalize_name(name)): _render_common_aliases(
216223
name = normalize_name(name),
217224
aliases = pkg_aliases,
225+
extra_aliases = extra_hub_aliases.get(name, []),
218226
group_name = whl_group_mapping.get(normalize_name(name)),
219227
).strip()
220228
for name, pkg_aliases in aliases.items()

tests/pypi/extension/extension_tests.bzl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ def _parse(
105105
experimental_index_url = "",
106106
experimental_requirement_cycles = {},
107107
experimental_target_platforms = [],
108+
extra_hub_aliases = {},
108109
extra_pip_args = [],
109110
isolated = True,
110111
netrc = None,
@@ -130,6 +131,7 @@ def _parse(
130131
experimental_index_url = experimental_index_url,
131132
experimental_requirement_cycles = experimental_requirement_cycles,
132133
experimental_target_platforms = experimental_target_platforms,
134+
extra_hub_aliases = extra_hub_aliases,
133135
extra_pip_args = extra_pip_args,
134136
hub_name = hub_name,
135137
isolated = isolated,
@@ -204,6 +206,9 @@ filegroup(
204206
hub_name = "pypi",
205207
python_version = "3.15",
206208
requirements_lock = "requirements.txt",
209+
extra_hub_aliases = {
210+
"simple": ["foo"],
211+
},
207212
whl_modifications = {
208213
"@whl_mods_hub//:simple.json": "simple",
209214
},
@@ -221,9 +226,7 @@ filegroup(
221226
pypi.is_reproducible().equals(True)
222227
pypi.exposed_packages().contains_exactly({"pypi": []})
223228
pypi.extra_aliases().contains_exactly({
224-
"pypi": {
225-
"simple": "foo",
226-
}
229+
"pypi": {"simple": ["foo"]},
227230
})
228231
pypi.hub_group_map().contains_exactly({"pypi": {}})
229232
pypi.hub_whl_map().contains_exactly({"pypi": {

0 commit comments

Comments
 (0)