Per-index exclude-newer for extra-index-urls
Problem description
Summary
Allow [tool.pixi.pypi-options].extra-index-urls entries to be inline tables that carry their own exclude-newer value, mirroring ChannelInlineTable.exclude-newer already supported for conda channels.
Motivation
[tool.pixi.workspace].exclude-newer and the per-package [tool.pixi.pypi-exclude-newer] table (added in 0.67) both require upload-time metadata in the index response to evaluate the cutoff. When a private/internal PyPI mirror does not expose upload-time (which is common — Artifactory's pypi-virtual repo, for example, does not), every version of every package served from that mirror becomes ineligible. The solve fails with Because there is no version of <pkg>==X.Y.Z and you require <pkg>==X.Y.Z, we can conclude that your requirements are unsatisfiable, even when the pin is exact and the version is unambiguously present.
There is currently no way to apply yank protection to public-index packages while leaving private-index packages alone.
Proposed syntax
[tool.pixi.pypi-options]
extra-index-urls = [
"https://pypi.org/simple", # filter applied via global exclude-newer
{ url = "https://artifactory.internal/simple", exclude-newer = false },
]exclude-newer = false (or omitted, with appropriate default) → no filter on packages served from that index. A string value would set a custom cutoff for that index. Mirrors the existing ChannelInlineTable:
channels = [
"conda-forge",
{ channel = "internal", exclude-newer = false },
]Alternatives considered
[tool.pixi.pypi-exclude-newer] = { pkg = "9999-01-01" }: doesn't help because uv still excludes versions whoseupload-timeis unparseable/missing, regardless of the per-package cutoff value.[tool.pixi.pypi-exclude-newer] = { pkg = "0d" }: same.- Enumerating every public-index package explicitly and omitting private-index ones: works as a script-level workaround but doesn't cover transitive deps and doesn't generalize.
Use case
We rewrite version pins in esr-pkg/pyproject.toml periodically via a bump-constraints script that strips == pins, calls pixi update, and rewrites the resolved versions. We want a 7-day soak window on every public-index package (PyPI yanks happen often enough to be a real concern), but our manifest also depends on internal-mirror packages whose metadata doesn't include upload-time. The per-index lever would let us write one line in the manifest and stop maintaining a per-package exemption list in the bump script.
Source: prefix-dev/pixi