Currently, Python discovery happens sequentially — which is good most of
the time because uv will lazily exit once it finds a satisfactory
version. However, in `uv python list`, uv needs to query all
interpreters on the system which makes sequential discovery quite slow.
Here, we add parallelization to discovery. Annoyingly, it means a fair
amount of code repetition, but I've done my best to minimize that.
In the long-term, we may want to consolidate these code paths such that
uv can do prefetching during normal discovery, since technically if the
interpreter we want is far down the PATH then laziness does not save us
anything.
```
Benchmark 1: main
Time (mean ± σ): 3.108 s ± 0.026 s [User: 2.290 s, System: 0.386 s]
Range (min … max): 3.072 s … 3.157 s 8 runs
Benchmark 2: branch
Time (mean ± σ): 414.1 ms ± 11.1 ms [User: 2955.2 ms, System: 743.7 ms]
Range (min … max): 398.1 ms … 429.5 ms 8 runs
Summary
branch ran
7.51 ± 0.21 times faster than main
```
## Summary
This expands the usage of global preview in a key area which has
wide-ranging impact.
Key notes:
* uv-dev needs to set up default global preview because of this.
Although it seems like it should technically have been setting it up
earlier?
* A number of tests no longer pass `Preview::default()` but also don't
use the guard. This is because they only call into the preview stuff
when the relevant conda environment variables are present. Which we
assume they're not (otherwise the tests would be invalid for other
reasons). There's really a hermeticity issue here, but I've addressed it
in a separate PR.
## Test Plan
Tests have been modified, but existing coverage should be sufficient.
This adds abstractions for handing hints, pulling them out of ad-hoc
addendums to error messages and treating them as a first-class concept
so we can render them more consistently.
The key concepts are:
- `Hints`: a wrapper struct for `Vec<Cow<'a, str>>`
- `Hint`: a trait with `hints(&self) -> Hints<'_>`
Error types now `impl Hint` to provide hints. This means errors need to
carry more information to construct the `Hint` lazily instead of ahead
of time. The majority of refactoring around error types is to support
that change.
When displaying errors, we
[downcast](https://github.com/astral-sh/uv/pull/18090/changes#r2935662966)
to each type known to implement the trait and extract hints. We then
display all the hints after the error chain is complete.
The user-facing affect of this is that hints are now always rendered
outside the error chain.
This is a blocker to #17110 and is pulled out of that project. There is
still some weirdness with miette's `help:` prompts that will be removed
entirely in a following change.
---------
Co-authored-by: Codex <noreply@openai.com>
Includes a few things...
- Drops preview warnings for use of `uv python upgrade` and `uv python
install --upgrade`
- Adds `--resolve-links` to `uv python find`, which I needed in test
cases to retain existing snapshots
- Fixes issues in our "Using environment ..." messages on Windows which
were incorrect
- Refactors `from_executable` for the `PythonMinorVersionLink` type
(https://github.com/astral-sh/uv/pull/17842/commits/28b2ed2525327d94fdf5372a29bbbc476d74680f)
to use the type system to prevent incorrect construction (for above)
- Removes special casing where we only upgrade links if they already
exist, which existed so preview wasn't needed on every invocation
- Fixes a bug with `PythonMinorVersionLink::exists` which returned
`true` even if the link pointed to the wrong Python installation leading
to discovery failures