Skip to content

uv: Support parsing and updating tool.uv.required-version field#14581

Open
r7sy wants to merge 5 commits intodependabot:mainfrom
r7sy:uv/support-required-version
Open

uv: Support parsing and updating tool.uv.required-version field#14581
r7sy wants to merge 5 commits intodependabot:mainfrom
r7sy:uv/support-required-version

Conversation

@r7sy
Copy link
Copy Markdown

@r7sy r7sy commented Mar 30, 2026

What are you trying to accomplish?

Add support for parsing and updating the required-version field in uv.toml and [tool.uv] in pyproject.toml within 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 real uv package in DependencySet, which merges dependencies by name. FileUpdater#package_dependencies filters it out by name before passing deps to CompileFileUpdater/LockFileUpdater, so it doesn't interfere with pip-compile or lock file resolution.

Both uv.toml and pyproject.toml are supported as sources. The parser checks both files and can produce dependencies from each independently. uv.toml is included in ecosystem_specific_required_files so repos that only have uv.toml (no pyproject.toml) are still supported by the file fetcher. When updating pyproject.toml, the file updater scopes edits to the [tool.uv] section to avoid modifying identically-named keys in other TOML sections.

The RequirementsUpdater has a dedicated updated_uv_toml_requirement method for uv.toml files. Rather than inheriting Python's full updated_pyproject_requirement path (which has Poetry/pyproject-specific branching), uv.toml gets 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" in uv.toml or [tool.uv] in pyproject.toml:

  • The file parser detects uv:required-version as a dependency with version 0.6.12.
  • The update checker resolves a newer version and produces updated requirements.
  • The file updater rewrites the required-version value in the correct file without altering unrelated content.
  • For range constraints like >=0.6.0, the parser reports no pinned version and the updater leaves already-satisfied ranges unchanged.
  • All behaviors are validated by specs covering exact pins, ranges, empty values, multi-file scenarios, section-collision edge cases, and non-uv dependency filtering. RuboCop passes with 0 offenses and all tests pass.

Checklist

  • I have run the complete test suite to ensure all tests and linters pass.
  • I have thoroughly tested my code changes to ensure they work as expected, including adding additional tests for new functionality.
  • I have written clear and descriptive commit messages.
  • I have provided a detailed description of the changes in the pull request, including the problem it addresses, how it fixes the problem, and any relevant details about the implementation.
  • I have ensured that the code is well-documented and easy to understand.

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
@r7sy r7sy requested a review from a team as a code owner March 30, 2026 21:59
Copilot AI review requested due to automatic review settings March 30, 2026 21:59
r7sy and others added 3 commits March 31, 2026 00:02
- 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)
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-version into a synthetic dependency (grouped as uv-required-version) from uv.toml and pyproject.toml.
  • Update-check and file-update logic to bump the required-version constraint and scope edits to [tool.uv] in pyproject.toml.
  • Fetch uv.toml and 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.

@r7sy r7sy requested a review from Copilot March 30, 2026 22:24
@r7sy r7sy changed the title uv: Support parsing and updating required-version field uv: Support parsing and updating tool.uv.required-version field Mar 30, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.

Comment on lines 35 to 43
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
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support updating required-version in uv.toml and [tool.uv] in pyproject.toml

2 participants