uv: Support parsing and updating tool.uv.required-version field#14581
uv: Support parsing and updating tool.uv.required-version field#14581r7sy wants to merge 5 commits intodependabot:mainfrom
Conversation
Add support for the `required-version` field in `uv.toml` and `[tool.uv]` in `pyproject.toml`. This allows Dependabot to detect the pinned UV tool version as a dependency and create PRs to update it. The UV tool version is modeled as a regular dependency tagged with a `uv-required-version` group. This lets the existing dependency pipeline handle it without new orchestration, while FileUpdater filters it out before passing deps to CompileFileUpdater/LockFileUpdater so it does not interfere with package dependency resolution. Changes: - FileFetcher: fetch uv.toml alongside uv.lock - FileParser: new UvVersionParser extracts the uv dependency from both uv.toml and pyproject.toml [tool.uv] sections - FileUpdater: new UvVersionFileUpdater rewrites the required-version value, with section-scoped edits for pyproject.toml to avoid modifying identically-named keys in other TOML sections - UpdateChecker: route uv.toml deps to the requirements resolver - RequirementsUpdater: dedicated uv.toml handler that bumps unsatisfied version constraints without pyproject-specific branching logic
- Remove redundant T.must on T.untyped hash values (srb 7050) - Add T.must for nilable array slice results (srb 7003) - Use T.cast for req[:groups] to avoid method call on T.untyped (srb 7018)
…bot-core into uv/support-required-version
There was a problem hiding this comment.
Pull request overview
Adds UV-ecosystem support for treating required-version (from uv.toml and [tool.uv] in pyproject.toml) as an updatable dependency, so Dependabot can propose bumps for the UV tool itself.
Changes:
- Parse
required-versioninto a synthetic dependency (grouped asuv-required-version) fromuv.tomlandpyproject.toml. - Update-check and file-update logic to bump the
required-versionconstraint and scope edits to[tool.uv]inpyproject.toml. - Fetch
uv.tomland add extensive specs/fixtures covering pins, ranges, multi-file, and key-collision cases.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
uv/lib/dependabot/uv/file_fetcher.rb |
Fetches uv.toml alongside existing UV files. |
uv/lib/dependabot/uv/file_parser.rb |
Integrates UV tool version parsing and allows uv.toml as a “required file”. |
uv/lib/dependabot/uv/file_parser/uv_version_parser.rb |
New parser extracting required-version from uv.toml / [tool.uv]. |
uv/lib/dependabot/uv/update_checker.rb |
Ensures uv.toml requirements select the appropriate resolver behavior. |
uv/lib/dependabot/uv/update_checker/requirements_updater.rb |
UV-specific subclass to update requirements including uv.toml. |
uv/lib/dependabot/uv/file_updater.rb |
Filters tool-version deps from pip-compile/lock flows and invokes the new updater. |
uv/lib/dependabot/uv/file_updater/uv_version_file_updater.rb |
New updater that rewrites required-version in uv.toml and [tool.uv]. |
uv/spec/** + uv/spec/fixtures/** |
Adds fixtures and specs for parsing/updating behavior and edge cases. |
…et merge, add uv.toml to required files
| sig { override.returns(T::Array[String]) } | ||
| def self.ecosystem_specific_required_files | ||
| # uv.lock is not a standalone required file - it requires pyproject.toml | ||
| [] | ||
| %w(uv.toml) | ||
| end | ||
|
|
||
| sig { override.returns(String) } | ||
| def self.required_files_message | ||
| "Repo must contain a requirements.txt, uv.lock, requirements.in, or pyproject.toml" | ||
| "Repo must contain a requirements.txt, uv.lock, uv.toml, requirements.in, or pyproject.toml" | ||
| end |
There was a problem hiding this comment.
required_files_message states that a repo may contain uv.lock to be considered supported, but Dependabot::Python::SharedFileFetcher.required_files_in? does not treat uv.lock as a satisfying required file for the uv ecosystem (only .txt/.in, pyproject.toml, requirements, or ecosystem_specific_required_files, which is currently just uv.toml). This can mislead users when they hit the "missing required files" error.
Consider either (a) removing uv.lock from the message / clarifying it requires pyproject.toml, or (b) adding uv.lock to ecosystem_specific_required_files if it should truly be sufficient on its own.
What are you trying to accomplish?
Add support for parsing and updating the
required-versionfield inuv.tomland[tool.uv]inpyproject.tomlwithin the UV ecosystem.UV projects can pin their required UV tool version via
required-version(e.g.required-version = "==0.6.12"). Before this change, Dependabot had no awareness of this field and could not propose version bumps for the UV tool itself. This enables Dependabot to detect the pinned UV version as a dependency and create PRs to update it, just like it does for package dependencies.Closes #14376
Anything you want to highlight for special attention from reviewers?
The UV tool version is modeled as a dependency named
uv:required-version. This synthetic name avoids collision with any realuvpackage inDependencySet, which merges dependencies by name.FileUpdater#package_dependenciesfilters it out by name before passing deps toCompileFileUpdater/LockFileUpdater, so it doesn't interfere with pip-compile or lock file resolution.Both
uv.tomlandpyproject.tomlare supported as sources. The parser checks both files and can produce dependencies from each independently.uv.tomlis included inecosystem_specific_required_filesso repos that only haveuv.toml(nopyproject.toml) are still supported by the file fetcher. When updatingpyproject.toml, the file updater scopes edits to the[tool.uv]section to avoid modifying identically-named keys in other TOML sections.The
RequirementsUpdaterhas a dedicatedupdated_uv_toml_requirementmethod foruv.tomlfiles. Rather than inheriting Python's fullupdated_pyproject_requirementpath (which has Poetry/pyproject-specific branching),uv.tomlgets a simpler handler that just bumps the version when unsatisfied.How will you know you've accomplished your goal?
Given a repo with
required-version = "==0.6.12"inuv.tomlor[tool.uv]inpyproject.toml:uv:required-versionas a dependency with version0.6.12.required-versionvalue in the correct file without altering unrelated content.>=0.6.0, the parser reports no pinned version and the updater leaves already-satisfied ranges unchanged.Checklist