Skip to content

Commit fd47903

Browse files
committed
refactor!(bzlmod): introduce pypi.install extension
With this PR we are introducing a new extension for managing PyPI dependencies and it seems that we would fix bazel-contrib#2268 in doing so. The code has been sitting around for long enough so that we have ironed out most of the bigger bugs already and the maintainers have agreed for long enough that pip.parse is not the best named, so I have chosen pypi.install. This should not actively break the code and will make some of the experimental parameters noop. This could yield to weird failures in cases where people are building docker containers, so I am thinking that we should potentially add a helpful error message prompting the users to migrate. However I am not sure how that works out when multiple module versions are at play in the same module graph.
1 parent a2773de commit fd47903

File tree

12 files changed

+4426
-2128
lines changed

12 files changed

+4426
-2128
lines changed

.bazelrc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
# (Note, we cannot use `common --deleted_packages` because the bazel version command doesn't support it)
55
# To update these lines, execute
66
# `bazel run @rules_bazel_integration_test//tools:update_deleted_packages`
7-
build --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/patches,examples/bzlmod/py_proto_library,examples/bzlmod/py_proto_library/example.com/another_proto,examples/bzlmod/py_proto_library/example.com/proto,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/another_proto,examples/py_proto_library/example.com/proto,gazelle,gazelle/manifest,gazelle/manifest/generate,gazelle/manifest/hasher,gazelle/manifest/test,gazelle/modules_mapping,gazelle/python,gazelle/pythonconfig,gazelle/python/private,tests/integration/compile_pip_requirements,tests/integration/compile_pip_requirements_test_from_external_repo,tests/integration/custom_commands,tests/integration/ignore_root_user_error,tests/integration/ignore_root_user_error/submodule,tests/integration/local_toolchains,tests/integration/pip_parse,tests/integration/pip_parse/empty,tests/integration/py_cc_toolchain_registered
8-
query --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/patches,examples/bzlmod/py_proto_library,examples/bzlmod/py_proto_library/example.com/another_proto,examples/bzlmod/py_proto_library/example.com/proto,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/another_proto,examples/py_proto_library/example.com/proto,gazelle,gazelle/manifest,gazelle/manifest/generate,gazelle/manifest/hasher,gazelle/manifest/test,gazelle/modules_mapping,gazelle/python,gazelle/pythonconfig,gazelle/python/private,tests/integration/compile_pip_requirements,tests/integration/compile_pip_requirements_test_from_external_repo,tests/integration/custom_commands,tests/integration/ignore_root_user_error,tests/integration/ignore_root_user_error/submodule,tests/integration/local_toolchains,tests/integration/pip_parse,tests/integration/pip_parse/empty,tests/integration/py_cc_toolchain_registered
7+
build --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/patches,examples/bzlmod/py_proto_library,examples/bzlmod/py_proto_library/example.com/another_proto,examples/bzlmod/py_proto_library/example.com/proto,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/another_proto,examples/py_proto_library/example.com/proto,gazelle,gazelle/manifest,gazelle/manifest/generate,gazelle/manifest/hasher,gazelle/manifest/test,gazelle/modules_mapping,gazelle/python,gazelle/python/private,gazelle/pythonconfig,tests/integration/compile_pip_requirements,tests/integration/compile_pip_requirements_test_from_external_repo,tests/integration/custom_commands,tests/integration/ignore_root_user_error,tests/integration/ignore_root_user_error/submodule,tests/integration/local_toolchains,tests/integration/pip_parse,tests/integration/pip_parse/empty,tests/integration/py_cc_toolchain_registered
8+
query --deleted_packages=examples/build_file_generation,examples/build_file_generation/random_number_generator,examples/bzlmod,examples/bzlmod/entry_points,examples/bzlmod/entry_points/tests,examples/bzlmod/libs/my_lib,examples/bzlmod/other_module,examples/bzlmod/other_module/other_module/pkg,examples/bzlmod/patches,examples/bzlmod/py_proto_library,examples/bzlmod/py_proto_library/example.com/another_proto,examples/bzlmod/py_proto_library/example.com/proto,examples/bzlmod/runfiles,examples/bzlmod/tests,examples/bzlmod/tests/other_module,examples/bzlmod/whl_mods,examples/bzlmod_build_file_generation,examples/bzlmod_build_file_generation/other_module/other_module/pkg,examples/bzlmod_build_file_generation/runfiles,examples/multi_python_versions/libs/my_lib,examples/multi_python_versions/requirements,examples/multi_python_versions/tests,examples/pip_parse,examples/pip_parse_vendored,examples/pip_repository_annotations,examples/py_proto_library,examples/py_proto_library/example.com/another_proto,examples/py_proto_library/example.com/proto,gazelle,gazelle/manifest,gazelle/manifest/generate,gazelle/manifest/hasher,gazelle/manifest/test,gazelle/modules_mapping,gazelle/python,gazelle/python/private,gazelle/pythonconfig,tests/integration/compile_pip_requirements,tests/integration/compile_pip_requirements_test_from_external_repo,tests/integration/custom_commands,tests/integration/ignore_root_user_error,tests/integration/ignore_root_user_error/submodule,tests/integration/local_toolchains,tests/integration/pip_parse,tests/integration/pip_parse/empty,tests/integration/py_cc_toolchain_registered
99

