Add experimental uv resolver for Python lockfiles#22949
Add experimental uv resolver for Python lockfiles#22949Liam-Deacon wants to merge 3 commits intopantsbuild:mainfrom
Conversation
|
Wow, this is a really creative design 🤩 |
|
Thanks for the contribution. We've just branched for 2.31.x, so merging this pull request now will come out in 2.32.x, please move the release notes updates to docs/notes/2.32.x.md if that's appropriate. |
bc17fc2 to
efc7d06
Compare
|
Hi maintainers 👋 — just rebased this onto the latest Summary of what this PR adds:
Known limitations (documented in the option help):
Would love a review from anyone familiar with the Python backend / lockfile generation — @cburroughs, @stuhood, @benjy, or whoever is currently shepherding the lockfile work. Happy to iterate! |
|
Thanks for this! Excited to review. I will try and take a look in the next day or two. I somehow missed this back when it was first created in, looks like, December. Sorry about that! Meanwhile, if you used LLMs in the making of this PR, can you elaborate on that? We are working on an official AI disclosure policy but haven't yet put one into practice. |
benjyw
left a comment
There was a problem hiding this comment.
Before I review the meat of this PR: a couple of seemingly unrelated changes got pulled in here.
| root_str, | ||
| dep_entries | ||
| .iter() | ||
| .map(|d| format!("\"{}\"", d.entry_str)) |
There was a problem hiding this comment.
Why these changes?
They aren't wrong, but AFAICT they are irrelevant to the purpose of this PR, and they don't seem to have any benefit. These strings are going to be consumed either here or immediately after, when they go out of scope.
| // Licensed under the Apache License, Version 2.0 (see LICENSE). | ||
|
|
||
| use std::convert::{AsRef, Infallible}; | ||
| use std::convert::Infallible; |
|
Hello, @Liam-Deacon @benjyw Can I help you somehow with PR? |
|
One question - why universal style is unsupported? I see no reason not to support him here. |
Summary
This PR adds an experimental
uv-backed resolver option for Python user lockfile generation.Pants still generates and consumes Pex lockfiles, but when opted in it uses
uv pip compileto pre-resolve pins, then usespex lock create --no-transitiveto materialize the Pex lock.pex lock create)[uv].argsMotivation
Issue: #20679 — faster, more ergonomic lockfile generation by leveraging
uv.How it works
Usage
1) Enable resolves and select the uv resolver
2) Pass arbitrary uv flags (passthrough)
Use the standard
argspattern (same as other downloadable tools in Pants):Equivalent CLI:
pants generate-lockfiles --resolve=python-default \ --python-lockfile-resolver=uv \ --uv-args='--index-strategy unsafe-first-match'Current limitations (intentional safeguards)
lock_style = "universal"uv pip compileresolves for a single interpreter environment todaycomplete_platformssources/overrides/excludesnot yet modeled in uv stepBenchmark (real-world example)
Environment:
CPython==3.11.*strictpipvsuv~/repos/python-mono/3rdparty/python/requirements.txt~/repos/python-mono/3rdparty/python/requirements-dev.txtpip.antarcticaam.app/privatereferencesblpapi,StressVaR,module-wrapper,pytest-localstackTiming (
/usr/bin/time -p, Pantsd disabled; repeated to show warm-cache behavior):Method:
/tmp/pants-uv-lockfile-benchmark(isolated), usingpython_requirements(...)pointing at the filteredrequirements.in.PANTS_WORKDIRto avoid Pants's local process cache reusing results.PANTS_GLOBAL_PEX_ROOT=/tmp/pants-uv-lockfile-benchmark/cache/pex_rootPIP_CACHE_DIR=/tmp/pants-uv-lockfile-benchmark/cache/pip_cacheUV_CACHE_DIR=/tmp/pants-uv-lockfile-benchmark/cache/uv_cachepippipuvuvSpeedup (lower is better):
pip/uv = 3.58xpip/uv = 1.16xNotes:
uvpre-solve materially reduces cold-cache solve time in this real-world-ish set.Additional visibility (uv mode only):
uv pip compilepre-solve (previous run-set)In this run-set,
uvreduced end-to-end wall time vspip(especially cold-cache). Warm-cache repeats narrow the gap, which suggests resolver overhead is a larger fraction of first-time generation than subsequent runs.Code changes
src/python/pants/backend/python/subsystems/setup.py[python].lockfile_resolver = {pip,uv}src/python/pants/backend/python/subsystems/uv.pyuvtool +[uv].argspassthroughsrc/python/pants/backend/python/goals/lockfile.pyuv pip compilepre-step (opt-in) thenpex lock create --no-transitivesrc/python/pants/backend/python/goals/lockfile_test.pydocs/docs/python/overview/lockfiles.mdx