From d55c72f8b376be079c8a11fea17c5938dbce568c Mon Sep 17 00:00:00 2001 From: James Sharpe Date: Tue, 10 Feb 2026 10:33:30 +0000 Subject: [PATCH] fix(pip): preserve PEP 508 URL-based requirements when extract_url_srcs=False pip_parse (via pip_repository) passes extract_url_srcs=False to parse_requirements. The _package_srcs() function silently dropped PEP 508 URL-based requirements (pkg @ https://...) in this mode because _add_dists() returns can_fallback=False for URL requirements, causing them to fall through to the `continue` statement. Fix the elif condition to also accept the case where extract_url_srcs is False but a valid URL dist exists, falling back to pip to handle the URL requirement directly. Co-Authored-By: Claude Opus 4.6 --- CHANGELOG.md | 3 ++ python/private/pypi/parse_requirements.bzl | 2 +- .../parse_requirements_tests.bzl | 41 +++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96e7dcd5b3..12edf68c4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -79,6 +79,9 @@ END_UNRELEASED_TEMPLATE ([#2762](https://github.com/bazel-contrib/rules_python/issues/2762)) * (gazelle) Ancestor `conftest.py` files are added in addition to sibling `conftest.py`. ([#3497](https://github.com/bazel-contrib/rules_python/issues/3497)) +* (pypi) `pip_parse` no longer silently drops PEP 508 URL-based requirements + (`pkg @ https://...`) when `extract_url_srcs=False` (the default for + `pip_repository`). {#v0-0-0-added} ### Added diff --git a/python/private/pypi/parse_requirements.bzl b/python/private/pypi/parse_requirements.bzl index 5c05c753fd..760bf5a9e8 100644 --- a/python/private/pypi/parse_requirements.bzl +++ b/python/private/pypi/parse_requirements.bzl @@ -260,7 +260,7 @@ def _package_srcs( if extract_url_srcs and dist: req_line = r.srcs.requirement - elif can_fallback: + elif can_fallback or (not extract_url_srcs and dist): dist = struct( url = "", filename = "", diff --git a/tests/pypi/parse_requirements/parse_requirements_tests.bzl b/tests/pypi/parse_requirements/parse_requirements_tests.bzl index 63755d2edd..a2efe91d99 100644 --- a/tests/pypi/parse_requirements/parse_requirements_tests.bzl +++ b/tests/pypi/parse_requirements/parse_requirements_tests.bzl @@ -192,6 +192,47 @@ def _test_direct_urls_integration(env): _tests.append(_test_direct_urls_integration) +def _test_direct_urls_no_extract(env): + """Check that URL requirements are not dropped when extract_url_srcs=False.""" + got = parse_requirements( + requirements_by_platform = { + "requirements_direct": ["linux_x86_64"], + "requirements_direct_sdist": ["osx_x86_64"], + }, + extract_url_srcs = False, + ) + env.expect.that_collection(got).contains_exactly([ + struct( + name = "foo", + is_exposed = True, + is_multiple_versions = True, + srcs = [ + struct( + distribution = "foo", + extra_pip_args = [], + filename = "", + requirement_line = "foo @ https://github.com/org/foo/downloads/foo-1.1.tar.gz", + sha256 = "", + target_platforms = ["osx_x86_64"], + url = "", + yanked = False, + ), + struct( + distribution = "foo", + extra_pip_args = [], + filename = "", + requirement_line = "foo[extra] @ https://some-url/package.whl", + sha256 = "", + target_platforms = ["linux_x86_64"], + url = "", + yanked = False, + ), + ], + ), + ]) + +_tests.append(_test_direct_urls_no_extract) + def _test_extra_pip_args(env): got = parse_requirements( requirements_by_platform = {