1007 Commits

Author SHA1 Message Date
Zanie Blue
c4d0caaee5 Bump version to 0.5.11 (#10044) 2024-12-19 18:01:45 -06:00
Zanie Blue
37b11ddb22 Bump version to 0.5.10 (#9983) 2024-12-17 14:53:19 -06:00
Zanie Blue
3fae5332c1 Fix Cargo.lock by updating thiserror (#9975) 2024-12-17 10:53:44 -06:00
konsti
ebc6d20d9d Better build error messages (#9660)
Build failures are one of the most common user facing failures that
aren't "obivous" errors (such as typos) or resolver errors. Currently,
they show more technical details than being focussed on this being an
error in a subprocess that is either on the side of the package or -
more likely - in the build environment, e.g. the user needs to install a
dev package or their python version is incompatible.

The new error message clearly delineates the part that's important (this
is a build backend problem) from the internals (we called this hook) and
is consistent about which part of the dist building stage failed. We
have to calibrate the exact wording of the error message some more. Most
of the implementation is working around the orphan rule, (this)error
rules and trait rules, so it came out more of a refactoring than
intended.

Example:


![image](https://github.com/user-attachments/assets/2bc12992-db79-4362-a444-fd0d94594b77)
2024-12-17 09:44:32 -06:00
konsti
b7df5dbaf3 Avoid liblzma-dev system dep in uv-dev and uv-bench (#9933)
Enable `lzma-sys/static` through the performance feature not only in uv,
but in uv-dev and uv-bench too, to avoid the system dependency on
`liblzma-dev`.

Ref #9880
2024-12-17 16:12:33 +01:00
konsti
431ddc1d74 Change backtracking when packages conflict too much (#9843)
Background reading: https://github.com/astral-sh/uv/issues/8157
Companion PR: https://github.com/astral-sh/pubgrub/pull/36
Requires for test coverage: https://github.com/astral-sh/packse/pull/230

When two packages A and B conflict, we have the option to choose a lower
version of A, or a lower version of B. Currently, we determine this by
the order we saw a package (assuming equal specificity of the
requirement): If we saw A before B, we pin A until all versions of B are
exhausted. This can lead to undesirable outcomes, from cases where it's
just slow (sentry) to others cases without lower bounds where be
backtrack to a very old version of B. This old version may fail to build
(terminating the resolution), or it's a version so old that it doesn't
depend on A (or the shared conflicting package) anymore - but also is
too old for the user's application (fastapi). #8157 collects such cases,
and the `wrong-backtracking` packse scenario contains a minimized
example.

We try to solve this by tracking which packages are "A"s, culprits, and
"B"s, affected, and manually interfering with project selection and
backtracking. Whenever a version we just chose is rejected, we give the
current package a counter for being affected, and the package it
conflicted with a counter for being a culprit. If a package accumulates
more counts than a threshold, we reprioritize: Undecided after the
culprits, after the affected, after packages that only have a single
version (URLs, `==<version>`). We then ask pubgrub to backtrack just
before the culprit. Due to the changed priorities, we now select package
B, the affected, instead of package A, the culprit.

To do this efficiently, we ask pubgrub for the incompatibility that
caused backtracking, or just the last version to be discarded (due to
its dependencies). For backtracking, we use the last incompatibility
from unit propagation as a heuristic. When a version is discarded
because one of its dependencies conflicts with the partial solution, the
incompatibility tells us the package in the partial solution that
conflicted.

We only backtrack once per package, on the first time it passes the
threshold. This prevents backtracking loops in which we make the same
decisions over and over again. But we also changed the priority, so that
we shouldn't take the same path even after the one time we backtrack (it
would defeat the purpose of this change).

There are some parameters that can be tweaked: Currently, the threshold
is set to 5, which feels not too eager with so me of the conflicts that
we want to tolerate but also changes strategies quickly. The relative
order of the new priorities can also be changed, as for each (A, B) pair
the priority of B is afterwards lower than that for A. Currently,
culprits capture conflict for the whole package, but we could limit that
to a specific version. We could discard conflict counters after
backtracking instead of keeping them eternally as we do now. Note that
we're always taking about pairs (A, B), but in practice we track
individual packages, not pairs.

A case that we wouldn't capture is when B is only introduced to the
dependency graph after A, but I think that would require cyclical
dependency for A and B to conflict? There may also be cases where
looking at the last incompatibility is insufficient.

Another example that we can't repair with prioritization is
urllib3/boto3/botocore: We actually have to check all the newer versions
of boto3 and botocore to identify the version that allows with the older
urllib3, no shortcuts allowed.

```
urllib3<1.25.4
boto3
```

All examples I tested were cases with two packages where we only had to
switch the order, so I've abstracted them into a single packse case.

This PR changes the resolution for certain paths, and there is the risk
for regressions.

Fixes #8157

---

All tested examples improved.

Input fastapi:
```text
starlette<=0.36.0
fastapi<=0.115.2
```

```
# BEFORE
$ uv pip --no-progress compile -p 3.11 --exclude-newer 2024-10-01 --no-annotate debug/fastapi.txt
annotated-types==0.7.0
anyio==4.6.0
fastapi==0.1.17
idna==3.10
pydantic==2.9.2
pydantic-core==2.23.4
sniffio==1.3.1
starlette==0.36.0
typing-extensions==4.12.2

# AFTER
$ cargo run --profile fast-build --no-default-features pip compile -p 3.11 --no-progress --exclude-newer 2024-10-01 --no-annotate debug/fastapi.txt 
annotated-types==0.7.0
anyio==4.6.0
fastapi==0.109.1
idna==3.10
pydantic==2.9.2
pydantic-core==2.23.4
sniffio==1.3.1
starlette==0.35.1
typing-extensions==4.12.2
```


Input xarray:
```text
xarray[accel]
```

```
# BEFORE
$ uv pip --no-progress compile -p 3.11 --exclude-newer 2024-10-01 --no-annotate debug/xarray-accel.txt
bottleneck==1.4.0
flox==0.9.13
llvmlite==0.36.0
numba==0.53.1
numbagg==0.8.2
numpy==2.1.1
numpy-groupies==0.11.2
opt-einsum==3.4.0
packaging==24.1
pandas==2.2.3
python-dateutil==2.9.0.post0
pytz==2024.2
scipy==1.14.1
setuptools==75.1.0
six==1.16.0
toolz==0.12.1
tzdata==2024.2
xarray==2024.9.0

# AFTER
$ cargo run --profile fast-build --no-default-features pip compile -p 3.11 --no-progress --exclude-newer 2024-10-01 --no-annotate debug/xarray-accel.txt
bottleneck==1.4.0
flox==0.9.13
llvmlite==0.43.0
numba==0.60.0
numbagg==0.8.2
numpy==2.0.2
numpy-groupies==0.11.2
opt-einsum==3.4.0
packaging==24.1
pandas==2.2.3
python-dateutil==2.9.0.post0
pytz==2024.2
scipy==1.14.1
six==1.16.0
toolz==0.12.1
tzdata==2024.2
xarray==2024.9.0
```


Input sentry: The resolution is identical, but arrived at much faster:
main tries 69 versions (sentry-kafka-schemas: 63), PR tries 12 versions
(sentry-kafka-schemas: 6; 5 times conflicting, then once the right
version).

```text
python-rapidjson<=1.20,>=1.4
sentry-kafka-schemas<=0.1.113,>=0.1.50
```

```
# BEFORE
$ uv pip --no-progress compile -p 3.11 --exclude-newer 2024-10-01 --no-annotate debug/sentry.txt
fastjsonschema==2.20.0
msgpack==1.1.0
python-rapidjson==1.8
pyyaml==6.0.2
sentry-kafka-schemas==0.1.111
typing-extensions==4.12.2

# AFTER
$ cargo run --profile fast-build --no-default-features pip compile -p 3.11 --no-progress --exclude-newer 2024-10-01 --no-annotate debug/sentry.txt
fastjsonschema==2.20.0
msgpack==1.1.0
python-rapidjson==1.8
pyyaml==6.0.2
sentry-kafka-schemas==0.1.111
typing-extensions==4.12.2
```


Input apache-beam
```text
# Run on Python 3.10
dill<0.3.9,>=0.2.2
apache-beam<=2.49.0
```

```
# BEFORE
$ uv pip --no-progress compile -p 3.10 --exclude-newer 2024-10-01 --no-annotate debug/apache-beam.txt
  × Failed to download and build `apache-beam==2.0.0`
  ╰─▶ Build backend failed to determine requirements with `build_wheel()` (exit status: 1)

# AFTER
$ cargo run --profile fast-build --no-default-features pip compile -p 3.10 --no-progress --exclude-newer 2024-10-01 --no-annotate debug/apache-beam.txt
apache-beam==2.49.0
certifi==2024.8.30
charset-normalizer==3.3.2
cloudpickle==2.2.1
crcmod==1.7
dill==0.3.1.1
dnspython==2.6.1
docopt==0.6.2
fastavro==1.9.7
fasteners==0.19
grpcio==1.66.2
hdfs==2.7.3
httplib2==0.22.0
idna==3.10
numpy==1.24.4
objsize==0.6.1
orjson==3.10.7
proto-plus==1.24.0
protobuf==4.23.4
pyarrow==11.0.0
pydot==1.4.2
pymongo==4.10.0
pyparsing==3.1.4
python-dateutil==2.9.0.post0
pytz==2024.2
regex==2024.9.11
requests==2.32.3
six==1.16.0
typing-extensions==4.12.2
urllib3==2.2.3
zstandard==0.23.0
```
2024-12-16 11:39:50 +01:00
renovate[bot]
2b61a67cf7 Update Rust crate rustix to v0.38.42 (#9924) 2024-12-15 20:12:42 -05:00
renovate[bot]
34281d96f1 Update Rust crate thiserror to v2.0.7 (#9926) 2024-12-15 20:12:08 -05:00
renovate[bot]
3617dd1b46 Update Rust crate serde to v1.0.216 (#9925) 2024-12-15 20:11:53 -05:00
Charlie Marsh
0652800cb0 Bump version to v0.5.9 (#9889) 2024-12-13 17:28:19 -05:00
Charlie Marsh
d2fb4c585d Patch sysconfig data at install time (#9857)
## Summary

This PR reimplements
[`sysconfigpatcher`](https://github.com/bluss/sysconfigpatcher) in Rust
and applies it to our Python installations at install-time, ensuring
that the `sysconfig` data is more likely to be correct.

For now, we only rewrite prefixes (i.e., any path that starts with
`/install` gets rewritten to the correct absolute path for the current
machine).

Unlike `sysconfigpatcher`, this PR does not yet do any of the following:

- Patch `pkginfo` files.
- Change `clang` references to `cc`.

A few things that we should do as follow-ups, in my opinion:

1. Rewrite
[`AR`](c1ebf8ab92/src/sysconfigpatcher.py (L61)).
2. Remove `-isysroot`, which we already do for newer builds.
2024-12-13 14:36:22 -05:00
Zanie Blue
80d41671bc Bump version to 0.5.8 (#9791) 2024-12-11 15:18:51 +00:00
renovate[bot]
3b727b7323 Update Rust crate target-lexicon to 0.13.0 (#9729) 2024-12-10 20:34:07 -05:00
Charlie Marsh
3ee2b10738 Enable uv tool uninstall uv on Windows (#8963)
## Summary

Extending self-delete and self-replace functionality to uv itself on
Windows.

Closes https://github.com/astral-sh/uv/issues/6400.
2024-12-10 13:13:22 -05:00
renovate[bot]
b17902da0f Update Rust crate thiserror to v2.0.6 (#9727) 2024-12-09 01:15:25 +00:00
Charlie Marsh
c4f3d1cf14 Run cargo update (#9712) 2024-12-07 22:50:22 -05:00
Zanie Blue
3ca155ddd6 Bump version to 0.5.7 (#9698) 2024-12-06 17:50:21 -06:00
konsti
6ed6fc108e Build backend: Add direct builds to the resolver and installer (#9621)
This is like #9556, but at the level of all other builds, including the
resolver and installer. Going through PEP 517 to build a package is
slow, so when building a package with the uv build backend, we can call
into the uv build backend directly instead: No temporary virtual env, no
temp venv sync, no python subprocess calls, no uv subprocess calls.

This fast path is gated through preview. Since the uv wheel is not
available at test time, I've manually confirmed the feature by comparing
`uv venv && cargo run pip install . -v --preview --reinstall .` and `uv
venv && cargo run pip install . -v --reinstall .`. When hacking the
preview so that the python uv build backend works without the setting
the direct build also (wheel built with `maturin build --profile
profiling`), we can see the perfomance difference:

```
$ hyperfine --prepare "uv venv" --warmup 3 \
    "UV_PREVIEW=1 target/profiling/uv pip install --no-deps --reinstall scripts/packages/built-by-uv --preview" \
    "target/profiling/uv pip install --no-deps --reinstall scripts/packages/built-by-uv --find-links target/wheels/"
Benchmark 1: UV_PREVIEW=1 target/profiling/uv pip install --no-deps --reinstall scripts/packages/built-by-uv --preview
  Time (mean ± σ):      33.1 ms ±   2.5 ms    [User: 25.7 ms, System: 13.0 ms]
  Range (min … max):    29.8 ms …  47.3 ms    73 runs
 
Benchmark 2: target/profiling/uv pip install --no-deps --reinstall scripts/packages/built-by-uv --find-links target/wheels/
  Time (mean ± σ):     115.1 ms ±   4.3 ms    [User: 54.0 ms, System: 27.0 ms]
  Range (min … max):   109.2 ms … 123.8 ms    25 runs
 
Summary
  UV_PREVIEW=1 target/profiling/uv pip install --no-deps --reinstall scripts/packages/built-by-uv --preview ran
    3.48 ± 0.29 times faster than target/profiling/uv pip install --no-deps --reinstall scripts/packages/built-by-uv --find-links target/wheels/
```

Do we need a global option to disable the fast path? There is one for
`uv build` because `--force-pep517` moves `uv build` much closer to a
`pip install` from source that a user of a library would experience (See
discussion at #9610), but uv overall doesn't really make guarantees
around the build env of dependencies, so I consider the direct build a
valid option.

Best reviewed commit-by-commit, only the last commit is the actual
implementation, while the preview mode introduction is just a
refactoring touching too many files.
2024-12-04 15:57:18 +00:00
konsti
19c3c08bf3 Improve build frontend error handling (#9611)
Move the error handling for `build_package` into an enum, to avoid
`bail!` and duplicated `.context()` calls.
2024-12-04 09:04:23 +00:00
Zanie Blue
ae033e2d3b Improve message when updater receipt is for a different uv executable (#9487)
Attempts to improve confusing messaging in cases like
https://github.com/astral-sh/uv/issues/6774#issuecomment-2504950681,
when the receipt is for a different uv executable.

```
❯ cargo run --all-features -q -- self update
warning: Self-update is only available for uv binaries installed via the standalone installation scripts.

The current executable is at `/Users/zb/workspace/uv/target/debug/uv` but the standalone installer was used to install uv to `/Users/zb/.cargo`. Are multiple copies of uv installed?
```

Requires https://github.com/axodotdev/axoupdater/pull/221
Closes https://github.com/astral-sh/uv/issues/6774
2024-12-04 01:26:32 +00:00
Zanie Blue
59460b8a7c Bump version to 0.5.6 (#9612) 2024-12-03 14:13:06 -06:00
Charlie Marsh
75949f3fec Avoid cloning String in marker evaluation (#9598)
## Summary

A small TODO that I found interesting. See:
https://github.com/astral-sh/pubgrub/pull/35.
2024-12-03 14:28:04 +00:00
renovate[bot]
89a25ba465 Update Rust crate rustc-hash to v2.1.0 (#9569) 2024-12-02 01:23:42 +00:00
renovate[bot]
b5807754fe Update Rust crate indexmap to v2.7.0 (#9567) 2024-12-01 20:07:06 -05:00
renovate[bot]
2ee710a620 Update tokio-tracing monorepo (#9566) 2024-12-01 20:06:59 -05:00
renovate[bot]
0a42c3c340 Update Rust crate syn to v2.0.90 (#9564) 2024-12-01 20:06:47 -05:00
renovate[bot]
3ee6ef2556 Update Rust crate rkyv to v0.8.9 (#9563) 2024-12-01 20:06:40 -05:00
renovate[bot]
f92640cf2a Update Rust crate pathdiff to v0.2.3 (#9562) 2024-12-01 20:06:34 -05:00
renovate[bot]
fb64fb7e13 Update Rust crate jiff to v0.1.15 (#9561) 2024-12-01 20:06:28 -05:00
renovate[bot]
ef20d6a92a Update Rust crate cargo-util to v0.2.16 (#9560) 2024-12-01 20:06:20 -05:00
konsti
8a863194c8 Use SharedState for build dispatch (#9553)
When looking at the build frontend code, I noticed that we always pass
every single field of the shared state to the build dispatch:

```rust
    let build_dispatch = BuildDispatch::new(
        ...
        &state.index,
        &state.git,
        &state.capabilities,
        &state.in_flight,
        ...
    );
```

We can abstract this by moving `SharedState` into the build dispatch.
The `BuildDispatch` then has only immutable fields and the
`SharedState`. Since the `SharedState` is all `Arc`s, we can clone it
freely.
2024-12-01 17:20:28 -05:00
Zanie Blue
95cd8b8b3f Bump version to 0.5.5 (#9478) 2024-11-27 11:37:39 -06:00
Charlie Marsh
916d5d7778 Migrate to PubGrub's arena for package names (#9448)
## Summary

There's more we can do here, i.e., to leverage the IDs more widely, but
this is a start.
2024-11-26 15:05:39 -05:00
konsti
c94777fc54 Initialize rayon lazily (#9435)
When performing a noop sync, we don't need the rayon threadpool, yet we
pay for its initialization:

![Screenshot from 2024-11-26
08-59-07](https://github.com/user-attachments/assets/d918f50d-b5b7-4bdd-820d-cbe71b633aaa)

Be making the initialization lazy, we avoid that cost:

![Screenshot from 2024-11-26
09-53-08](https://github.com/user-attachments/assets/193baea0-667f-4b9d-9a75-886a86f0f837)

This code runs every time before user code in `uv run`.

This means that before calling rayon, one now needs to call
`LazyLock::force(&RAYON_INITIALIZE);`.

Performance mode (CPU 0 is a perf core):
```
$ taskset -c 0 hyperfine --warmup 5 -N "/home/konsti/projects/uv/uv-main sync" "/home/konsti/projects/uv/target/profiling/uv sync"
Benchmark 1: /home/konsti/projects/uv/uv-main sync
  Time (mean ± σ):       4.5 ms ±   0.1 ms    [User: 2.7 ms, System: 1.8 ms]
  Range (min … max):     4.4 ms …   6.4 ms    640 runs
 
  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.
 
Benchmark 2: /home/konsti/projects/uv/target/profiling/uv sync
  Time (mean ± σ):       4.4 ms ±   0.1 ms    [User: 2.7 ms, System: 1.6 ms]
  Range (min … max):     4.3 ms …   5.0 ms    679 runs
 
Summary
  /home/konsti/projects/uv/target/profiling/uv sync ran
    1.03 ± 0.04 times faster than /home/konsti/projects/uv/uv-main sync
```

Power saver mode:
```
$ hyperfine --warmup 5 -N "/home/konsti/projects/uv/uv-main sync" "/home/konsti/projects/uv/target/profiling/uv sync"
Benchmark 1: /home/konsti/projects/uv/uv-main sync
  Time (mean ± σ):      28.1 ms ±   1.2 ms    [User: 15.5 ms, System: 20.3 ms]
  Range (min … max):    25.7 ms …  31.9 ms    102 runs
 
Benchmark 2: /home/konsti/projects/uv/target/profiling/uv sync
  Time (mean ± σ):      24.0 ms ±   1.2 ms    [User: 13.8 ms, System: 9.9 ms]
  Range (min … max):    22.2 ms …  28.2 ms    122 runs
 
Summary
  /home/konsti/projects/uv/target/profiling/uv sync ran
    1.17 ± 0.08 times faster than /home/konsti/projects/uv/uv-main sync
```
2024-11-26 14:58:38 +00:00
Charlie Marsh
0158717ae6 Don't warn when --output-file is empty (#9417)
## Summary

Closes https://github.com/astral-sh/uv/issues/9410.
2024-11-25 22:09:18 +00:00
renovate[bot]
288d128065 Update Rust crate url to v2.5.4 (#9405) 2024-11-24 20:48:44 -05:00
renovate[bot]
0c944681b1 Update Rust crate syn to v2.0.89 (#9404) 2024-11-24 20:48:37 -05:00
renovate[bot]
ab0e1552ac Update Rust crate proc-macro2 to v1.0.92 (#9403) 2024-11-24 20:48:31 -05:00
renovate[bot]
abd8281328 Update Rust crate hashbrown to v0.15.2 (#9402) 2024-11-24 20:48:11 -05:00
renovate[bot]
64f65031b7 Update Rust crate async-compression to v0.4.18 (#9401) 2024-11-24 20:48:03 -05:00
Charlie Marsh
c62c83c37a Bump version to v0.5.4 (#9290) 2024-11-20 16:01:24 -05:00
Charlie Marsh
1b13036674 Add retries for Python downloads (#9274)
## Summary

This uses the same approach as in the rest of uv, but with another
dedicated method for retries.

Closes https://github.com/astral-sh/uv/issues/8525.
2024-11-20 09:42:42 -05:00
Charlie Marsh
ccc0962cbd Use zlib-rs on all platforms (#9264) 2024-11-20 00:01:58 -05:00
Ben Beasley
80ab562f9f In uv-globfilter, use the workspace fs-err in dev-dependencies (#9262)
<!--
Thank you for contributing to uv! To help us out with reviewing, please
consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->

## Summary

In uv-globfilter, use the workspace `fs-err` in `dev-dependencies`.

This fixes an unnecessary dev-dependency on `fs-err` 2.x even after the
workspace fs-err was updated to 3.x in
https://github.com/astral-sh/uv/pull/8625.

The `Cargo.lock` file still has `fs-err v2.11.0` after this PR, but it
is via `tracing-durations-export v0.3.0` rather than directly required
by any `uv` crate.

## Test Plan

<!-- How was it tested? -->

```
$ cd crates/uv-globfilter/
$ cargo test
```
2024-11-20 03:59:37 +00:00
Charlie Marsh
45eeae61ff Use existing index field in PEP 723 scripts (#9238)
## Summary

Purely internal, this setting already exists.
2024-11-19 14:45:12 -05:00
Charlie Marsh
56d3622087 Bump version to v0.5.3 (#9229) 2024-11-19 18:53:54 +00:00
renovate[bot]
dae630ae50 Update Rust crate fs-err to v3 (#8625) 2024-11-19 15:09:00 +00:00
Charlie Marsh
0aaa6ba5be Migrate to zlib-rs (#9184)
## Summary

I've tried this a few times; just curious if it passes tests.
2024-11-18 15:45:14 +00:00
konsti
a07d5a1d18 Update pubgrub to Ranges::from_iter (#9145)
Co-authored-by: Zanie Blue <contact@zanie.dev>
2024-11-18 12:28:17 +00:00
renovate[bot]
b7de92d22c Update Rust crate spdx to v0.10.7 (#9182) 2024-11-17 20:50:26 -05:00