Deprecate PEP 508 Direct References (req.url)
Status: Proposed Date: 2026-07-02 Author: Shanmukh Pawan
What
Deprecate and eventually remove support for PEP 508 direct reference URLs (the package @ git+https://... syntax) as top-level bootstrap inputs. Migrate users to the declarative source provider config introduced in the new resolver and download configuration proposal.
Why
PEP 508 direct references (parsed into Requirement.url by the packaging library) let users specify a git URL inline in a requirement string. Fromager added this in 5f3fa68 (2025-02-22) to support two use cases: building packages whose PyPI sdists were broken or unavailable, and building from branch HEAD for nightly builds to catch integration issues before tagged releases.
This feature sits outside fromager’s normal pipeline. Because the Requirement object carries the URL instead of a version specifier, every pipeline phase (resolution, download, prepare, build sdist) needs a separate if req.url: branch to bypass its normal logic. The codebase currently has 19 such branches across 6 files. Each subsequent commit (4a080bb, 45008ce, e50247d, 5687cf7) added special-case handling to accommodate req.url in a pipeline that wasn’t designed for it.
The scope is inherently narrow:
Only top-level requirements. Transitive dependencies cannot carry URLs (PyPI rejects them per PEP 440).
Only git URLs. No other VCS or URL type is supported.
Only command-line input. Not declarative, not version-controlled, not per-variant.
Requires cloning just to discover the version. The normal pipeline resolves versions without fetching source.
The new source provider config covers every req.url use case declaratively, without special-casing:
Use case |
|
|
|---|---|---|
Build from git tag |
|
|
Build from GitHub tag |
|
|
Build from GitLab tag |
|
|
Build from specific commit |
|
|
Build from branch HEAD |
|
No direct equivalent yet. Requires a new provider that clones first and discovers the version from package metadata. |
Decision
Deprecate req.url support with a warning, then remove it after users have migrated to source provider configs.
The deprecation is reversible. If unforeseen use cases emerge, the warning can remain indefinitely without blocking users.
How
Phase 1: When a top-level requirement has req.url set, emit a deprecation warning with guidance pointing to the equivalent source provider config. No behavior change.
Phase 2: Add a migration guide documenting the before/after for each use case (git tag, git commit, branch HEAD).
Phase 3: After downstream migration is confirmed, remove the req.url code paths: the 19 if req.url: branches, _resolve_version_from_git_url(), and related helper methods in bootstrapper.py.
gitutils.py is retained. It is used by git-clone source providers via default_download_source().