1010
test --test_output=errors
1111

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ A brief description of the categories of changes:
2727
### Changed
2828
* (toolchains) `py_runtime.implementation_name` now defaults to `cpython`
2929
(previously it defaulted to None).
30+
* (bzlmod) **BREAKING** The `experimental_index_url` feature has been removed
31+
from `pip.parse` and a new extension (`pypi.install`) has been created in
32+
order to ensure that `MODULE.bazel.lock` remains working for others.
33+
Fixes [#2268](https://github.com/bazelbuild/rules_python/issues/2268).
3034

3135
### Fixed
3236
* (bzlmod) The `python.override(minor_mapping)` now merges the default and the

MODULE.bazel

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ register_toolchains("@pythons_hub//:all")
5454
#####################
5555
# Install twine for our own runfiles wheel publishing and allow bzlmod users to use it.
5656

57-
pip = use_extension("//python/private/pypi:pip.bzl", "pip_internal")
58-
pip.parse(
57+
pypi = use_extension("//python/private/pypi:pypi.bzl", "pypi")
58+
pypi.install(
5959
hub_name = "rules_python_publish_deps",
6060
python_version = "3.11",
6161
requirements_by_platform = {
@@ -64,7 +64,7 @@ pip.parse(
6464
"//tools/publish:requirements_windows.txt": "windows_*",
6565
},
6666
)
67-
use_repo(pip, "rules_python_publish_deps")
67+
use_repo(pypi, "rules_python_publish_deps")
6868

6969
# ===== DEV ONLY DEPS AND SETUP BELOW HERE =====
7070
bazel_dep(name = "stardoc", version = "0.6.2", dev_dependency = True, repo_name = "io_bazel_stardoc")
@@ -85,22 +85,22 @@ dev_python.override(
8585
register_all_versions = True,
8686
)
8787

88-
dev_pip = use_extension(
89-
"//python/private/pypi:pip.bzl",
90-
"pip_internal",
88+
dev_pypi = use_extension(
89+
"//python/private/pypi:pypi.bzl",
90+
"pypi",
9191
dev_dependency = True,
9292
)
93-
dev_pip.parse(
93+
dev_pypi.install(
9494
hub_name = "dev_pip",
9595
python_version = "3.11",
9696
requirements_lock = "//docs:requirements.txt",
9797
)
98-
dev_pip.parse(
98+
dev_pypi.install(
9999
hub_name = "pypiserver",
100100
python_version = "3.11",
101101
requirements_lock = "//examples/wheel:requirements_server.txt",
102102
)
103-
use_repo(dev_pip, "dev_pip", "pypiserver")
103+
use_repo(dev_pypi, "dev_pip", "pypiserver")
104104

105105
# Bazel integration test setup below
106106

docs/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ sphinx_stardocs(
109109
] if IS_BAZEL_7_OR_HIGHER else []) + ([
110110
# This depends on @pythons_hub, which is only created under bzlmod,
111111
"//python/extensions:pip_bzl",
112+
"//python/extensions:pypi_bzl",
112113
] if IS_BAZEL_7_OR_HIGHER and BZLMOD_ENABLED else []),
113114
prefix = "api/rules_python/",
114115
tags = ["docs"],

examples/bzlmod/MODULE.bazel

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,11 @@ register_toolchains("@uv_toolchains//:all")
104104
# See @rules_python//python/extensions:whl_mods.bzl attributes for more information
105105
# on each of the attributes.
106106
# You are able to set a hub name, so that you can have different modifications of the same
107-
# wheel in different pip hubs.
108-
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
107+
# wheel in different pypi hubs.
108+
pypi = use_extension("@rules_python//python/extensions:pypi.bzl", "pypi")
109109

110110
# Call whl_mods.create for the requests package.
111-
pip.whl_mods(
111+
pypi.whl_mods(
112112
# we are using the appended_build_content.BUILD file
113113
# to add content to the request wheel BUILD file.
114114
additive_build_content_file = "//whl_mods:appended_build_content.BUILD",
@@ -127,7 +127,7 @@ write_file(
127127
"""
128128

129129
# Call whl_mods.create for the wheel package.
130-
pip.whl_mods(
130+
pypi.whl_mods(
131131
additive_build_content = ADDITIVE_BUILD_CONTENT,
132132
copy_executables = {
133133
"@@//whl_mods:data/copy_executable.py": "copied_content/executable.py",
@@ -140,27 +140,24 @@ pip.whl_mods(
140140
hub_name = "whl_mods_hub",
141141
whl_name = "wheel",
142142
)
143-
use_repo(pip, "whl_mods_hub")
143+
use_repo(pypi, "whl_mods_hub")
144144

145-
# To fetch pip dependencies, use pip.parse. We can pass in various options,
145+
# To fetch pypi dependencies, use pypi.install. We can pass in various options,
146146
# but typically we pass requirements and the Python version. The Python
147147
# version must have been configured by a corresponding `python.toolchain()`
148148
# call.
149149
# Alternatively, `python_interpreter_target` can be used to directly specify
150150
# the Python interpreter to run to resolve dependencies.
151-
pip.parse(
151+
pypi.install(
152152
# We can use `envsubst in the above
153153
envsubst = ["PIP_INDEX_URL"],
154-
# Use the bazel downloader to query the simple API for downloading the sources
155-
# Note, that we can use envsubst for this value.
156-
experimental_index_url = "${PIP_INDEX_URL:-https://pypi.org/simple}",
157154
# One can also select a particular index for a particular package.
158155
# This ensures that the setup is resistant against confusion attacks.
159-
# experimental_index_url_overrides = {
156+
# index_url_overrides = {
160157
# "my_package": "https://different-index-url.com",
161158
# },
162159
# Or you can specify extra indexes like with `pip`:
163-
# experimental_extra_index_urls = [
160+
# extra_index_urls = [
164161
# "https://different-index-url.com",
165162
# ],
166163
experimental_requirement_cycles = {
@@ -182,6 +179,9 @@ pip.parse(
182179
"cp39_*",
183180
],
184181
hub_name = "pip",
182+
# Use the bazel downloader to query the simple API for downloading the sources
183+
# Note, that we can use envsubst for this value.
184+
index_url = "${PIP_INDEX_URL:-https://pypi.org/simple}",
185185
python_version = "3.9",
186186
requirements_lock = "requirements_lock_3_9.txt",
187187
# These modifications were created above and we
@@ -192,7 +192,7 @@ pip.parse(
192192
"@whl_mods_hub//:wheel.json": "wheel",
193193
},
194194
)
195-
pip.parse(
195+
pypi.install(
196196
experimental_requirement_cycles = {
197197
"sphinx": [
198198
"sphinx",
@@ -240,7 +240,7 @@ pip.parse(
240240
# You can add patches that will be applied on the whl contents.
241241
#
242242
# The patches have to be in the unified-diff format.
243-
pip.override(
243+
pypi.override(
244244
file = "requests-2.25.1-py2.py3-none-any.whl",
245245
patch_strip = 1,
246246
patches = [
@@ -249,7 +249,7 @@ pip.override(
249249
"@//patches:requests_record.patch",
250250
],
251251
)
252-
use_repo(pip, "pip")
252+
use_repo(pypi, "pip")
253253

254254
bazel_dep(name = "other_module", version = "", repo_name = "our_other_module")
255255
local_path_override(

0 commit comments

Comments
 (0)