Repository navigation
uv: update lockstep-pinned dependencies together - #16509
Draft
wenceslas-sanchez wants to merge 26 commits into
Draft
wenceslas-sanchez wants to merge 26 commits into
wenceslas-sanchez wants to merge 26 commits into
Conversation
Open
1 task done
1 task done
Author
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What are you trying to accomplish?
Fixes #16390 (second half, stacked on #16507).
Stacked on #16507: the first 4 commits here are that PR, only the last 22 are new. Clean diff on top of it: wenceslas-sanchez#1
When two direct dependencies are pinned in lockstep (
opentelemetry-api==1.25.0+opentelemetry-sdk==1.25.0,or the httpx2/httpcore2 case in the issue), neither can move alone and Dependabot skips both, grouped or not.
This implements full unlock for uv, behind the
uv_lockstep_full_unlockexperiment::ownnow asks uvinstead of trusting the registry. If uv's conflict names another direct dependency, the ladder moves on to
:all.:allworks like Bundler's force updater: rewrite the dependency's pin, runuv lock, and on a conflict takethe package names from uv's full conflict output (including the text behind
UpdateNotPossible, not just theshort message). Those peers are relaxed to
>= <locked>and the lock is retried, at most 3 rounds. Peers don'tget
--upgrade-package, so uv only moves a peer when it has to, instead of to its latest release.Anything you want to highlight for special attention from reviewers?
another direct dependency counts. Any other resolution failure (a new release needing a newer Python, or uv
rewording its message so we find no names) keeps today's behaviour: the file updater reports it as before.
Failures that aren't resolution failures (build, auth, network) now come out of the
:owncheck instead, withthe same error.
update-typesrules aren'tapplied to peers either, so a peer can take a major bump inside a patch/minor-only group.
Grouping lockstep packages together avoids that.
second PR that overlaps with this one.
uv lockfor pyproject dependencies that have a top-level neighbour in uv.lock (dependenciesonly in uv.lock already go through uv, so they aren't probed again).
:allreuses that runas its first round, so a real conflict adds one more
uv lockper discovery round (usually one). That's the mainreason it's behind an experiment.
:alldirectly on a fresh checker, before:ownhas been asked, just returns false.How will you know you've accomplished your goal?
Specs for the resolver (forward and reverse direction, a peer found further down uv's derivation, multi-round,
giving up when a round finds no new peer, a peer that uv forks onto several versions before or after the lock,
extras, cooldown in and out of the window, conflicts that name no other direct dependency, the peer filters that
skip build-system-only, local and unversioned dependencies, and reuse of the
:ownrun) and for the checker(experiment on/off,
:ownvs:all, the security fix stopping at the lowest fixed version). The checker specsthat matter most run the real resolver and
LockFileUpdaterwith only the uv shell command, the Python installand PyPI stubbed, feeding them real conflict messages from uv 0.11.25 and from 0.12.20 (same output as the 0.12.18 dependabot ships): they check that only
--upgrade-package opentelemetry-api==1.26.0is passed, that sdk is relaxed to>=1.25.0, that:ownthen:alltakes twouv lockruns, and that asking about the peer's side (sdk) also reports it can't move alone.The name parsing is also checked against nine conflict messages excerpted from uv's own test snapshots
(forked
{marker}nodes, extras, dependency groups, Python-version conflicts, ranges) plus two generated with uv(0.11.25 and 0.12.20). Names follow PEP 508 the way
uv-pep508parses them.One thing I hit along the way: since uv 0.12.14 (picked up in #16276) uv prints conflicts as
error: No solution found …/cause: …instead of× No solution found …, soLockFileErrorHandler::UV_UNRESOLVABLE_REGEXstopped matching. This PRonly makes the lockstep resolver recognise both formats; the handler fix for everyone else is #16511 (issue #16510).
I also ran the checker end to end with no stubs (real uv 0.12.18 from the dev image, real PyPI, experiment on)
on the lockstep fixture:
:ownis false,:allis true, and api and sdk both go 1.25.0 → 1.45.1 inpyproject.tomland
uv.lock.Locally:
bin/test uv(1303 examples, 0 failures, 2 pending that are skipped by the spec helper) and RuboCop(no offenses).
srb tcdoesn't work in my image, so I ran the sorbet binary directly with the repo'ssorbet/config: no errors.Checklist