## Summary
I tried to fix minor typos in the project
---------
Co-authored-by: Samuel Rigaud <rigaud@gmail.com>
Co-authored-by: konstin <konstin@mailbox.org>
## Summary
Fixes the logic for escaping a double quoted string in PowerShell by not
escaping a backslash but escaping the Unicode double quote variants that
PowerShell treats the same as the ASCII double quotes.
<img width="685" height="99" alt="image"
src="https://github.com/user-attachments/assets/ac1368c2-d915-4e49-b67f-ac71ee0f7d46"
/>
## Test Plan
There does not seem to be any tests for this. I'm fairly new to rust but
happy to add some if someone can point me in the right direction.
---------
Co-authored-by: Aria Desires <aria.desires@gmail.com>
Hello,
# Summary
This PR makes the error message clearer when you try to install packages
into an externally managed Python environment with the `--system` flag.
Now, instead of just failing, the error explains that you're hitting
this because you explicitly used `--system`.
This closes#15639.
# Test plan
- I added a new integration test (`install_with_system_interpreter` in
`pip_install.rs`) that checks the error message includes the hint.
- I tried to run `uv pip install --system -r requirements.txt` to see
the actual error message in action, but had permission issues.
Fixes#16340
## Summary
Some package registries (PyTorch, corporate PyPI mirrors) return `403
Forbidden` when a package is not found, instead of `404 Not Found`. The
previous error message incorrectly suggested this was always an
authentication issue, causing confusion for users.
This PR updates the error hint to clarify that a 403 error could
indicate either missing authentication credentials OR that the package
doesn't exist on the index.
## Test Plan
- Updated existing snapshot test in `crates/uv/tests/it/edit.rs` to
reflect the new error message
- The change is purely a message improvement with no behavioral changes
## Changes
### Before
hint: An index URL (https://example.com/simple) could not be queried due
to a lack of valid authentication credentials (403 Forbidden).
### After
hint: An index URL (https://example.com/simple) returned a 403 Forbidden
error. This could indicate missing authentication credentials, or the
package may not exist on this index.
## Files Changed
- `crates/uv-resolver/src/pubgrub/report.rs` - Updated error message
- `crates/uv/tests/it/edit.rs` - Updated snapshot test expectation
---------
Co-authored-by: eun2ce <eun2ce@eun2ceui-MacBookPro.local>
Co-authored-by: konstin <konstin@mailbox.org>
## Summary
fixes issue #15938
- show platform wheel hint with a concrete
`tool.uv.required-environments` example so users know how to configure
compatibility
- add `WheelTagHint::suggest_environment_marker` to pick a sensible
environment marker based on the available wheel tags
- update the `sync_required_environment_hint` integration snapshot to
expect the new multi-line hint
## Test Plan
cargo test --package uv --test it --
sync::sync_required_environment_hint
<!--
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? -->
The warning shown when `egg-info` lacks `top_level.txt` incorrectly
warns about missing `top-level.txt`
ee2649feaa/crates/uv-install-wheel/src/uninstall.rs (L179-L188)ee2649feaa/crates/uv/src/commands/pip/operations.rs (L687-L693)
The non fatal warning with incorrect filename was introduced in
https://github.com/astral-sh/uv/pull/6881 which changed previous fatal
error https://github.com/astral-sh/uv/issues/6872 with correct
`top_level.txt` output.
## Test Plan
<!-- How was it tested? -->
Updated unit test to reflect change in warning
This PR enables `--torch-backend=auto` to automatically detect Intel
GPUs. It follows up on
[#14386](https://github.com/astral-sh/uv/pull/14386).
On Windows, detection is implemented by querying the
`Win32_VideoController` class via the [WMI
crate](https://github.com/ohadravid/wmi-rs/tree/v0.16.0).
Currently, Intel GPUs (XPU) do not depend on specific driver or toolkit
versions to determine which PyTorch wheel to use.
<!--
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
HTTP1.1 [RFC 9112 -
HTTP/1.1](https://www.rfc-editor.org/rfc/rfc9112.html#name-status-line)
section 4 defines the response status code to optionally include a text
description (human readable) of the reason for the status code.
[RFC9113 - HTTP/2](https://www.rfc-editor.org/rfc/rfc9113) is the HTTP2
protocol standard and the response status only considers the [status
code](https://www.rfc-editor.org/rfc/rfc9113#name-response-pseudo-header-fiel)
and not the reason phrase, and as such important information can be lost
in helping the client determine a route cause of a failure.
As per discussion on this
[PR](https://github.com/astral-sh/uv/pull/15979) the current feeling is
that implementing the RFC9457 standard might be the preferred route.
This PR makes those changes to aid the discussion which has also been
moved to the [PEP
board](https://discuss.python.org/t/block-download-of-components-when-violating-policy/104021/1)
## Test Plan
Pulling components that violate our policy over HTTP2 and without any
RFC9457 implementation the following message is presented to the user:
<img width="1482" height="104" alt="image"
src="https://github.com/user-attachments/assets/0afcd0d8-ca67-4f94-a6c2-131e3b6d8dcc"
/>
With the RFC9457 standard implemented, below you can see the advantage
in the extra context as to why the component has been blocked:
<img width="2171" height="127" alt="image"
src="https://github.com/user-attachments/assets/25bb5465-955d-4a76-9f30-5477fc2c866f"
/>
---------
Co-authored-by: konstin <konstin@mailbox.org>
<!--
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
Fixes#16285
## Test Plan
<!-- How was it tested? -->
Sometimes a credential's `Debug` formatted value appears in tracing logs
- make sure the credential doesn't appear there.
## Test plan
Added a test case + ran
```
uv pip install --default-index $PYX_API_URL/$SOME_INDEX $SOME_PACKAGE -vv
```
With an authenticated uv client and confirmed the tokens are obfuscated.
---------
Co-authored-by: Zsolt Dollenstein <zsol.zsol@gmail.com>
## Summary
- Move parsing `UV_CONCURRENT_INSTALLS`, `UV_CONCURRENT_BUILDS` and
`UV_CONCURRENT_DOWNLOADS` to `EnvironmentOptions`
Relates https://github.com/astral-sh/uv/issues/14720
## Test Plan
- Tests with existing tests
- Add test with invalid parsing
<!--
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?
-->
Closes#15312
Closes https://github.com/astral-sh/uv/issues/16237
---------
Co-authored-by: pythonweb2 <32141163+pythonweb2@users.noreply.github.com>
Co-authored-by: Wade Roberts <wade.roberts@centralsquare.com>
## Summary
Adds the version for environment variables added in
https://github.com/astral-sh/uv/pull/16040 and
https://github.com/astral-sh/uv/pull/16125. as these were in-flight
before documentation versioning was added.
Adds ability to emit a compiler error when added in is missing for
improved reporting to the developer.
e.g. example for the ones fixed in this PR
```shell
error: missing #[attr_added_in("x.y.z")] on `UV_UPLOAD_HTTP_TIMEOUT`
note: env vars for an upcoming release should be annotated with `#[attr_added_in("next release")]`
--> crates\uv-static\src\env_vars.rs:593:15
|
593 | pub const UV_UPLOAD_HTTP_TIMEOUT: &'static str = "UV_UPLOAD_HTTP_TIMEOUT";
| ^^^^^^^^^^^^^^^^^^^^^^
error: missing #[attr_added_in("x.y.z")] on `UV_WORKING_DIRECTORY`
note: env vars for an upcoming release should be annotated with `#[attr_added_in("next release")]`
--> crates\uv-static\src\env_vars.rs:1087:15
|
1087 | pub const UV_WORKING_DIRECTORY: &'static str = "UV_WORKING_DIRECTORY";
| ^^^^^^^^^^^^^^^^^^^^
error: could not compile `uv-static` (lib) due to 2 previous errors
```
Cargo is currently recompiling uv-python on every invocation because the
minified JSON output file is getting a mod time newer than the last run.
Instead, set the mod time of the output file to the same as the input
file.
## Summary
When specifying constraints or overrides in combination with
`pylock.toml` as an input to `uv pip install`,
the error messages are not currently correct.
## Test Plan
No testing, it's a straightforward error string fix.
---------
Co-authored-by: Zanie Blue <contact@zanie.dev>
## Summary
- Move parsing `UV_HTTP_TIMEOUT`, `UV_REQUEST_TIMEOUT` and
`HTTP_TIMEOUT` to `EnvironmentOptions`
- Add new env varialbe `UV_UPLOAD_HTTP_TIMEOUT`
Relates https://github.com/astral-sh/uv/issues/14720
## Test Plan
Tests with existing tests
I think this is ostensively breaking, though I think the impact would be
small given this will go out in 0.9.1 and should only affect people
using pre-release Python versions.
When `3.14.0` is requested (opposed to `3.14`), we treat this as a
request for a final / stable version and ignore pre-releases.
I think this is a fairly clean way to allow users to explicitly request
the stable version.
Closes https://github.com/astral-sh/uv/issues/16175
Follows #16208
## Summary
Fixes [1633](https://github.com/astral-sh/uv/issues/16133). Preserves
comments preceding "version = ..." line when uv version --bump is ran
## Test Plan
Added IT test
---------
Co-authored-by: konsti <konstin@mailbox.org>
Example output:
```
$ uv-debug init foo -v
DEBUG uv 0.9.0+6 (d3324baf68 2025-10-08)
DEBUG Acquired shared lock for `/home/konsti/.cache/uv`
DEBUG No Python version file found in ancestors of working directory: /home/konsti/projects/foo
DEBUG Checking for Python environment at: `foo/.venv`
DEBUG Searching for default Python interpreter in managed installations or search path
DEBUG Searching for managed installations at `/home/konsti/.local/share/uv/python`
DEBUG Found managed installation `cpython-3.14.0-linux-x86_64-gnu`
DEBUG Found `cpython-3.14.0-linux-x86_64-gnu` at `/home/konsti/.local/share/uv/python/cpython-3.14.0-linux-x86_64-gnu/bin/python3.14` (managed installations)
DEBUG Using Python version `>=3.14` from default interpreter
DEBUG `git rev-parse --is-inside-work-tree` failed but didn't contain `not a git repository` in stderr for `/home/konsti/projects/foo`
DEBUG No Python version file found in ancestors of working directory: /home/konsti/projects/foo
DEBUG Writing Python versions to `/home/konsti/projects/foo/.python-version`
Initialized project `foo` at `/home/konsti/projects/foo`
DEBUG Released lock at `/home/konsti/.cache/uv/.lock`
```
First commit is refactoring, second commit is the actual change.
The h2 errors, a specific type nested in reqwest errors, all look like
they shouldn't happen in regular operations and should be retried. This
covers all `io::Error`s going through h2 (i.e., only HTTP 2
connections).
Fixes https://github.com/astral-sh/uv/issues/15916
## Summary
As new environment variables get introduced (e.g. `UV_EDITABLE`) I
thought it would useful to start tracking which release they were
introduced. I think its a common workflow to navigate to the [env var
documentation](https://docs.astral.sh/uv/reference/environment) to know
what the env var for something is but then end up in a situation where
one is using an environment variable with the wrong version of uv and
not notice immediately that its not compatible and therefore ignored.
## Test Plan
Existing tests.
The versions in `since` have all been manually reviewed to the best of
my ability for correctness.
<!--
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? -->
This pull request enables the `--directory` option to accept environment
variable: `UV_DIRECTORY`
### Motivation
Currently, the `--project` option already supports environment
variables, but --directory does not.
The motivation for this change is the same as for the --project option.
When using this option, it’s likely that the project root and the
directory containing the uv project differ. In such cases, allowing
environment variables makes it easier to avoid repeatedly specifying the
directory in commands or task runners.
### Other PRs
- PR for create `--project` option:
https://github.com/astral-sh/uv/pull/12327
## Test Plan
<!-- How was it tested? -->
### no auto testing
As with the --project option, no auto tests are included for this
change.
This is because the implementation relies on Clap’s built-in attribute
functionality, and testing such behavior would effectively mean testing
a third-party crate, which would be redundant.
As long as the compiler accepts it, things should work as expected.
### testing manually
i tested manually like [previous pull
request](https://github.com/astral-sh/uv/pull/12327)
```shell
$ cargo build --locked
./target/debug/uv init uv_directory
$ mkdir uv_directory
$ UV_DIRECTORY=uv_directory ./target/debug/uv sync
Using CPython 3.14.0rc3
Creating virtual environment at: .venv
Resolved 1 package in 15ms
Audited in 0.04ms
$ UV_DIRECTORY=uv_directory ./target/debug/uv run main.py
Hello from uv-directory!
$ ./target/debug/uv run main.py
error: Failed to spawn: `main.py`
Caused by: No such file or directory (os error 2)
```
---------
Co-authored-by: Zanie Blue <contact@zanie.dev>
<!--
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?
-->
Hey devs, great tool as always, you're doing amazing work.
## Summary
<!-- What's the purpose of the change? What does it do, and why? -->
Adds the following fields to the `[package]` table of `Cargo.toml` files
where they were missing:
```toml
rust-version = { workspace = true }
homepage = { workspace = true }
documentation = { workspace = true }
repository = { workspace = true }
authors = { workspace = true }
license = { workspace = true }
```
Most crates already had these fields, this just aligns the rest for
consistency.
This also resolves the warnings from `cargo-deny` when using `uv` crates
as dependencies in Pixi.
## Test Plan
No tests needed, this only updates metadata.
Pick up python-build-standalone tag 20251007 to add 3.14.0 final
and 3.13.8, and adjust tests.
Also, fix matching version requests with prereleases: `uvx
python@3.14.0rc3` should not be satisfied by 3.14.0 final.
Co-authored-by: Geoffrey Thomas <geofft@ldpreload.com>
The `uv-python` crate reads the checked-in download metadata to write
out a minified version to be statically included into the binary.
Sometimes, the resulting `download-metadata-minified.json` can go
missing, such as when `uv` is installed via `cargo` as a git source, and
there is an update; `cargo` will do a hard reset on the git repo it
stores in the cache, causing it to be deleted. In these instances, the
`uv-python` crate does not currently re-run its build script, because as
it happens, there was no change to the `download-metadata.json` since it
was last compiled. This causes a build error like:
```
Updating git repository `https://github.com/astral-sh/uv`
Installing uv v0.8.24 (https://github.com/astral-sh/uv?tag=0.8.24#252f8873)
Updating crates.io index
Compiling uv-version v0.8.24 (/home/skhawtho/.cargo/git/checkouts/uv-c9e40703e19509a8/252f887/crates/uv-version)
Compiling uv-git v0.0.1 (/home/skhawtho/.cargo/git/checkouts/uv-c9e40703e19509a8/252f887/crates/uv-git)
Compiling uv-build-backend v0.1.0 (/home/skhawtho/.cargo/git/checkouts/uv-c9e40703e19509a8/252f887/crates/uv-build-backend)
Compiling uv-configuration v0.0.1 (/home/skhawtho/.cargo/git/checkouts/uv-c9e40703e19509a8/252f887/crates/uv-configuration)
Compiling uv-client v0.0.1 (/home/skhawtho/.cargo/git/checkouts/uv-c9e40703e19509a8/252f887/crates/uv-client)
Compiling uv-extract v0.0.1 (/home/skhawtho/.cargo/git/checkouts/uv-c9e40703e19509a8/252f887/crates/uv-extract)
Compiling uv-workspace v0.0.1 (/home/skhawtho/.cargo/git/checkouts/uv-c9e40703e19509a8/252f887/crates/uv-workspace)
Compiling uv-python v0.0.1 (/home/skhawtho/.cargo/git/checkouts/uv-c9e40703e19509a8/252f887/crates/uv-python)
Compiling uv-requirements-txt v0.0.1 (/home/skhawtho/.cargo/git/checkouts/uv-c9e40703e19509a8/252f887/crates/uv-requirements-txt)
Compiling uv-bin-install v0.0.1 (/home/skhawtho/.cargo/git/checkouts/uv-c9e40703e19509a8/252f887/crates/uv-bin-install)
Compiling uv-publish v0.1.0 (/home/skhawtho/.cargo/git/checkouts/uv-c9e40703e19509a8/252f887/crates/uv-publish)
error: couldn't read `crates/uv-python/src/download-metadata-minified.json`: No such file or directory (os error 2)
--> crates/uv-python/src/downloads.rs:795:45
|
795 | const BUILTIN_PYTHON_DOWNLOADS_JSON: &str = include_str!("download-metadata-minified.json");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: could not compile `uv-python` (lib) due to 1 previous error
error: failed to compile `uv v0.8.24 (https://github.com/astral-sh/uv?tag=0.8.24#252f8873)`, intermediate artifacts can be found at `/home/skhawtho/.cache/cargo`.
To reuse those artifacts with a future compilation, set the environment variable `CARGO_TARGET_DIR` to that path.
```
This fixes the issue by also adding a `rerun-if-changed` on the
resulting minified JSON file.
Separately, this revision also changes the output directory of the
minified file to the build script's output directory via the `OUT_DIR`
environment variable, so as not to pollute the source code.
Resolves https://github.com/astral-sh/uv/issues/15665
`uv tool upgrade` already respects version pins, but when a tool was
installed with an exact version the command quietly becomes a no-op even
though users expect it to upgrade the executable. This change tweaks the
upgrade flow to detect that situation by inspecting the stored receipt
and, whenever the tool stays pinned, emit a concise hint explaining why
the version didn’t move and how to reinstall without the pin.
The message still appears if the run only refreshed supporting packages,
so users aren’t misled by dependency churn that leaves the tool itself
untouched.
I also added an integration test for the scenario end to end by
installing `babel==2.6.0`, attempting an upgrade, and asserting that the
hint is shown alongside the dependency updates.
Closes https://github.com/astral-sh/uv/issues/16112
```
❯ cargo run -q cache clean
Cache is currently in-use, waiting for other uv processes to finish (use `--force` to override)
```
Otherwise, `-v` is required to see we're waiting on a lock.
I'd rather do this than elevate the exclusive lock log message to
something more verbose because this allows us to use a more specific
message as appropriate for the situation. We also previously reduced the
verbosity of arbitrary locks, e.g., see
https://github.com/astral-sh/uv/issues/7489
<!--
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? -->
Fixes a part of #14720
Add `TRACING_DURATIONS_FILE` to EnvironmentOptions.
## Test Plan
<!-- How was it tested? -->
## Summary
We serialize the index to the lockfile without the username, so if we
compare based on `==` and the user _includes_ the username in their
`pyproject.toml`, the check will always fail.
Closes https://github.com/astral-sh/uv/issues/16076.
Resolves https://github.com/astral-sh/uv/issues/16067
When we build the dependency graph we add an edge per `Requires-Dist`.
If a package publishes multiple marker-guarded requirements (like
pylint’s `dill>=…` for different Python versions), more than one marker
can evaluate to true at runtime, which gives us several edges pointing
to the same installed package node.
To avoid printing the package multiple times, we gather all edges
targeting that node, pass them through a `Cursor`, and aggregate their
requirement details before we print the dependency line. That
aggregation does two things:
1. If any edge carries a URL, we return that URL immediately.
2. Otherwise we merge all version specifiers into one canonical PEP 440
string.
I've added an integration test, namely `cargo test -p uv --test it
--features pypi -- no_duplicate_dependencies_with_markers` exercises the
new snapshot that installs pylint (with the real dill duplication
scenario present in the original issue) and asserts the tree output,
both with and without `--show-version-specifiers`, now shows a single
dill entry with the merged constraint.
## Summary
I don't think it's common for this to matter, but in theory at least
it's important that these are ordered by severity. Otherwise, e.g,
changing the pre-release mode (and then returning early) could mean we
retain the forks when we otherwise shouldn't.
## Summary
This argument has always existed for compatibility, but apparently we
don't respect it. I assume it was unintentionally dropped during a
refactor.
Closes https://github.com/astral-sh/uv/issues/15950.
Coming soon: The Renovate bot (GitHub App) will be renamed to Mend. PRs
from Renovate will soon appear from 'Mend'. Learn more
[here](https://redirect.github.com/renovatebot/renovate/discussions/37842).
This PR contains the following updates:
| Package | Type | Update | Change |
|---|---|---|---|
| [anyhow](https://redirect.github.com/dtolnay/anyhow) |
workspace.dependencies | patch | `1.0.99` -> `1.0.100` |
---
> [!WARNING]
> Some dependencies could not be looked up. Check the Dependency
Dashboard for more information.
---
### Release Notes
<details>
<summary>dtolnay/anyhow (anyhow)</summary>
###
[`v1.0.100`](https://redirect.github.com/dtolnay/anyhow/releases/tag/1.0.100)
[Compare
Source](https://redirect.github.com/dtolnay/anyhow/compare/1.0.99...1.0.100)
- Teach clippy to lint formatting arguments in `bail!`, `ensure!`,
`anyhow!`
([#​426](https://redirect.github.com/dtolnay/anyhow/issues/426))
</details>
---
### Configuration
📅 **Schedule**: Branch creation - "before 4am on Monday" (UTC),
Automerge - At any time (no schedule defined).
🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.
♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box
---
This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/astral-sh/uv).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MS45Ny4xMCIsInVwZGF0ZWRJblZlciI6IjQxLjk3LjEwIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJpbnRlcm5hbCJdfQ==-->
---------
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: konstin <konstin@mailbox.org>
## Summary
If you provide `--refresh` to `uv lock`, we'll now always resolve (even
though it might return the same result). This is also robust to
`--locked` such that `--refresh --locked` will only fail if the lockfile
changes.
Closes https://github.com/astral-sh/uv/issues/15997.
## Summary
This PR enables users to mark a URL as an S3 endpoint, at which point uv
will sign requests to that URL by detecting credentials from the
standard AWS environment variables, configuration files, etc.
Signing is handled by the
[reqsign](https://docs.rs/reqsign/latest/reqsign/) crate, which we can
also use in the future to sign requests for other providers.
We're seeing reports of a regression from
https://github.com/astral-sh/uv/pull/15888 where `--no-cache` causes `uv
run` and `uvx` to fail to spawn a command.
The intent of this code was to allow destructive cache operations
_after_ we'd finished setting up the environment. However, it's unclear
to me that it's safe to run `uv cache clean` during a `uv run` operation
(e.g., `uv run --script` uses an environment in the cache) and, more
importantly, we cannot drop non-persistent caches (e.g., from
`--no-cache`) as they include the environment we're spawning the command
in.
Alternative to #15977 which retains release of the lock — we may want to
consider that approach still but this regression needs to be resolved
quickly.
Closes https://github.com/astral-sh/uv/issues/15989
Closes https://github.com/astral-sh/uv/issues/15987
Closes https://github.com/astral-sh/uv/issues/15967
Turns out if the minor versions matched we returned false from
`is_upgrade_of` instead of continuing to compare prerelease versions.
Closes#15955.
Note: test cases were initially generated by Claude - I tried making
them shorter.
## Test plan
```
❯ cargo run -- -v python upgrade 3.14
[...]
DEBUG Inspecting existing executable at `/Users/zsol/.local/bin/python3.14`
DEBUG Replacing existing executable for `cpython-3.14.0rc2-macos-aarch64-none` at `/Users/zsol/.local/bin/python3.14` with executable for `cpython-3.14.0rc3-macos-aarch64-none` since it is an upgrade
DEBUG Updated executable at `/Users/zsol/.local/bin/python3.14` to cpython-3.14.0rc3-macos-aarch64-none
Installed Python 3.14.0rc3 in 5.04s
+ cpython-3.14.0rc3-macos-aarch64-none (python3.14)
[...]
❯ uvx python3.14 -V
Python 3.14.0rc3
```
Add an incompatibility that lets pubgrub skip of marker packages when
the base package already has an incompatible version to improve the
error messages (https://github.com/astral-sh/uv/issues/15199).
The change is also a small perf improvement. Overall this should be able
to improve performance in slow cases by avoiding trying proxy package
versions that are impossible anyway, for a (ideally very small cost) for
tracking the additional incompatibility and tracking the base package
for each proxy package.
```
$ hhyperfine --warmup 2 "uv pip compile --universal scripts/requirements/airflow.in" "target/release/uv pip compile --universal scripts/requirements/airflow.in"
Benchmark 1: uv pip compile --universal scripts/requirements/airflow.in
Time (mean ± σ): 145.5 ms ± 3.9 ms [User: 154.7 ms, System: 140.7 ms]
Range (min … max): 139.2 ms … 153.4 ms 20 runs
Benchmark 2: target/release/uv pip compile --universal scripts/requirements/airflow.in
Time (mean ± σ): 128.7 ms ± 5.5 ms [User: 141.9 ms, System: 137.3 ms]
Range (min … max): 121.8 ms … 142.0 ms 23 runs
Summary
target/release/uv pip compile --universal scripts/requirements/airflow.in ran
1.13 ± 0.06 times faster than uv pip compile --universal scripts/requirements/airflow.in
```
This implementation is the basic version: When we see a proxy
`foo{...}>=x,<y` we add a dependency edge `foo{...}>=x,<y` ->
`foo>=x,<y`. There are several way to extend this, which likely help
more with performance than with error messages.
One idea is that if we see `foo{...}>=x,<y` but we already made a
selection for `foo==z` outside that range, we can insert a dependency
`foo{...}!=z` -> `foo!=z`. This avoids trying any version of the proxy
package except the version that matches our previous selection.
Another is that if we see a dependency `foo>=x,<y`, we also add
`foo{...}>=x,y` -> `foo>=x,<y`. This allows backtracking beyond `foo`
immediately if all version of `foo{...}>=x,<y` are incompatible, since
`foo{...}>=x,<y` incompatible -> `foo>=x,<y` incompatible -> the package
that depended of `foo>=x,<y` is incompatible.
The cost for each of these operations is tracking an additional
incompatibility per virtual package. An alternative approach is to only
add the incompatibility lazily, only when we've tried several version of
the virtual package already. This needs to be weighed of with the better
error messages that the incompatibility gives, we unfortunately have
only few large reference examples.
Requires https://github.com/astral-sh/pubgrub/pull/45
Closes https://github.com/astral-sh/uv/issues/15199
Currently, `uv cache clean` and `uv cache prune` can cause crashes in
other uv processes running in parallel by removing their in-use files.
We can solve this by using a shared (read) lock on the cache directory,
while the `uv cache` operations use an exclusive (write) lock. The
drawback is that this is always one extra lock, and that we assume that
all platforms support shared locks.
Once Rust 1.89 fulfills our N-2 policy, we can add support for these
methods in fs_err and switch to
https://doc.rust-lang.org/std/fs/struct.File.html#platform-specific-behavior-2.
**Test Plan**
Open one terminal, run:
```
uv venv -c -p 3.13
UV_CACHE_DIR=cache uv cache clean
UV_CACHE_DIR=cache uv pip install numpy==2.0.0
```
Open another terminal, run:
```
UV_CACHE_DIR=cache uv cache clean
```
Fixes#15704
Part of #13883
<!--
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
I'm back again after #14041, this time for `win_arm64`. I [asked a
Windows on ARM
user](https://github.com/getlogbook/logbook/pull/451#issuecomment-3295513650)
what the value of `platform.machine()` is, and it's `ARM64`.
## Test Plan
Updated/added tests
Extends https://github.com/astral-sh/uv/pull/15679
I'm not sure if we want to do this. It is probably _generally_ true, but
I think I'd rather remove the special casing entirely? I think the main
case for this is that it could help prevent regressions from #15679 and
we can remove it in a breaking release?
While investigating https://github.com/astral-sh/uv/pull/15679, I
created an unnamed conda environment and noticed this quality which
allows us to detect that it's not the base environment.
## Summary
I spent time trying to figure out how to support this but came up empty.
It _seems_ like maybe the `DefaultFields` implementation in
`tracing-subscriber` uses debug formatting for fields...? So if you have
a string with ANSI codes, they end up printing as unformatted values? I
even reverted all our custom formatting in `logging.rs` and saw the same
thing.
Closes https://github.com/astral-sh/uv/issues/15840.
## Summary
Fixes issue #15190 where `uv sync --no-sources` fails to switch from
editable to registry package installations. The problem occurred because
the installer's satisfaction check didn't consider the `--no-sources`
flag when determining if an existing editable installation was
compatible with a registry requirement.
## Solution
Modified `RequirementSatisfaction::check()` to reject non-registry
installations when `SourceStrategy::Disabled` and the requirement is
from registry. Added `SourceStrategy` parameter threading through the
entire call chain from commands to the satisfaction check to ensure
consistent behavior between `uv sync --no-sources` and `uv pip install
--no-sources`.
---------
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
**Setup**
```
$ git clone https://github.com/wheelnext/variant_aarch64
$ cd variant_aarch64
$ git checkout 1d047e667dbce4c74878a68c653a6b41bc3d3684
```
**Before**
```
$ uv build -v
[...]
DEBUG Not using uv build backend direct build of , no pyproject.toml: TOML parse error at line 5, column 1
|
5 | [project]
| ^^^^^^^^^
missing field `version`
[...]
```
**After**
```
$ uv build -v
[...]
DEBUG Not using uv build backend direct build of ``, pyproject.toml does not match: The value for `build_system.build-backend` should be `"uv_build"`, not `"flit_core.buildapi"`
[...]
```
The empty string gets fixed in
https://github.com/astral-sh/uv/pull/15897
---------
Co-authored-by: Zanie Blue <contact@zanie.dev>
Closes https://github.com/astral-sh/uv/issues/15604
The previous logic does not match the discussion in the original issue
about this feature, nor does it match the comment for the function. I'm
confused because I know this logic is working for some people? I'm
consequently a little wary of making this change. I'm following up with
some additional changes that should ensure this is robust, e.g., #15680
<!--
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
- Added `RemovableReason` enum to track removal context
- Updated `OnExisting::Remove` to include source information
- Modified debug message to show appropriate context
- Updated all call sites to specify correct removal source
fixes: #14734
---------
Co-authored-by: Zanie Blue <contact@zanie.dev>
This PR contains two changes: The companion PR to
https://github.com/astral-sh/packse/pull/277, which moderately
simplifies the uv side, and switching to pylock.toml for packse as
dogfooding. These changes can be applied independent from each other.
Since all files, including the vendored build dependencies, are now on
GitHub Pages under the same root, we only need a packse index root URL.
<!--
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?
-->
Closes#15485
---------
Co-authored-by: Aditya-PS-05 <adityapratapsjnhh7654@gmail.com>
Co-authored-by: Zanie Blue <contact@zanie.dev>
Closes https://github.com/astral-sh/uv/issues/15818
Unfortunately, this is how we perform lookups. We could also change the
lookup to include the scheme. I expect all of this to change in the
future anyway, as I want to redesign the storage model for native
credentials.
## Summary
In the process of making a different change, I noticed that we parse
this during source discovery, throw it away, then parse it again later.
## Summary
If the target for `uv pip compile` is a `pyproject.toml` in a
subdirectory, we won't have loaded the credentials when we go to lower
(since it won't be loaded as part of "configuration discovery"). We now
add those indexes just-in-time.
Closes https://github.com/astral-sh/uv/issues/15362.
## Summary
I had to use ChatGPT to help with my research on the "correct"
architecture names for these platforms; there could still be some rough
edges, but this seems like an improvement.
Closes https://github.com/astral-sh/uv/issues/15799.
## Summary
I think this is leftover from a prior refactor whereby we used to avoid
reusing the cached environment if `--reinstall` was passed; but then we
stopped allowing `--reinstall` in `uv tool run` anyway, and this got
changed to `--refresh`. It seems wrong to skip cache reuse with
`--refresh`, though.
Closes https://github.com/astral-sh/uv/issues/15824.
## Summary
We allow space-delimiting for `--env-file`, but Clap doesn't support any
form of escaping, so as-is, there's no way to provide a `.env` file in a
directory that contains a space. We now do the splitting ourselves and
respect escapes.
Closes https://github.com/astral-sh/uv/issues/15806.
## Summary
Right now, we only list changes if the _version_ differs. This PR takes
the SHA into account. We may want to list changes to _any_ sources, but
that gets more complicated (e.g., if the user swaps the index URL, we'd
have to show _all_ changes to the index URL).
Closes#15810.
<!--
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
This change extends the default initialized projects with scikit and
maturin build backends to ensure that the rust or C++ build gets invoked
when a source file changes.
## Test Plan
`cargo run init cppextension-test --build-backend=scikit` followed by
manual testing of the behaviour of the resulting project under `uv run
--with jupyter jupyter lab` and changes to the source file of the
extension.
Analogous for `cargo run init maturin-test --build-backend=maturin `.
## Relevant Issues
The question of why the python extension is not rebuilt on source
changes has been discussed in
https://github.com/astral-sh/uv/issues/15701#issuecomment-3258714942.
<!--
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
- Added `conflicts_with = "only_group"` to `--extra` arguments in
`SyncArgs`, `RunArgs`, and `ExportArgs`
- Added tests to verify proper conflict detection and error messages
**Before:** The `--extra` flag was silently ignored when used with
`--only-group`
**After:** Clear error message: `error: the argument '--only-group
<ONLY_GROUP>' cannot be used with '--extra <EXTRA>'`
fixes: #15676
## Test Plan
- Tests confirm proper error message format when `--only-group` and
`--extra` are used together
- Verified existing functionality remains unchanged when flags are used
independently
## Summary
If the user explicitly authenticated to pyx, then we attempt to use the
pyx PyTorch URLs; otherwise, we stick to `download.pytorch.org` as the
default.
## Summary
Ignore managed pre-release versions of Python for purposes of creating a
`requires-python` constraint when running `uv init --script`. This makes
the behavior consistent with `uv init` for normal projects.
## Test Plan
Added a regression test that makes sure that the constraint is
`requires-python = ">=3.13"`, even though a pre-release version of 3.14
is installed.
Consistently omit backticks after a colon in build backend messages,
following
https://github.com/astral-sh/uv/pull/15733#discussion_r2330156783.
There's still 74 matches for `: {}"` and 183 matches for `: {[^{]*}"`,
but this PR clears all matches in the build backend.
The initial motivation for this change was that we were using both the
`windows`, the `window_sys` and the `windows_core` crate in various
places. These crates have slightly unconventional versioning scheme
where there is a large workspace with the same version in general, but
only some crates get breaking releases when a new breaking release
happens, the others stay on the previous breaking version. The `windows`
crate is a shim for all three of them, with a single version. This
simplifies handling the versions.
Using `windows` over `windows_sys` has the advantage of a higher level
error interface, we now get a `Result` for all windows API calls instead
of C-style int-returns and get-last-error calls. This makes the
uv-keyring crate more resilient.
We keep using the `windows_registry` crate, which provides a higher
level interface to windows registry access.
A user in the support chat had an error message for `uv build` with the
`uv_build` backend they didn't understand, which was caused by them
having a venv in their build directory. This PR adds a dedicated error
message when adding something to a distribution that looks like a venv.
When a user passes `--no-project` argument to `uv format` command,
instead of running the formatter in the context of the current project,
run it in the context of the current directory. This is useful when the
current directory is not a project.
Closes https://github.com/astral-sh/uv/issues/15462
Paths referencing above the directory of the `pyproject.toml`, such as
`module-root = ".."`, are not supported by the build backend. The check
that should catch was not working properly, so the source distribution
built successfully and only the wheel build failed. We now error early.
The same fix is applied to data includes.
Fix#15702
This PR contains the following updates:
| Package | Type | Update | Change |
|---|---|---|---|
| [mimalloc](https://redirect.github.com/purpleprotocol/mimalloc_rust) |
dependencies | patch | `0.1.47` -> `0.1.48` |
---
> [!WARNING]
> Some dependencies could not be looked up. Check the Dependency
Dashboard for more information.
---
### Release Notes
<details>
<summary>purpleprotocol/mimalloc_rust (mimalloc)</summary>
###
[`v0.1.48`](https://redirect.github.com/purpleprotocol/mimalloc_rust/releases/tag/v0.1.48):
Version 0.1.48
[Compare
Source](https://redirect.github.com/purpleprotocol/mimalloc_rust/compare/v0.1.47...v0.1.48)
##### Changes
- Mimalloc `v3` feature flag. (credits
[@​gschulze](https://redirect.github.com/gschulze)).
</details>
---
### Configuration
📅 **Schedule**: Branch creation - "before 4am on Monday" (UTC),
Automerge - At any time (no schedule defined).
🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.
♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box
---
This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/astral-sh/uv).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MS45MS4xIiwidXBkYXRlZEluVmVyIjoiNDEuOTEuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiaW50ZXJuYWwiXX0=-->
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
## Summary
We support `--no-editable` on the CLI, but now that workspace members
and path dependencies can be marked as `editable = false`, I think it
makes sense for `--editable` to override that.
## Summary
This ended up being a bit more complex, similar to `package = false`,
because we need to understand the editable status _globally_ across the
workspace based on the packages that depend on it.
Closes https://github.com/astral-sh/uv/issues/15686.
## Summary
This refreshes the venv activation scripts from upstream `virtualenv`
project.
This was largely triggered by a problem in the activate.nu script (for
nushell):
- #14888
- #14914
- #14917
I was careful to respect the git history going back to astral-sh/uv#3376
(the last time this was done).
Actually I looked at the complete history from back when this
`uv-virtualenv` crate was named after a Pokémon (⁉️), but I found
nothing (about activation scripts) from back then that hasn't been
overwritten since.
### Some post-processing was involved
- Retained license info at top of scripts
- Retained template vars (eg `{{ BIN_PATH }}`) to assure current support
toward relocatable venv
- Retained deviation from upstream in astral-sh/uv#5640. This seems to
be the only deviation that isn't in sync with upstream.
### Notable changes from upstream
- (omitted due to undesirable complexity) pypa/virtualenv#2928 and its
follow-up pypa/virtualenv#2940
- pypa/virtualenv#2910 (what prompted astral-sh/uv#14917 from
astral-sh/uv#14888)
## Test Plan
There was a request in #14917 to add unit tests to detect breakage or
errors.
I have added a CI job that runs the nushell activation script.
But I think it is better to have the CI test all/most supported shells.
See also #15294
I have tested this locally using
- [x] nushell (v0.106.1)
- [x] cmd.exe (Microsoft Windows [Version 10.0.26100.4946])
- [x] bash in WSL (GNU bash, version 5.1.16(1)-release
(x86_64-pc-linux-gnu))
- [x] pwsh (PSVersion 5.1.26100.4768)
uv currently panics with a stack overflow when requirements or
constraints are recursively included. Instead, we ignore files we have
already seen. The one complexity here is that we have to track whether
we're in a requirements inclusion or in a constraints inclusion, to
allow including a file separately for requirements and for constraints,
and to handle `-r` inside or `-c` (which we treat as constraints too).
Fixes#15650
## Summary
If the package that has the `match-runtime` dependency itself isn't
being installed, we should avoid erroring if the package it _depends on_
isn't in the resolution.
Closes https://github.com/astral-sh/uv/issues/15661.
## Summary
This implements the iOS part of
https://github.com/astral-sh/uv/issues/8029
FYI: @freakboy3742
<!-- What's the purpose of the change? What does it do, and why? -->
## Test Plan
Create a venv with uv and run `cargo run pip install --python-platform
arm64-apple-ios pillow`. Then the iOS binary of pillow should be
installed inside the venv.
## Summary
This implements the Android part of
https://github.com/astral-sh/uv/issues/8029
FYI: @freakboy3742 @mhsmith
<!-- What's the purpose of the change? What does it do, and why? -->
## Test Plan
Create a venv with uv and run `cargo run pip install --python-platform
aarch64-linux-android pybase64`. Then the Android binary of pybase64
should be installed inside the venv.
## Summary
This PR allows pyx to send down hashes for zstandard-compressed
tarballs. If the hash is present, then the file is assumed to be present
at `${wheel_url}.tar.zst`, similar in design to PEP 658
`${wheel_metadata}.metadata` files. The intent here is that the index
must include the wheel (to support all clients and support
random-access), but can optionally include a zstandard-compressed
version alongside it.
## Summary
`uv publish --dry-run` will perform the `--check-url` validation, and
hit the `/validate` endpoint if the registry is known to support
fast-path validation (like pyx). The `/validate` endpoint lets us
validate an upload without uploading the file _contents_, which lets you
skip the expensive step for common mistakes.
In the future, my hope is that the `/validate` step will deprecated in
favor of Upload API 2.0.
## Summary
This PR adds support for the `application/vnd.pyx.simple.v1` content
type, similar to `application/vnd.pypi.simple.v1` with the exception
that it can also include core metadata for package-versions directly.
## Summary
This PR adds support for pyx to `uv auth login`, `uv auth logout`, and
`uv auth token`. These are generic uv commands that can be used to store
credentials for arbitrary indexes and other URLs, but we include a
fast-path for pyx that initiates the appropriate login or logout flow.
We're not sure what the best way to expose the native store to users is
yet and it's a bit weird that you can use this in the `uv auth` commands
but can't use any of the other keyring provider options. The simplest
path forward is to just not expose it to users as a keyring provider,
and instead frame it as a preview alternative to the plaintext uv
credentials store. We can revisit the best way to expose configuration
before stabilization.
Note this pull request retains the _internal_ keyring provider
implementation — we can refactor it out later but I wanted to avoid a
bunch of churn here.
Adds locking of the credentials store for concurrency safety. It's
important to hold the lock from read -> write so credentials are not
dropped during concurrent writes.
I opted not to attach the lock to the store itself. Instead, I return
the lock on read and require it on write to encourage safe use. Maybe
attaching the source path to the store struct and adding a `lock(&self)`
method would make sense? but then you can forget to take the lock at the
right time. The main problem with the interface here is to write a _new_
store you have to take the lock yourself, and you could make a mistake
by taking a lock for the wrong path or something. The fix for that would
be to introduce a new `CredentialStoreHandle` type or something, but
that seems overzealous rn. We also don't eagerly drop the lock on token
read, although we could.
Adds a default plain text storage mechanism to `uv auth`.
While we'd prefer to use the system store, the "native" keyring support
is experimental still and I don't want to ship an unusable interface.
@geofft also suggested that the story for secure credential storage is
much weaker on Linux than macOS and Windows and felt this approach would
be needed regardless.
We'll switch over to using the native keyring by default in the future.
On Linux, we can now fallback to a plaintext store the secret store is
not configured, which is a nice property.
Right now, we store credentials in a TOML file in the uv state
directory. I expect to also read from the uv config directory in the
future, but we don't need it immediately.
Picks up the work from
- #14559
- https://github.com/astral-sh/uv/pull/14896
There are some high-level changes from those pull requests
1. We do not stash seen credentials in the keyring automatically
2. We use `auth login` and `auth logout` (for future consistency)
3. We add a `token` command for showing the credential that will be used
As well as many smaller changes to API, messaging, testing, etc.
---------
Co-authored-by: John Mumm <jtfmumm@gmail.com>
## Summary
We (and I'm sure many others) are currently doing a lot of RISC-V work
in QEMU. It is possible to significantly improve the speed of
Python-related builds by taking care of the environment setup using an
AMD64 `uv` binary (bypassing binfmt/qemu-system emulation).
Some approx numbers from local testing in riscv64 Ubuntu in QEMU:
| Resolver arch | Command | Time |
| --- | --- | --- |
| riscv64 | `pip install --upgrade --break-system-packages
--index-url=https://gitlab.com/api/v4/projects/riseproject%2Fpython%2Fwheel_builder/packages/pypi/simple
openai-harmony` | 15s |
| riscv64 | `uv pip install --upgrade --system --break-system-packages
--index-url=https://gitlab.com/api/v4/projects/riseproject%2Fpython%2Fwheel_builder/packages/pypi/simple
openai-harmony` | 5s |
| amd64 | `uv pip install --python-platform=riscv64-unknown-linux
--upgrade --system --break-system-packages
--index-url=https://gitlab.com/api/v4/projects/riseproject%2Fpython%2Fwheel_builder/packages/pypi/simple
openai-harmony` | 4s |
The numbers from some larger internal packages with deeper dependency
trees are much more pronounced - 3m6 vs 43s vs 8s, in one example.
Manylinux 2.39 is specified, as it's the first (only?) RISC-V manylinux
## Test Plan
Locally, in QEMU.
`$ docker run --platform linux/riscv64 -it ubuntu:latest`, get amd64
libc into LD_LIBRARY_PATH, tests as above
## Summary
Override `sys.base_prefix` when performing `python_module` tests, in
order to prevent `find_uv_bin()` from finding `uv` installed alongside
system Python, and therefore fix test failures on Gentoo.
Fixes#15368
## Test Plan
```
cargo test --profile=fast-build --features git --features pypi --features python --no-default-features --test it python_module
```
Signed-off-by: Michał Górny <mgorny@gentoo.org>
When migrating from the `reqwest_retry` crate, we want to ensure that
the status codes we retry stay the same. This also helps us to
intentionally migrate to a different list later, by enumerating the list
of status codes that are retried.
In https://github.com/astral-sh/uv/issues/11636, we're getting reports
for installation flakes that report an invalid package format for what
appears to be a network problem. Since we're cutting the error reporting
to the first error message in the chain, we're not reporting the actual
network error underneath it.
This PR displays the whole error chain for invalid package format
errors, so we can debug and eventually catch-and-retry
https://github.com/astral-sh/uv/issues/11636.
## Summary
This was fixed in https://github.com/astral-sh/uv/pull/15161, then
reverted as it regressed the error handling. I've re-applied the change
here, but moved the error handling to the runtime, rather than
parse-time. I think this is slightly worse in that we no longer include
the originating source code snippet, but it at least gives us the
expected behavior :(
Closes https://github.com/astral-sh/uv/issues/15124.
When there is an error during the streaming download and unpack for
Python interpreter and bin installs, we would previously fail, causing a
lot of CI flakes on GitHub Actions.
The problem was that the error is not one of the extended IO errors we
were previously handling, but a regular reqwest error, nested below
layers of errors of other crates processing the stream, including some
IO errors. We now handle nested reqwest errors, too.
This surfaced another problem: Our manual retry loop couldn't inform the
retry middleware that it already performed the limit of retries, and
that the middleware should not retry anymore. While too many retries are
more a problem for debugging than for the user, this causes confusing
error output. To work around this, we disable the retries in the client
and handle all retry errors in our loop.
Fixes https://github.com/astral-sh/uv/issues/14171
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
Alternative to #15105
Instead of building a `BaseClientBuilder` from `NetworkSettings` each
time we need a client, we instead build a single `BaseClientBuilder` and
pass it around. The `RegistryClientBuilder` then uses
`BaseClientBuilder` exclusively for configuration. This removes a chunk
of copy-and-paste code, and also moves the fallible `retries_from_env`
into a single place
Borrow vs. clone is mostly ad-hoc, we can change it in either direction
if it matters.
Closes#15105
https://github.com/astral-sh/uv/issues/11836#issuecomment-3022735011 was
caused by a missing `cache_index_credentials()` call. This call was
always preceding a registry client builder. We can improve this
situation by caching index credentials in the registry client builder.
<!--
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
Adds the enhancement proposed in #15470. Each package in the dependency
tree now shows its compressed wheel file size, reading the wheel sizes
directly from the lockfile (uv.lock). Doesn't break existing tree
formatting or options. If no wheel size is available, nothing is added.
Now, developers can identify large packages in their dependency tree.
The tree still shows extras exactly as before, and then appends a size
for the package.
## Test Plan
Manually tested :
```
harsh@fcr-node:~/uv/test-uv-tree-sizes$ ../target/debug/uv tree
Using CPython 3.13.7
warning: No `requires-python` value found in the workspace. Defaulting to `>=3.13`.
Resolved 4 packages in 6ms
pure-python v0.1.0
├── click v8.2.1
└── six v1.17.0
harsh@fcr-node:~/uv/test-uv-tree-sizes$ ../target/debug/uv tree --show-sizes
Using CPython 3.13.7
warning: No `requires-python` value found in the workspace. Defaulting to `>=3.13`.
Resolved 4 packages in 6ms
pure-python v0.1.0
├── click v8.2.1 (99.8KiB)
└── six v1.17.0 (10.8KiB)
```
## 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!