## Summary
`CLICOLOR_FORCE` changes the output of underlying build commands, which
messes with wrapper tools trying to parse their output.
Closes#12564, closes#15415.
Add support for `RUST_LOG` to the uv build backend. While we were
previously using logging statements in the uv build backend, they could
only be shown when when using the direct build fast path through uv, as
there was no tracing subscriber to write log messages out. This means no
debug logging when using the build backend through pip, `python -m
build`, an incompatible version of uv, or any other build frontend; No
option to figure why includes and excludes behave the way they do.
This PR closes this gap by adding a tracing subscriber. The only option
to enable it is `RUST_LOG`, as we don't have a CLI. The formatting style
is the same as for uv, and color is also support in the same way, albeit
only through anstream's support for TTYs and environment variables. We
recommend only `RUST_LOG=uv=debug` and `RUST_LOG=uv=verbose` in the
docs, but this can be used to debug into crates such as `glob`, too.
<img width="1008" height="325" alt="image"
src="https://github.com/user-attachments/assets/d33df219-750b-46a2-b3b4-8895aa137ab9"
/>
**Before**
```
$ pip wheel . -v [...]
Looking in links: /home/konsti/projects/uv/target/wheels/
Processing /home/konsti/projects/uv/scripts/packages/built-by-uv
Running command pip subprocess to install build dependencies
Looking in links: /home/konsti/projects/uv/target/wheels/
Processing /home/konsti/projects/uv/target/wheels/uv_build-0.8.13-py3-none-manylinux_2_39_x86_64.whl
Installing collected packages: uv_build
Successfully installed uv_build-0.8.13
Installing build dependencies ... done
Running command Getting requirements to build wheel
Getting requirements to build wheel ... done
Running command Preparing metadata (pyproject.toml)
Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: built-by-uv
Running command Building wheel for built-by-uv (pyproject.toml)
Error: Unsupported glob expression in: `tool.uv.build-backend.*-exclude`
Caused by:
Invalid character `!` at position 10 in glob: `**/build-*!$§%!½¼²¼³¬!§%$§%.h`. hint: Characters can be escaped with a backslash
error: subprocess-exited-with-error
× Building wheel for built-by-uv (pyproject.toml) did not run successfully.
│ exit code: 1
╰─> See above for output.
note: This error originates from a subprocess, and is likely not a problem with pip.
full command: /usr/bin/python3 /usr/lib/python3/dist-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py build_wheel /tmp/tmpow1illc9
cwd: /home/konsti/projects/uv/scripts/packages/built-by-uv
Building wheel for built-by-uv (pyproject.toml) ... error
ERROR: Failed building wheel for built-by-uv
Failed to build built-by-uv
ERROR: Failed to build one or more wheels
```
**After**
```
$ RUST_LOG=uv=debug pip wheel . -v [...]
Looking in links: /home/konsti/projects/uv/target/wheels/
Processing /home/konsti/projects/uv/scripts/packages/built-by-uv
Running command pip subprocess to install build dependencies
Looking in links: /home/konsti/projects/uv/target/wheels/
Processing /home/konsti/projects/uv/target/wheels/uv_build-0.8.13-py3-none-manylinux_2_39_x86_64.whl
Installing collected packages: uv_build
Successfully installed uv_build-0.8.13
Installing build dependencies ... done
Running command Getting requirements to build wheel
Getting requirements to build wheel ... done
Running command Preparing metadata (pyproject.toml)
DEBUG Writing metadata files to /tmp/pip-modern-metadata-l_kh78cj
DEBUG Found PEP 639 license declarations, using METADATA 2.4
DEBUG License files match: `LICENSE-APACHE`
DEBUG License files match: `LICENSE-MIT`
DEBUG License files match: `third-party-licenses/PEP-401.txt`
Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: built-by-uv
Running command Building wheel for built-by-uv (pyproject.toml)
DEBUG Checking metadata directory /tmp/pip-modern-metadata-l_kh78cj/built_by_uv-0.1.0.dist-info
DEBUG Found PEP 639 license declarations, using METADATA 2.4
DEBUG License files match: `LICENSE-APACHE`
DEBUG License files match: `LICENSE-MIT`
DEBUG License files match: `third-party-licenses/PEP-401.txt`
DEBUG Writing wheel at /tmp/pip-wheel-bu6to9i7/built_by_uv-0.1.0-py3-none-any.whl
DEBUG Wheel excludes: ["__pycache__", "*.pyc", "*.pyo", "build-*!$§%!½¼²¼³¬!§%$§%.h", "/src/built_by_uv/not-packaged.txt"]
Error: Unsupported glob expression in: `tool.uv.build-backend.*-exclude`
Caused by:
Invalid character `!` at position 10 in glob: `**/build-*!$§%!½¼²¼³¬!§%$§%.h`. hint: Characters can be escaped with a backslash
error: subprocess-exited-with-error
× Building wheel for built-by-uv (pyproject.toml) did not run successfully.
│ exit code: 1
╰─> See above for output.
note: This error originates from a subprocess, and is likely not a problem with pip.
full command: /usr/bin/python3 /usr/lib/python3/dist-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py build_wheel /tmp/tmpjrxou13a
cwd: /home/konsti/projects/uv/scripts/packages/built-by-uv
Building wheel for built-by-uv (pyproject.toml) ... error
ERROR: Failed building wheel for built-by-uv
Failed to build built-by-uv
ERROR: Failed to build one or more wheels
```
(There is no color in the above uv log statements, as pip doesn't
register as a TTY)
Fixes#12723
Allows pinning the Python build version via environment variables, e.g.,
`UV_PYTHON_CPYTHON_BUILD=...`. Each variable is implementation specific,
because they use different versioning schemes.
Updates the Python download metadata to include a `build` string, so we
can filter downloads by the pin. Writes the build version to a file in
the managed install, e.g., `cpython-3.10.18-macos-aarch64-none/BUILD`,
so we can filter installed versions by the pin.
Some important follow-up here:
- Include the build version in not found errors (when pinned)
- Automatically use a remote list of Python downloads to satisfy build
versions not present in the latest embedded download metadata
Some less important follow-ups to consider:
- Allow using ranges for build version pins
## Summary
We've received several requests to validate that installed wheels match
the current Python platform. This isn't _super_ common, since it
requires that your platform changes in some meaningful way (e.g., you
switch from x86 to ARM), though in practice, it sounds like it _can_
happen in HPC environments. This seems like a good thing to do
regardless, so we now validate that the tags (as recoded in `WHEEL`) are
consistent with the current platform during installs.
Closes https://github.com/astral-sh/uv/issues/15035.
## Summary
After chatting with the PyTorch team, it looks like some number of
wheels were accidentally uploaded with
`no-cache,no-store,must-revalidate` due to
https://github.com/pytorch/pytorch/pull/149218. They're going to correct
this for the respective wheels. I've encouraged them to set an immutable
caching header for these files, and it might happen. But even if this
isn't set, by default we only allow these wheels to be cached for 600s,
since the other wheels don't include a `Cache-Control` header at all
(but do include a `Last-Modified`, so we cache based on our heuristic:
`Freshness lifetime heuristically assumed because of presence of
last-modified header: 600s`). This probably leads to tons of unnecessary
downloads for users over time. Andrey from the PyTorch team agreed that
we should do this.
Closes https://github.com/astral-sh/uv/issues/15480.
## Summary
This is causing some cyclic dependencies issues for me, because these
can be used in virtually _any_ crate (like `uv-install-wheel`), which
then means that all of `uv-configuration` becomes a dependency, etc. I
think this should be a leaf crate so that we can safely depend on it
anywhere.
<!--
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
<!-- What's the purpose of the change? What does it do, and why? -->
Closes#14866. Adds a `no-install-local` flag to the sync and export
commands that excludes locally defined packages from being installed.
This helps with if you're caching your virtual environment. You can
exclude local packages since they're more likely to change between
builds.
## Test Plan
snapshot test: `sync::no_install_local`
CI
## Notes
I made an `InstallOptions` struct to avoid a crate isolation issue I was
running into while implementing.
Thanks for maintaining this project!
## Summary
There isn't any risk here, and we have reports of at least one zip file
with more than one (but fewer than, e.g., 10) null bytes.
Closes https://github.com/astral-sh/uv/issues/15451.
## Summary
Packages like `triton` should come from the PyTorch index, but they
don't actually vary across (e.g.) the `cu128` or `cu129` indexes.
Closes https://github.com/astral-sh/uv/issues/15446.
## Test Plan
Validate that the following pins to `cu128`, rather than `cpu`:
```
echo "vllm\ntorch==2.7.1+cu128" | cargo run pip compile --torch-backend=auto --extra-index-url https://wheels.vllm.ai/b2f6c247a9b84556a8ea0e75bb4a2db765ff3315 - --python-platform linux --python-version 3.13 -v
```
## Summary
After #15395, I realized that we didn't actually need a separate struct
for this since we now pass it around as an `Option`. (The key change
from #15395 is that when combining, we treat the options as a single
unit.)
## Summary
`match-runtime` can be explicitly specified, and if it's `false` it
should behave the same way as if it's omitted.
## Test Plan
Added snapshot test
We should not unnecessarily leak memory. Instead, we follow the general
patterns and use `Cow` for strings that can be from either a static or a
dynamic source.
## Summary
Right now, if you put `upgrade = false` in a `uv.toml`, then pass
`--upgrade-package numpy` on the CLI, we won't upgrade NumPy. This PR
fixes that interaction by ensuring that when we "combine", we look at
those arguments holistically (i.e., we bundle `upgrade` and
`upgrade-package` into a single struct, which then goes through the
`.combine` logic), rather than combining `upgrade` and `upgrade-package`
independently.
If approved, I then need to add the same thing for `no-build-isolation`,
`reinstall`, `no-build`, and `no-binary`.
## Summary
Add torch cuda 12.9 backend
<!-- What's the purpose of the change? What does it do, and why? -->
## Test Plan
<!-- How was it tested? -->
---------
Signed-off-by: youkaichao <youkaichao@gmail.com>
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
## Summary
The PyTorch team publishes ARM Linux wheels for `triton` to the PyTorch
index, which aren't available on PyPI.
## Test Plan
```
echo "torch" | cargo run pip compile - --torch-backend=cu128 --python-platform aarch64-unknown-linux-gnu --python-version 3.13
```
Previously failed because it couldn't find a compatible `triton` wheel.
As a frontend to Ruff's formatter.
There are some interesting choices here, some of which may just be
temporary:
1. We pin a default version of Ruff, so `uv format` is stable for a
given uv version
2. We install Ruff from GitHub instead of PyPI, which means we don't
need a Python interpreter or environment
3. We do not read the Ruff version from the dependency tree
See https://github.com/astral-sh/ruff/pull/19665 for a prototype of the
LSP integration.