fix(bzlmod): correctly wire the extra_pip_args (#2258)
Before this PR we were just dropping the `extra_pip_args` passed to
`pip.parse` and were just using the args passed through the requirements
file. Thanks to @swarren12 for pointing this out.
This PR also passes `extra_pip_args` to `sdist` `whl_library` instances
so that users can build the `sdists` correctly when using
`experimental_index_url` feature.
Summary:
- pass `extra_pip_args` when building sdists in experimental mode
- join `extra_pip_args` from the file and the pip.parse attr
- test: add a test to ensure that the extra args are joined
Fixes #2239
Closes #2254
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a16a5e3..7235e89 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -28,6 +28,11 @@
* Nothing yet
### Fixed
+* (bzlmod) correctly wire the {attr}`pip.parse.extra_pip_args` all the
+ way to {obj}`whl_library`. What is more we will pass the `extra_pip_args` to
+ {obj}`whl_library` for `sdist` distributions when using
+ {attr}`pip.parse.experimental_index_url`. See
+ [#2239](https://github.com/bazelbuild/rules_python/issues/2239).
* (whl_filegroup): Provide per default also the `RECORD` file
### Added
diff --git a/examples/bzlmod/MODULE.bazel.lock b/examples/bzlmod/MODULE.bazel.lock
index cb8fbe2..604aef1 100644
--- a/examples/bzlmod/MODULE.bazel.lock
+++ b/examples/bzlmod/MODULE.bazel.lock
@@ -1231,7 +1231,7 @@
},
"@@rules_python~//python/extensions:pip.bzl%pip": {
"general": {
- "bzlTransitiveDigest": "ED3oUrLQz/MTptq8JOZ03sjD7HZ3naUeFS3XFpxz4tg=",
+ "bzlTransitiveDigest": "W8FWi7aL0uqh7djg6csTMzkL1RB6WGRgfO/MOcbqYZI=",
"usagesDigest": "MChlcSw99EuW3K7OOoMcXQIdcJnEh6YmfyjJm+9mxIg=",
"recordedFileInputs": {
"@@other_module~//requirements_lock_3_11.txt": "a7d0061366569043d5efcf80e34a32c732679367cb3c831c4cdc606adc36d314",
@@ -6140,7 +6140,7 @@
},
"@@rules_python~//python/private/pypi:pip.bzl%pip_internal": {
"general": {
- "bzlTransitiveDigest": "vEOIMpxlh8qbHkABunGFRr+IDbabjCM/hUF0V3GGTus=",
+ "bzlTransitiveDigest": "9aEp4XU4yVL6sJqODxio5iSCoqf37Ro3o+Mt1izDnq8=",
"usagesDigest": "Y8ihY+R57BAFhalrVLVdJFrpwlbsiKz9JPJ99ljF7HA=",
"recordedFileInputs": {
"@@rules_python~//tools/publish/requirements.txt": "031e35d03dde03ae6305fe4b3d1f58ad7bdad857379752deede0f93649991b8a",
diff --git a/python/private/pypi/extension.bzl b/python/private/pypi/extension.bzl
index 77a4778..712d2fe 100644
--- a/python/private/pypi/extension.bzl
+++ b/python/private/pypi/extension.bzl
@@ -182,6 +182,7 @@
python_version = major_minor,
logger = logger,
),
+ extra_pip_args = pip_attr.extra_pip_args,
get_index_urls = get_index_urls,
# NOTE @aignas 2024-08-02: , we will execute any interpreter that we find either
# in the PATH or if specified as a label. We will configure the env
@@ -275,8 +276,13 @@
if pip_attr.auth_patterns:
whl_library_args["auth_patterns"] = pip_attr.auth_patterns
- # pip is not used to download wheels and the python `whl_library` helpers are only extracting things
- whl_library_args.pop("extra_pip_args", None)
+ if distribution.filename.endswith(".whl"):
+ # pip is not used to download wheels and the python `whl_library` helpers are only extracting things
+ whl_library_args.pop("extra_pip_args", None)
+ else:
+ # For sdists, they will be built by `pip`, so we still
+ # need to pass the extra args there.
+ pass
# This is no-op because pip is not used to download the wheel.
whl_library_args.pop("download_only", None)
diff --git a/python/private/pypi/parse_requirements.bzl b/python/private/pypi/parse_requirements.bzl
index eee97d7..c72f5d4 100644
--- a/python/private/pypi/parse_requirements.bzl
+++ b/python/private/pypi/parse_requirements.bzl
@@ -48,7 +48,7 @@
different package versions (or different packages) for different
os, arch combinations.
extra_pip_args (string list): Extra pip arguments to perform extra validations and to
- be joined with args fined in files.
+ be joined with args found in files.
get_index_urls: Callable[[ctx, list[str]], dict], a callable to get all
of the distribution URLs from a PyPI index. Accepts ctx and
distribution names to query.
diff --git a/tests/pypi/parse_requirements/parse_requirements_tests.bzl b/tests/pypi/parse_requirements/parse_requirements_tests.bzl
index 25d2961..c719ad6 100644
--- a/tests/pypi/parse_requirements/parse_requirements_tests.bzl
+++ b/tests/pypi/parse_requirements/parse_requirements_tests.bzl
@@ -22,6 +22,11 @@
"requirements_direct": """\
foo[extra] @ https://some-url
""",
+ "requirements_extra_args": """\
+--index-url=example.org
+
+foo[extra]==0.0.1 --hash=sha256:deadbeef
+""",
"requirements_linux": """\
foo==0.0.3 --hash=sha256:deadbaaf
""",
@@ -93,6 +98,43 @@
_tests.append(_test_simple)
+def _test_extra_pip_args(env):
+ got = parse_requirements(
+ ctx = _mock_ctx(),
+ requirements_by_platform = {
+ "requirements_extra_args": ["linux_x86_64"],
+ },
+ extra_pip_args = ["--trusted-host=example.org"],
+ )
+ env.expect.that_dict(got).contains_exactly({
+ "foo": [
+ struct(
+ distribution = "foo",
+ extra_pip_args = ["--index-url=example.org", "--trusted-host=example.org"],
+ requirement_line = "foo[extra]==0.0.1 --hash=sha256:deadbeef",
+ srcs = struct(
+ requirement = "foo[extra]==0.0.1",
+ shas = ["deadbeef"],
+ version = "0.0.1",
+ ),
+ target_platforms = [
+ "linux_x86_64",
+ ],
+ whls = [],
+ sdist = None,
+ is_exposed = True,
+ ),
+ ],
+ })
+ env.expect.that_str(
+ select_requirement(
+ got["foo"],
+ platform = "linux_x86_64",
+ ).srcs.version,
+ ).equals("0.0.1")
+
+_tests.append(_test_extra_pip_args)
+
def _test_dupe_requirements(env):
got = parse_requirements(
ctx = _mock_ctx(),