Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions news/pip-default-empty-index-url.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
(pypi) Fixed {obj}`pip.default` so setting `index_url = ""` disables the Simple

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is considered a fix or a behavioral change, let me know.

API downloader and falls back to `pip` instead of being ignored.
19 changes: 17 additions & 2 deletions python/private/pypi/extension.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ load(":simpleapi_download.bzl", "simpleapi_download")
load(":unified_hub_repo.bzl", "unified_hub_repo")
load(":whl_library.bzl", "whl_library")

_DEFAULT_INDEX_URL = "https://pypi.org/simple"

def _whl_mods_impl(whl_mods_dict):
"""Implementation of the pip.whl_mods tag class.

Expand Down Expand Up @@ -249,10 +251,14 @@ def build_config(
if platform and not (tag.arch_name or tag.config_settings or tag.env or tag.os_name or tag.whl_abi_tags or tag.whl_platform_tags or tag.marker):
defaults["platforms"].pop(platform)

if tag.index_url != _DEFAULT_INDEX_URL and (
mod.is_root or "index_url" not in defaults
):
defaults["index_url"] = tag.index_url

_configure(
defaults,
override = mod.is_root,
index_url = tag.index_url,
# extra values that we just add
auth_patterns = tag.auth_patterns,
netrc = tag.netrc,
Expand All @@ -264,7 +270,7 @@ def build_config(
return struct(
auth_patterns = defaults.get("auth_patterns", {}),
default_hub = default_hub,
index_url = defaults.get("index_url", "https://pypi.org/simple").rstrip("/"),
index_url = defaults.get("index_url", _DEFAULT_INDEX_URL).rstrip("/"),
netrc = defaults.get("netrc", None),
python_version = defaults.get("python_version", None),
platforms = {
Expand Down Expand Up @@ -687,6 +693,7 @@ Supported keys:
""",
),
"index_url": attr.string(
default = _DEFAULT_INDEX_URL,
doc = """\
The index URL to use as a default when downloading packages from PyPI. This is used if nothing is
specified via `--index-url` or `--extra-index-url` parameters in the `requirements.txt` file or via
Expand All @@ -701,13 +708,21 @@ The indexes must support Simple API as described here:
Index metadata will be used to get the hash digest values for packages even
if the `--hash` values are not present in the requirements.txt lock file.

Set to `""` to disable the Simple API downloader and fall back to using `pip`
to download wheels.

Defaults to `https://pypi.org/simple`.

:::{versionadded} 2.0.0
This has been added as a replacement for
{obj}`pip.parse.experimental_index_url` and
{obj}`pip.parse.experimental_extra_index_urls`.
:::

:::{versionchanged} VERSION_NEXT_PATCH
Setting `index_url = ""` now disables the Simple API downloader instead of
being ignored.
:::
""",
),
"marker": attr.string(
Expand Down
6 changes: 5 additions & 1 deletion python/private/pypi/hub_builder.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,11 @@ def _set_get_index_urls(self, mctx, pip_attr):
pip_attr.experimental_index_url,
pip_attr.envsubst,
mctx.getenv,
) or self._config.index_url
) or envsubst(
self._config.index_url,
pip_attr.envsubst,
mctx.getenv,
)
default_extra_index_urls = pip_attr.experimental_extra_index_urls or []

if not default_index_url:
Expand Down
55 changes: 53 additions & 2 deletions tests/pypi/extension/extension_tests.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def _default(
config_settings = None,
default_hub = "",
env = None,
index_url = None,
index_url = "https://pypi.org/simple",
marker = None,
netrc = None,
os_name = None,
Expand All @@ -61,7 +61,7 @@ def _default(
config_settings = config_settings,
default_hub = default_hub,
env = env or {},
index_url = index_url or "",
index_url = index_url,
marker = marker or "",
netrc = netrc,
os_name = os_name,
Expand Down Expand Up @@ -761,6 +761,57 @@ simple==0.0.1 \

_tests.append(_test_default_index_setting)

def _test_default_index_url_empty_disables_simpleapi(env):
def fail_simpleapi_download(*_args, **_kwargs):
fail("simpleapi_download should not be called when index_url is empty")

for index_url, envsubst, want_whl_library in [
("", [], {}),
(
"$RULES_PYTHON_PIP_INDEX_URL",
["RULES_PYTHON_PIP_INDEX_URL"],
{"envsubst": ["RULES_PYTHON_PIP_INDEX_URL"]},
),
]:
pypi = _parse_modules(
env,
module_ctx = _pypi_mock_mctx(
_mod(
name = "my_module",
default = _default_tags_default + [
_default(index_url = index_url),
_default(default_hub = "pypi_a"),
],
parse = [
_parse(
hub_name = "pypi_a",
python_version = "3.15",
envsubst = envsubst,
requirements_lock = "requirements.txt",
),
],
),
os_name = "linux",
arch_name = "x86_64",
),
available_interpreters = {
"python_3_15_host": "unit_test_interpreter_target",
},
minor_mapping = {"3.15": "3.15.19"},
simpleapi_download = fail_simpleapi_download,
)

pypi.whl_libraries().contains_exactly({
"pypi_a_315_simple": {
"config_load": "@pypi_a//:config.bzl",
"dep_template": "@pypi_a//{name}:{target}",
"python_interpreter_target": "unit_test_interpreter_target",
"requirement": "simple==0.0.1 --hash=sha256:deadbeef --hash=sha256:deadbaaf",
} | want_whl_library,
})

_tests.append(_test_default_index_url_empty_disables_simpleapi)

def extension_test_suite(name):
"""Create the test suite.

Expand Down
Loading