Expand description
Private/custom PyPI index resolution — --index-url/--extra-index-url
(requirements.txt), Poetry [[tool.poetry.source]], and uv
[tool.uv.index]/[tool.uv.sources].
§Security model (read before touching this module)
A requirements.txt/pyproject.toml index declaration is attacker-controlled the moment a
hostile repository is cloned and opened — this LSP parses on file open, before any build
ever runs. Phase 1 carries no authentication at all (spec Out of Scope: no URL userinfo, no
keyring/.netrc), which closes the credential half of the threat model this module would
otherwise have to solve, but two things still apply:
- No credential-shaped value is ever parsed.
PypiIndexUrl::newrejects any URL carryingusername()/password()outright (FR-006/FR-011) — there is no expansion step for PyPI config (unlike npm’s${VAR}), soInvalidEntry::rawand everytracing::warn!here name the as-written value with any embedded userinfo stripped first (seeredact_userinfo) — the raw value is otherwise preserved so a warning or aDependencySource::CustomRegistrynaming an unresolved primary/named source still shows the user what they actually typed, minus the credential. - FR-005’s resolution order is the load-bearing security invariant of this whole
feature. Case (a) (an explicit
--index-url/Poetry primary/uvdefault): the explicit primary is checked first, then extras — a deliberate user choice, no disclosure risk. Case (b) (no explicit primary, extras only): declared extras are checked before the implicit publicpypi.orgfallback, never the reverse — this is what stops a private package’s name from being sent topypi.orgbefore the user’s own declared index has had a chance, and what stops a same-named public package from silently shadowing a private one. SeePypiIndexConfig::resolve_source_forandResolvedChain’s docs.
See specs/033-pypi-private-index-support/spec.md FR-001–FR-014 and
specs/033-pypi-private-index-support/plan.md §1/§3 for the design review this module
implements.
Structs§
- Invalid
Entry - A present-but-unusable index entry — an invalid URL, a policy-blocked host, or a well-formed-but-non-https/userinfo-bearing value.
- Pypi
Index Config - Resolved index configuration for one
requirements.txt/pyproject.tomlfile. - Pypi
Index Url - A validated, normalized, https-only PyPI-protocol index URL with no embedded userinfo.
- Resolved
Chain - One fully-resolved, ready-to-register routing chain — produced by
PypiIndexConfig::resolved_chains, consumed byPypiRegistry::register_chain/register_named_source.
Enums§
- Pypi
Index UrlError - Why a candidate index URL failed
PypiIndexUrl::new’s validation.