docs(proposals): Deprecate PEP 508 Direct References (req.url)#1225
docs(proposals): Deprecate PEP 508 Direct References (req.url)#1225smoparth wants to merge 1 commit into
Conversation
📝 WalkthroughWalkthroughThis change adds a new architecture decision record proposing deprecation and eventual removal of PEP 508 direct reference URL ( Estimated code review effort: 1 (Trivial) | ~3 minutes Sequence Diagram(s)No diagram generated, as this change is a documentation-only addition with no code flow to depict. Related issues: None mentioned in the provided context. Related PRs: None mentioned in the provided context. Suggested labels: documentation, proposal Suggested reviewers: None specified. 🐰 A note is penned, no code to see, 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
This aligns with what we discussed earlier today. @dhellmann originally added this feature and we should wait for him to take a look and see what he thinks. |
|
Nit-pick: We don't use the term "ADR" in upstream Fromager. |
…(req.url) Propose deprecating the `package @ git+https://...` syntax in favor of the declarative `source` provider config. The feature requires 19 special-case branches across 6 files and every use case is covered by the new git-clone providers (pypi-git, github-tag-git, gitlab-tag-git, versionmap-git). Co-Authored-By: Claude <claude@anthropic.com> Signed-off-by: Shanmukh Pawan <smoparth@redhat.com>
3e4eda9 to
4f97bed
Compare
|
I like this idea. This gives us an opportunity to cleanup the code |
|
|
||
| ## 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](https://github.com/python-wheel-build/fromager/commit/5f3fa68) (2025-02-22) to support building packages whose PyPI sdists were broken or unavailable. |
There was a problem hiding this comment.
We also added it to allow building from source for nightly builds, to differentiate from building only tagged versions of packages. We did that originally for one of our downstream apps that was regularly adding new dependencies when they did tag and we wanted to pull those dependencies into the nightly builds to catch issues before releases.
|
|
||
| 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](https://github.com/python-wheel-build/fromager/commit/5f3fa68) (2025-02-22) to support building packages whose PyPI sdists were broken or unavailable. | ||
|
|
||
| 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](https://github.com/python-wheel-build/fromager/commit/4a080bb), [45008ce](https://github.com/python-wheel-build/fromager/commit/45008ce), [e50247d](https://github.com/python-wheel-build/fromager/commit/e50247d), [5687cf7](https://github.com/python-wheel-build/fromager/commit/5687cf7)) added special-case handling to accommodate `req.url` in a pipeline that wasn't designed for it. |
There was a problem hiding this comment.
This is a good reason to consider changing or removing this feature.
| | Build from GitHub tag | `pkg @ git+https://github.com/org/repo@v1.0` | `provider: github-tag-git` with `project_url` | | ||
| | Build from GitLab tag | `pkg @ git+https://gitlab.com/org/repo@v1.0` | `provider: gitlab-tag-git` with `project_url` | | ||
| | Build from specific commit | `pkg @ git+https://repo@abc123` | `provider: versionmap-git` with `versionmap` | | ||
| | Build from branch HEAD | `pkg @ git+https://repo@main` | Same providers with appropriate tag/ref config | |
There was a problem hiding this comment.
This is the primary case we really cared about. Could you expand on the "same providers with appropriate config" explanation? How would we sometimes build from the HEAD of a branch and other times build a tagged version?
There was a problem hiding this comment.
When I wrote "same providers with appropriate config," I was thinking of the case where a user could resolve the current HEAD to a known tag and passes that into the settings. I didn't mean to imply the existing providers support dynamic HEAD resolution out of the box. I'll update the proposal to make that distinction clear.
For supporting builds from branch HEAD directly, I think we'd want a new provider, something like git-branch that clones the repo first and discovers the version from package metadata. The source config proposal already mentions VCS support as future work in the git clone section, so a git-branch provider could fit naturally into that scope.
That said, I don't think we'd be able to support both building from HEAD and from a tagged release for the same package in the same run. The source config settings allows only one provider per package (or per variant).
The current req.url flow has the same limitation. If requirements.txt contains both mypkg==1.2.3 and mypkg @ git+https://...main, the bootstrap loop is keyed on (package_name, version). Whichever entry resolves first gets processed; the other is silently marked as "already seen" and skipped. The behavior is order-dependent.
There's also a cache staleness concern with branch HEAD builds. If the package uses a static version in pyproject.toml (not setuptools-scm or similar), then two different commits can produce the same version string and since fromager's wheel cache is keyed by (name, version), a rebuild the next day would find the cached wheel from the previous run and reuse it, even though the source has changed. This only works correctly when the version is dynamic and includes the commit hash (e.g., setuptools-scm producing 1.2.3.dev7+g3a4b5c6).
There was a problem hiding this comment.
Yes, the whole URL based scheme was only designed to work for builds where the version was dynamically determined from the tag. If the project is not using a tag to set the version, then all bets are off.
Given that, I think the cache situation you raise is only a problem if the exact version specified in the build inputs is the same as the exact version that would be produced by the tag. In that case, it's not really a big deal because we only want one build anyway.
The feature was designed to be used in a completely separate pipeline build, though. Like having a new collection for nightly builds of projects. Those might not even necessarily go to the same place as a production build.
There was a problem hiding this comment.
Thanks, Doug! This is incredibly useful information. We'll review it during the next Fromager office hours and update you.
There was a problem hiding this comment.
Sounds good, and to reiterate what I said elsewhere earlier today: I do think we should review whether this feature is useful enough to keep the code complexity. It's possible we could handle it a different way (a pre-processor to produce a config file or a different set of phase implementation functions are 2 ways), but it's also possible we could just delete the code and not worry about it.
Propose deprecating the
package @ git+https://...syntax in favor of the declarativesourceprovider config. The feature requires 19 special-case branches across 6 files and every use case is covered by the new git-clone providers (pypi-git, github-tag-git, gitlab-tag-git, versionmap-git).Pull Request Description
What
Why