Commit Graph

5565 Commits

Author SHA1 Message Date
Ahmed Ilyas 88a7b2d864
Fix clippy warnings in downloads.rs (#15255)
## Summary

Fixes clippy warnings on main.

## Test Plan

`cargo clippy`
2025-08-13 12:21:03 -05:00
Hood Chatham c8d0bfba5c
Add support for installing pyodide Pythons (#14518)
- [x] Add tests

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2025-08-13 11:03:25 -05:00
Zanie Blue b38edb9b7d
Allow Python requests with missing segments (#14399)
This allows `PythonDownloadRequest` which is used for parsing general
install key requests to have missing segments, which unblocks requests
like `windows-aarch64` or `cpython-linux` (whereas before those would
require `any-any-windows-aarch64` and `cpython-any-linux` respectively).
We still require strict ordering of segments.

Previously, we only allowed missing segments at the end of the key.

This uses a state machine for parsing, which is quite a bit more
complicated.

I'm a little hesitant about the possibility that this regresses error
messages and the complexity of the implementation, but `uv run -p
aarch64` seems valuable following #13724. The alternative to this would
probably be to make these explicit in various places? e.g., expose
`--python-arch`, `--python-libc`, and `--python-os`? Or make
`--python-platform` (which already exists) accept a subset of the keys?

There is a possibility of regressions here, e.g., if something matches
this parser it will not fallback to the `PythonRequest::ExecutableName`
case and we've made this parser more permissive, but I think that should
be quite rare?
2025-08-13 11:03:09 -05:00
Zanie Blue 78c8c711fa
Refactor os, arch, and libc information into a shared `Platform` type (#15027)
Addresses this outstanding item from a previous review
https://github.com/astral-sh/uv/pull/13724#discussion_r2114867288

I'm interested in this now for consolidating some logic in #12731
2025-08-13 09:02:55 -05:00
samypr100 323aa8f332
chore(🧹): cleanup env var usage (#15247)
## Summary

Split the cleanup fixes from https://github.com/astral-sh/uv/pull/15196
into a separate PR for easier review.

This cleans up some minor env var usage / references throughout tests
and runtime code.

## Test Plan

Existing Tests. No functional changes.
2025-08-12 21:11:28 -05:00
Zanie Blue 68c0bf8a2c
Bump version to 0.8.9 (#15229) 2025-08-11 21:07:59 -05:00
Charlie Marsh dacc86ff03
Revert "Fix settings rendering for `extra-build-dependencies`" (#15228)
Reverts astral-sh/uv#15161
2025-08-11 19:37:12 -05:00
Charlie Marsh 9ba1ef1155
Fix settings rendering for `extra-build-dependencies` (#15161)
## Summary

It would be nice if this rendered as
`[tool.uv.extra-build-dependencies]` and `[extra-build-dependencies]`
(in `uv.toml`), but this is at least correct.

Closes https://github.com/astral-sh/uv/issues/15124.
2025-08-11 22:24:31 +01:00
Ubaid Shaikh 43341ad0a6
Filter date in GitHub release URLs for `python_install_no_cache` test (#15204)
## Summary

fixes https://github.com/astral-sh/uv/issues/15172

This change adds a regex filter to normalize dates in GitHub release
URLs within the `python_install_no_cache` test snapshot.

**Problem:**
The test was hardcoding the date `20250808` in the expected error
message URL:

```console
https://github.com/astral-sh/python-build-standalone/releases/download/20250808/cpython-3.12.[PATCH]-[DATE]-[PLATFORM].tar.gz
```

This creates a maintenance burden as the snapshot would need to be
updated whenever the underlying Python release date changes.

**Solution:**
Added a regex filter `r"releases/download/\d{8}/"` →
`"releases/download/[DATE]/"` to replace any 8-digit date in the GitHub
release URL path with a generic `[DATE]` placeholder.

**Result:**
The test is now resilient to new Python releases and won't require
snapshot updates when the underlying release date changes. The error
message now consistently shows:

```console
https://github.com/astral-sh/python-build-standalone/releases/download/[DATE]/cpython-3.12.[PATCH]-[DATE]-[PLATFORM].tar.gz
```

## Test Plan

`python_install` tests seem to pass  

```console
$ cargo test --package uv --test it -- python_install
   Compiling uv-cli v0.0.1 (/home/ubaid/projects/uv/crates/uv-cli)
   Compiling uv v0.8.8 (/home/ubaid/projects/uv/crates/uv)
    Finished `test` profile [unoptimized + debuginfo] target(s) in 19.04s
     Running tests/it/main.rs (target/debug/deps/it-14d47eb0324a8a0a)

running 30 tests
test python_install::python_install_unknown ... ok
test network::python_install_io_error ... ok
test network::python_install_http_500 ... ok
test python_install::python_install_invalid_request ... ok
test python_install::python_install_broken_link ... ok
test python_install::python_install_preview_no_bin ... ok
test python_install::regression_cpython ... ok
test python_install::uninstall_last_patch ... ok
test python_install::install_no_transparent_upgrade_with_venv_patch_specification ... ok
test python_install::install_lower_patch_automatically ... ok
test python_install::uninstall_highest_patch ... ok
test python_install::install_transparent_patch_upgrade_venv_module ... ok
test python_install::python_install_default_from_env ... ok
test python_install::python_install ... ok
test python_install::python_reinstall_patch ... ok
test python_install::python_install_force ... ok
test python_install::install_transparent_patch_upgrade_uv_venv ... ok
test python_install::install_multiple_patches ... ok
test python_install::python_install_314 ... ok
test python_install::python_install_default ... ok
test python_install::python_install_automatic ... ok
test python_install::python_install_freethreaded ... ok
test python_install::python_install_preview_upgrade ... ok
test python_install::python_install_no_cache ... ok
test python_install::python_install_default_preview ... ok
test python_install::python_install_preview ... ok
test python_install::python_install_minor ... ok
test python_install::python_reinstall ... ok
test python_install::python_install_cached ... ok
test python_install::python_install_multiple_patch ... ok

test result: ok. 30 passed; 0 failed; 0 ignored; 0 measured; 2207 filtered out; finished in 23.34s
```
2025-08-11 16:15:52 -05:00
Charlie Marsh 40b894bb1d
Include build settings in cache key for registry source distribution lookups (#15225)
## Summary

Like #15030, but for source distributions built from a registry.
2025-08-11 22:14:27 +01:00
John Mumm 76b4ae40c6
Never create bin links on `uv python upgrade` if they don't already exist (#15192)
Fixes #15178
2025-08-11 15:36:03 -05:00
John Mumm 23245c63e9
Add `--reinstall` flag to `uv python upgrade` (#15194)
As described in #15179, there are cases where it can be useful to
reinstall the latest patch on upgrade if it is already installed. Using
this flag, you don't need to know ahead of time if you have the latest
patch already.

Closes #15179.
2025-08-11 15:20:04 -05:00
github-actions[bot] ed499d7453
Sync latest Python releases (#15186)
Automated update for Python releases.

Co-authored-by: zanieb <2586601+zanieb@users.noreply.github.com>
2025-08-09 00:43:10 +00:00
Zanie Blue 6c9544ed5f
Add test coverage for the `find_uv_bin` error message (#15185)
All of these went away as we fixed the bugs! it seems nice to retain a
snapshot of the error
2025-08-09 00:28:40 +00:00
Zanie Blue 9a54754b0a
Bump version to 0.8.8 (#15184) 2025-08-08 19:03:07 -05:00
Dustin Ngo 0924490456
fix: Use 3.9 compatible zip (#15177)
<!--
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

Uses a <3.10-compatible version of `zip` since the `strict` argument was
[added in 3.10](https://docs.python.org/3.10/library/functions.html#zip)

## Test Plan

I executed the `_matching_parents` function in a local 3.9 environment

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2025-08-08 18:45:13 -05:00
Zanie Blue 6b5d309d28
Add `find_uv_bin` test cases by Python version (#15181)
Regression coverage for https://github.com/astral-sh/uv/issues/15176
2025-08-08 18:36:59 -05:00
Zanie Blue 8a22572338
Bump version to 0.8.7 (#15173) 2025-08-08 14:42:23 -05:00
github-actions[bot] d1beb7f640
Sync latest Python releases (#15171)
Automated update for Python releases.

This picks up dynamically-linked tkinter/libtcl/libtk, which fixes #6893
and a host of similar issues.

Co-authored-by: Geoffrey Thomas <geofft@ldpreload.com>
2025-08-08 19:03:25 +00:00
Zanie Blue bdb4b061db
Include all site packages directories in ephemeral environment overlays (#15121)
Related to https://github.com/astral-sh/uv/issues/15113

The case in the linked issue is that we perhaps should not be allowing
`uv run --with` with system interpreters at all. I think we can consider
that, but the issue highlighted that `uv run --with` for a system
interpreter is broken if the base interpreter has custom site packages.
This generalizes beyond system interpreters so we should probably fix
our overlays.
2025-08-08 13:49:21 -05:00
Charlie Marsh f6a9b55eb7
Add `UV_DEV` and `UV_NO_DEV` environment variables (#15010)
## Summary

Closes https://github.com/astral-sh/uv/issues/15009.

Co-authored-by: Zanie Blue <contact@zanie.dev>
2025-08-08 14:33:44 +00:00
Zanie Blue e18bfc6e9a
Do not update `uv.lock` when using `--isolated` (#15154)
A little spicy. We could consider this breaking, but I can't think of
what workflow it'd break and it matches the spirit of `--isolated`. This
was requested by @ssbarnea
2025-08-08 09:15:43 -05:00
samypr100 57df0146e2
Update Rust toolchain to 1.89 (#15157)
## Summary

Bumps Rust toolchain to 1.89, but not the MSRV.

Lifetime changes is related to a new lint rule explained in
https://blog.rust-lang.org/2025/08/07/Rust-1.89.0/#mismatched-lifetime-syntaxes-lint

## Test Plan

Existing Tests
2025-08-08 13:01:52 +00:00
Zanie Blue 8f71d239f8
Add support for `package`-level conflicts in workspaces (#14906)
Revives https://github.com/astral-sh/uv/pull/9130

Previously, we allowed scoping conflicting extras or groups to specific
packages, e.g. ,`{ package = "foo", extra = "bar" }` for a conflict in
`foo[bar]`. Now, we allow dropping the `extra` or `group` bit and using
`{ package = "foo" }` directly which declares a conflict with `foo`'s
production dependencies.

This means you can declare conflicts between workspace members, e.g.:

```
[tool.uv]
conflicts = [[{ package = "foo" }, { package = "bar" }]]
```

would not allow `foo` and `bar` to be installed at the same time.

Similarly, a conflict can be declared between a package and a group:

```
[tool.uv]
conflicts = [[{ package = "foo" }, { group = "lint" }]]
```

which would mean, e.g., that `--only-group lint` would be required for
the invocation.

As with our existing support for conflicting extras, there are
edge-cases here where the resolver will _not_ fail even if there are
conflicts that render a particular install target unusable. There's test
coverage for some of these. We'll still error at install-time when the
conflicting groups are selected. Due to the likelihood of bugs in this
feature, I've marked it as a preview feature.

I would not recommend reading the commits as there's some slop from not
wanting to rebase Andrew's branch.

---------

Co-authored-by: Andrew Gallant <andrew@astral.sh>
2025-08-08 07:44:58 -05:00
Zanie Blue a9302906ce
Search in the user scheme scripts directory last in `find_uv_bin` (#14191)
We should definitely not pick up user-level installations unless we
can't find uv anywhere else. Otherwise, e.g., we would find a uv
installed with `pipx install uv` before the one matching the uv module.
2025-08-08 11:46:32 +00:00
Charlie Marsh 9daadbfab0
Add R2 feature for malo tests (#15160)
Closes https://github.com/astral-sh/uv/issues/15158.
2025-08-08 06:26:18 -05:00
konsti 1843c90e74
Warn when two packages write to the same module (#13437)
We regularly get confusing bug reports where a package sometimes works
and sometimes doesn't and it's not clear to the user why. Ultimately, it
turns out that two packages contain the same module and there is a race
condition when installing the two packages. Usually, it's one of the
opencv-python distributions, but recently it's been z3, too. These error
are completely inscrutable to users.

* https://github.com/astral-sh/uv/issues/10708
* https://github.com/astral-sh/uv/issues/11806
* https://github.com/astral-sh/uv/issues/11659
* https://github.com/astral-sh/uv/issues/13435
* https://github.com/astral-sh/uv/issues/13550
* https://github.com/astral-sh/uv/issues/14030

We now warn for top-level modules (pattern: `<identifier>/__init__.py`)
that collide in a single installation, naming the offending wheels.
Checking for `__init__.py` excludes namespace packages.

Test script:

```
uv venv -q && cargo run -q --profile fast-build pip install --no-progress --link-mode clone opencv-python opencv-contrib-python --no-build --no-deps
uv venv -q && cargo run -q --profile fast-build pip install --no-progress --link-mode copy opencv-python opencv-contrib-python --no-build --no-deps
uv venv -q && cargo run -q --profile fast-build pip install --no-progress --link-mode hardlink opencv-python opencv-contrib-python --no-build --no-deps
uv venv -q && cargo run -q --profile fast-build pip install --no-progress --link-mode symlink opencv-python opencv-contrib-python --no-build --no-deps
```

We currently only catch conflicts in a single installation. Should we
prime the lock database with the site-packages contents, and would that
carry overhead?
2025-08-08 09:01:13 +00:00
Zanie Blue 8968d783de
Add support for `--prefix` and `--with` installations in `find_uv_bin` (#14184)
Follows #14182

Adds support for the case described at
https://github.com/astral-sh/uv/issues/10194#issuecomment-2993544346

This also happens to fix both `--with` requirement test cases, which
should close https://github.com/tox-dev/pre-commit-uv/issues/70
2025-08-07 16:48:07 -05:00
Zanie Blue 9425350478
Fix regression where `--require-hashes` applied to build dependencies in `uv pip install` (#15153)
Closes https://github.com/astral-sh/uv/issues/15146
2025-08-07 21:43:24 +00:00
Michael Šimáček e5eec05783
Ignore GraalPy devtag (#15013)
Allows [development builds of
GraalPy](https://github.com/graalvm/graal-languages-ea-builds) to work
with uv.

CC @timfel
2025-08-07 15:53:37 -05:00
Lars Grams d73edb019d
replace manual venv removal with remove_virtualenv (#15007)
<!--
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? -->
At some places the virtualenv directory was manually removed instead of
using `remove_virtualenv`.
I also adjusted the error type.
#14985 

## Test Plan

<!-- How was it tested? -->
2025-08-07 15:52:57 -05:00
Zanie Blue b1a036ccf5
Refactor `find_uv_bin` and add a better error message (#14182)
Follows https://github.com/astral-sh/uv/pull/14181

Two goals here

- Remove duplicated logic and make the search order clear
- Resolve user confusion around the searched directories; we previously
only displayed the last attempt, which we rarely expect to be relevant
2025-08-07 15:10:38 -05:00
Zanie Blue a7c4634243
Add a regression test for `--require-hashes` with unpinned build requirements (#15147)
Test case for https://github.com/astral-sh/uv/issues/15146
2025-08-07 20:04:18 +00:00
Zanie Blue ceb610c047
Update `find_uv_bin` to locate uv in the base prefix (#14181)
Closes https://github.com/astral-sh/uv/issues/10194
2025-08-07 13:40:57 -05:00
Charlie Marsh 329a6b446a
Bump version to v0.8.6 (#15137) 2025-08-07 16:17:14 +01:00
samypr100 abc68fc7c1
Consider pythonw when copying entrypoints in uv run (#15134)
## Summary

Follow up from
https://github.com/astral-sh/uv/pull/15068#discussion_r2258586926

It seems when copying entrypoints we're ignoring whether it was pythonw
vs not.

## Test Plan

Updated existing test.
2025-08-07 10:06:03 -05:00
Charlie Marsh 7f1eaf48c1
Harden ZIP streaming to reject repeated entries and other malformed ZIP files (#15136)
## Summary

uv will now reject ZIP files that meet any of the following conditions:

- Multiple local header entries exist for the same file with different
contents.
- A local header entry exists for a file that isn't included in the
end-of-central directory record.
- An entry exists in the end-of-central directory record that does not
have a corresponding local header.
- The ZIP file contains contents after the first end-of-central
directory record.
- The CRC32 doesn't match between the local file header and the
end-of-central directory record.
- The compressed size doesn't match between the local file header and
the end-of-central directory record.
- The uncompressed size doesn't match between the local file header and
the end-of-central directory record.
- The reported central directory offset (in the end-of-central-directory
header) does not match the actual offset.
- The reported ZIP64 end of central directory locator offset does not
match the actual offset.

We also validate the above for files with data descriptors, which we
previously ignored.

Wheels from the most recent releases of the top 15,000 packages on PyPI
have been confirmed to pass these checks, and PyPI will also reject ZIPs
under many of the same conditions (at upload time) in the future.

In rare cases, this validation can be disabled by setting
`UV_INSECURE_NO_ZIP_VALIDATION=1`. Any validations should be reported to
the uv issue tracker and to the upstream package maintainer.
2025-08-07 15:31:48 +01:00
github-actions[bot] 038bf56366
Sync latest Python releases (#15135)
Automated update for Python releases.

Co-authored-by: zanieb <2586601+zanieb@users.noreply.github.com>
2025-08-07 13:59:02 +00:00
konsti 84d57f2ee9
Ensure symlink warning is shown (#15126)
Fixes #15115, see also https://github.com/clap-rs/clap/discussions/6092

<img width="1079" height="1030" alt="image"
src="https://github.com/user-attachments/assets/05b003a6-9ca0-4f2b-8a74-078aa155ce6d"
/>
2025-08-07 15:56:59 +02:00
Zanie Blue 278295ef02
Add test cases for `find_uv_bin` (#15110)
Adds test cases to unblock

- https://github.com/astral-sh/uv/pull/14181
- https://github.com/astral-sh/uv/pull/14182
- https://github.com/astral-sh/uv/pull/14184
- https://github.com/astral-sh/uv/pull/14184
- https://github.com/tox-dev/pre-commit-uv/issues/70

We use a package with a symlink to the Python module to get a mock
installation of uv without building (or packaging) the uv binary. This
lets us test real patterns like `uv pip install --prefix` without
encoding logic about where things are placed during those installs.

---------

Co-authored-by: konstin <konstin@mailbox.org>
2025-08-07 07:14:01 -05:00
Zanie Blue aec90f0a3c
Fix warnings when running tests with a subset of features (#15120)
We were getting dead code warnings on Windows tests because these were
not properly feature gated.
2025-08-07 01:28:26 +00:00
Charlie Marsh 3c1844ca4a
Add support for per-project build-time environment variables (#15095)
## Summary

E.g., you can now do:

```toml
[tool.uv.extra-build-variables]
flash-attn = { FLASH_ATTENTION_SKIP_CUDA_BUILD = "TRUE" }
```
2025-08-06 18:01:55 -05:00
konsti 59558b13c1
Respect `UV_HTTP_RETRIES` in `uv publish` (#15106)
Previously, publish would always use the default retries, now it
respects `UV_HTTP_RETRIES`

Some awkward error handling to avoid pulling anyhow into uv-publish.
2025-08-06 17:59:17 +02:00
konsti 52771476f4
Support `UV_NO_EDITABLE` where `--no-editable` is supported (#15107)
Specifically, support `UV_NO_EDITABLE=1 uv export`. It's now also
supported in `uv add`, though it's default there anyway and the env var
exists only for completeness.

Fixes #15103
2025-08-06 13:06:49 +00:00
samypr100 d2330615c4
Update trampoline to ~1.87 nightly (#15052)
## Summary

1. Given the upcoming 1.89 update, this bumps uv-trampoline to "~1.87"
(closest nightly) from "~1.86" (closest nightly).
2. Adds additional CI check for arm builds now that runners are
available.

I wasn't sure the MSRV policy applies to uv-trampoline, so I didn't go
for higher than ~1.87 nightly.
This PR also fixes a build issue starting after 1.87 where fma and fmaf
symbols were missing.
Temporarily dded `#[allow(clippy::ptr_eq)]` to `close_handles` as this
lint should not trigger anymore in 1.88 and above.

## Test Plan

Existing tests and local build process. I did not commit the built
binaries for security purposes.

---------

Co-authored-by: konstin <konstin@mailbox.org>
2025-08-06 12:45:04 +00:00
konsti 91653f5fee
Avoid invalid simplification with conflict markers (#15041)
Previously, `simplify_conflict_markers` assumed that it can remove all
conflict set together, when we need to look at each conflict set
individually. Specifically, `(platform_machine == 'x86_64' and extra ==
'extra-5-foo-b') or extra == 'extra-5-foo-a'` can't be reduced
`platform_machine == 'x86_64'` only because it reduces to true when both
conflict extras are activated.

This case applied in https://github.com/astral-sh/uv/issues/14805, where
a jax 0.5.3 version was used for `platform_machine != 'aarch64' or
sys_platform != 'linux'` and the conflict extra `cu128`, but jax 0.7.0
for the conflict extra `cpu`.

Only removing the faulty inference regresses lockfiles to much more
verbose markers. To balance the much more conservative inference, I
added `unify_inference_sets` to simplify cases where all conflict
branches reduce to the same marker.

This still regresses some markers. For example `sys_platform == 'win32'`
regresses to `sys_platform == 'win32' or (extra == 'extra-3-pkg-x1' and
extra == 'extra-3-pkg-x2')` in `extra_inferences`, even through x1 and
x2 conflict and the second conjunction could be simplified away.

Fixes https://github.com/astral-sh/uv/issues/14805
2025-08-06 09:26:26 +00:00
Zanie Blue ce37286814
Bump version to 0.8.5 (#15093) 2025-08-05 20:21:00 +00:00
adamnemecek 3d3856ffd5
additional use of Self, remove * and & where not needed (#15091)
continuation of #15074.
2025-08-05 15:19:56 -05:00
Charlie Marsh bda9ea957a
Support `match-runtime = true` in the `uv pip` CLI (#15087)
## Summary

Pretty straightforward, a ~one line change plus recreating the
`BuildDispatch` (which I tried to avoid, but ran into lifetime issues).
2025-08-05 20:03:10 +00:00
Zanie Blue 1fb0fa045c
Add Python versions to markers implied from wheels (#14913)
Looking into  https://github.com/astral-sh/uv/issues/14836

This does resolve the issue, if the user adds `python_version ==
'3.8.*'` to the `required-environments`.
2025-08-05 14:52:32 -05:00
Zanie Blue b2e7b2b279
Improve HTTP response caching log messages (#15067)
"Cached request ... is not storable" doesn't make sense from a user
perspective, it's leaking our internal `CachedClient` abstraction. I
think it makes more sense to talk about this as "Response from ... is
not storable"
2025-08-05 14:34:12 -05:00
adamnemecek 3f83390e34
Make the use of `Self` consistent. (#15074)
## Summary

Make the use of `Self` consistent. Mostly done by running `cargo clippy
--fix -- -A clippy::all -W clippy::use_self`.

## Test Plan

<!-- How was it tested? -->
No need.
2025-08-05 20:17:12 +01:00
Charlie Marsh 57f900ad0d
Take a build constraints reference in `BuildDispatch` (#15090)
## Summary

This is just more consistent with the other fields.
2025-08-05 18:28:02 +00:00
Charlie Marsh 089b6d5538
Use "option" instead of "setting" in `pylock` warning (#15089)
## Summary

We use "option" everywhere else (though I don't have a strong opinion on
which is "better").
2025-08-05 18:17:30 +00:00
Charlie Marsh 327af017ae
Remove duplicate `extra-build-dependencies` warnings for `uv pip` (#15088)
## Summary

These are repeated for all the `uv pip` commands.
2025-08-05 19:14:58 +01:00
Charlie Marsh 8ef3b2eb8e
Enable extra build dependencies to 'match runtime' versions (#15036)
## Summary

This is an alternative to https://github.com/astral-sh/uv/pull/14944
that functions a little differently. Rather than adding separate
strategies, you can instead say:

```toml
[tool.uv.extra-build-dependencies]
child = [{ requirement = "anyio", match-runtime = true }]
```

Which will then enforce that `anyio` uses the same version as in the
lockfile.
2025-08-05 19:00:44 +01:00
Charlie Marsh b2c382f7c1
Revert h2 upgrade (#15079)
## Summary

While we figure out what's going on in
https://github.com/hyperium/h2/issues/856.

Closes https://github.com/astral-sh/uv/issues/15056.
2025-08-05 06:55:58 -05:00
Zanie Blue 8db61abb50
Prefer system Python installations over managed ones when `--system` is used (#15061)
This fixes a regression from 0.8.0 from
https://github.com/astral-sh/uv/pull/7934 and follows
https://github.com/astral-sh/uv/pull/15059

The regression is from [this
change](https://github.com/astral-sh/uv/pull/7934/files#diff-c7a660ac39628d5e12f388b0cacc7360affa3d7bb21191184d7ee78489675e83),
which was made because we'd otherwise (with the other changes in that
pull request) _filter out_ managed Python interpreters found in virtual
environments.

When `--system` is used we'll convert the default Python preference of
`managed` to `system` which avoids things like `uv pip install --system`
targeting a managed Python installation.

The basic test is

```
uv python install
uv pip install --system anyio
```

Prior to this change, we'd read a managed interpreter from our managed
installation directory and target that. After this change, without
#15059, we'd read a managed interpreter from the PATH and target that.
Both of those experiences are bad, because the managed interpreters are
marked as externally managed. After this change, with #15059, we
properly target the system interpreter.

Since we use `system` instead of `only-system`, if there is not a system
interpreter we'll still retain our existing behavior and use a managed
interpreter. This should limit breakage from the change. Given the
source of the regression, we could probably use `only-system` here. I
don't feel strongly. I think the main benefit of doing so would be that
we'd omit the check for managed installations in error messages when an
interpreter cannot be found?

We can't really add test coverage here because the test suite always has
externally managed interpreters :)
2025-08-04 19:53:59 -05:00
Charlie Marsh c77cb2023f
Show wheel tag hints in install plan (#15066)
## Summary

If we fail to install a wheel in `uv pip install` that's provided via
direct URL, we should explain why, just like in the lockfile.
2025-08-04 23:43:33 +00:00
Charlie Marsh 3b15da3c5d
Enable `uv run` with a GitHub Gist (#15058)
## Summary

You can now run `uv run
https://gist.github.com/charliermarsh/ea9eab7f56b1b3d41e51960001cae31d`
to execute a single-file Gist without having to go in and copy the raw
URL.
2025-08-05 00:38:20 +01:00
Charlie Marsh a28c3fb7d9
Preserve lowered extra build dependencies (#15038)
## Summary

I should've noticed this during review -- my bad -- but it looks like
after lowering, we're converting back to `uv_pep508::Requirement`. This
is mostly okay, but it's lossy for some lowerings. For example, we lose
index pinning. With this PR, we now preserve the lowered types
(`Requirement`).

Closes https://github.com/astral-sh/uv/issues/15037.
2025-08-04 22:42:11 +01:00
Zanie Blue 64e91a7e87
Fix handling of `python-preference = system` when managed interpreters are on the PATH (#15059)
This is the first part of fixing a 0.8.0 regression from
https://github.com/astral-sh/uv/pull/7934

There, we added handling for skipping managed interpreters on the PATH
when `only-system` is used, but did not update the logic to prefer
system interpreters over managed ones when `system` is used. Here, we
fix that by skipping managed interpreters when `system` is used unless
_only_ managed interpreters are available. While this logic is applied
during in a general discovery method, it's only relevant for the PATH
(and the Windows registry) because we already change the _order_ that we
inspect installations in when `system` is used, so the managed
installation directory is inspected last.

This behavior did not regress in 0.8, it's always been this way,
however, I need this change in order to fix a different bug.
2025-08-04 16:02:42 +00:00
Zanie Blue 8186aa963f
Remove test case that does not include global exclude newer (#15062)
Of course, this would flake over time.

Follows https://github.com/astral-sh/uv/pull/15054
2025-08-04 15:03:10 +00:00
konsti 06b84c6b60
Fix compile_exclude_newer_package test (#15054) 2025-08-04 09:21:09 +00:00
konsti 2ad924d4cf
Use consistent workspace inheritance (#15031)
Following a CI failure in https://github.com/astral-sh/uv/pull/15028,
ensure that all workspace crates are inheriting the MSRV and other
workspace configuration from the workspace root.
2025-08-02 22:03:51 +02:00
Charlie Marsh a981e92d31
Remove some arguments from `install` (#15033)
## Summary

We can read these from `BuildDispatch`.
2025-08-02 19:38:39 +00:00
Charlie Marsh 3a7aeff86f
Respect extra build requires when reading from wheel cache (#15030)
## Summary

We weren't including these in the cache key when constructing the
install plan. We likely still read them from the cache later, but we may
have reported the wrong number of prepares, etc.
2025-08-02 19:26:02 +00:00
konsti 368b7b1e12
Fix some nightly lints (#15028)
Apply fixes for some `cargo check` and `cargo clippy` lints that are on
in nightly Rust.

The following command now passes, the blanket allows had to many
false-positives:

```
cargo +nightly clippy -- -A clippy::doc_markdown -A mismatched_lifetime_syntaxes -A clippy::explicit_deref_methods
```

`cargo +nightly check -- -A mismatched_lifetime_syntaxes` now passes
without warnings.
2025-08-02 18:59:23 +00:00
Charlie Marsh 025d209735
Move cache sharding below `prepare_metadata_for_build_wheel` (#15029)
## Summary

No change in behavior. This logic just isn't needed until the next
block, and as-written, it's hard to tell.
2025-08-02 14:08:49 -04:00
Wang Bing-hua 3dc921d89c
Gracefully handle entrypoint permission errors (#15026)
Gracefully handle entrypoint permission errors

`uv run --with` could fail with a "permission denied" error when it
tried to copy an entrypoint with restrictive permissions.

For instance:

```sh
$ stat -c '%A' /usr/bin/groupmems
-rwxr-s---

$ uv python find
/usr/bin/python

$ uv run --with dummy_test
error: failed to open file `/usr/bin/groupmems`: Permission denied (os error 13)
```

The entrypoint copying logic now catches these permission errors and
skips the file, making `uv` more resilient on systems with binaries that
have restrictive permissions.
2025-08-02 07:03:37 -05:00
Charlie Marsh 785595bd35
Remove retry wrapper when matching on error kind (#14996)
## Summary

We often match on `ErrorKind` to figure out how to handle an error
(e.g., to treat a 404 as "Not found" rather than aborting the program).
Unfortunately, if we retry, we wrap the error in a new kind that
includes the retry count. This PR adds an unwrapping mechanism to ensure
that callers always look at the underlying error.

Closes https://github.com/astral-sh/uv/issues/14941.

Closes https://github.com/astral-sh/uv/issues/14989.
2025-07-31 17:00:01 -04:00
konsti 56677c540a
Log the debug error trace (#14458)
For #14425. We can see the error without `error(transparent)` applied by
looking at the debug representation.
2025-07-31 19:13:09 +02:00
Zanie Blue 1bca8bd044
Add `extra-build-dependencies` test cases for `setuptools` (#14998) 2025-07-31 11:17:53 -05:00
Zanie Blue d867f3e595
Skip`cargo dev generate-all` test case in CI (#14972)
This means that CI tests fail in a way that is redundant with the
dedicated CI job which can obscure signal on whether actual tests are
failing

e.g.,
https://github.com/astral-sh/uv/actions/runs/16623645930/job/47034116533
2025-07-31 15:49:42 +00:00
Charlie Marsh fa24d9a5e2
Include wheel hashes from local Simple indexes (#14993)
## Summary

This just looks like an oversight. We weren't including hashes from
local Simple API indexes if a package had both a wheel and a source
distribution.

Closes https://github.com/astral-sh/uv/issues/14883
2025-07-31 14:20:49 +00:00
Chisato 538ebe6fcf
Fix symlink preservation in virtual environment creation (#14933)
## Summary

  Fixes inconsistent symlink handling in `uv venv` command (#14670).

## Problem


00efde06b6/crates/uv-virtualenv/src/virtualenv.rs (L81)

The original code used `Path::metadata()` which automatically follows
symlinks, causing the system to treat symlinked virtual environment
paths as regular directories. When a user runs uv venv on an existing
symlinked virtual environment `(.venv -> foo)`, the code incorrectly
treats the symlink as a regular directory because `location.metadata()`
automatically follows the symlink and returns metadata for the target
directory `foo/`. This causes the removal logic to delete the symlink
itself and permanently breaking the symlink relationship and replacing
it with a standard directory structure.
 
## Solution

- Use canonicalize() to resolve symlinks only when removing and
recreating virtual
  environments
- This ensures operations target the actual directory while preserving
the symlink
  structure
- Minimal change that fixes the core issue without complex path
management

## Test Plan

```bash
➜  test-env alias uv-dev='/Users/wingmunfung/workspace/uv/target/debug/uv'
➜  test-env ln -s dummy foo
➜  test-env ln -s foo .venv
➜  test-env ls -lah        
total 0
drwxr-xr-x   4 wingmunfung  staff   128B Jul 30 10:39 .
drwxr-xr-x  48 wingmunfung  staff   1.5K Jul 29 17:08 ..
lrwxr-xr-x   1 wingmunfung  staff     3B Jul 30 10:39 .venv -> foo
lrwxr-xr-x   1 wingmunfung  staff     5B Jul 30 10:39 foo -> dummy
➜  test-env uv-dev venv
Using CPython 3.13.2
Creating virtual environment at: .venv
error: Failed to create virtual environment
  Caused by: failed to create directory `.venv`: File exists (os error 17)
➜  test-env mkdir dummy
➜  test-env uv-dev venv
Using CPython 3.13.2
Creating virtual environment at: .venv
Activate with: source .venv/bin/activate
➜  test-env ls -lah
total 0
drwxr-xr-x   5 wingmunfung  staff   160B Jul 30 10:39 .
drwxr-xr-x  48 wingmunfung  staff   1.5K Jul 29 17:08 ..
lrwxr-xr-x   1 wingmunfung  staff     3B Jul 30 10:39 .venv -> foo
drwxr-xr-x   7 wingmunfung  staff   224B Jul 30 10:39 dummy
lrwxr-xr-x   1 wingmunfung  staff     5B Jul 30 10:39 foo -> dummy
➜  test-env uv-dev venv
Using CPython 3.13.2
Creating virtual environment at: .venv
✔ A virtual environment already exists at `.venv`. Do you want to replace it? · yes
Activate with: source .venv/bin/activate
➜  test-env ls -lah
total 0
drwxr-xr-x   5 wingmunfung  staff   160B Jul 30 10:39 .
drwxr-xr-x  48 wingmunfung  staff   1.5K Jul 29 17:08 ..
lrwxr-xr-x   1 wingmunfung  staff     3B Jul 30 10:39 .venv -> foo
drwxr-xr-x@  7 wingmunfung  staff   224B Jul 30 10:39 dummy
lrwxr-xr-x   1 wingmunfung  staff     5B Jul 30 10:39 foo -> dummy

### the symlink still exists
```

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2025-07-31 11:59:23 +00:00
Charlie Marsh 3564e882d7
Ensure consistent indentation when adding dependencies (#14991)
## Summary

The basic problem here is that when we had multiple items in an inline
array, and that array expanded to multiple lines, we accidentally
changed the indentation part-way through due to how prefixes work in the
TOML.

Here's Claude's explanation of the root cause, which I find pretty
decent:

```
  Here's what happened step by step:

  1. First item ("iniconfig"): Has empty prefix "" → indentation_prefix stays None → uses default 4 spaces
  2. Second item ("ruff"): Has empty prefix "" → indentation_prefix stays None → uses default 4 spaces
  3. Third item ("typing-extensions"): Has prefix " " (single space from inline format) → indentation_prefix becomes
  Some(" ") → uses only 1 space!

  This produced:
  [dependency-groups]
  dev = [
      "iniconfig>=2.0.0",
      "ruff",
   "typing-extensions",  # ← Only 1 space instead of 4!
  ]

  Why the Third Item Had a Different Prefix

  In inline arrays like ["ruff", "typing-extensions"], the items are separated by commas and spaces. When parsed by
  the TOML library:
  - "ruff" has no prefix (it comes right after [)
  - "typing-extensions" has a single space prefix (the space after the comma)

  The Fix

  Moving the indentation calculation outside the loop ensures it's calculated only once:

  // Calculate indentation ONCE before the loop
  if let Some(first_item) = deps.iter().next() {
      let decor_prefix = /* get prefix from first item */
      indentation_prefix = (!decor_prefix.is_empty()).then_some(decor_prefix.to_string());
  }

  // Now use the same indentation for ALL items
  for item in deps.iter_mut() {
      // Apply consistent indentation to every item
  }

  This ensures all items get the same indentation (4 spaces by default when converting from inline arrays), producing
   the correct output:

  [dependency-groups]
  dev = [
      "iniconfig>=2.0.0",
      "ruff",
      "typing-extensions",  # ← Correct 4-space indentation
  ]

  The bug only affected arrays being converted from inline to multiline format, where different items might have
  different residual formatting from their inline representation.
```

Closes #14961.

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2025-07-31 11:50:05 +00:00
Tim de Jager fc0f637406
Make the `BuildDispatch` interpreter method async (#14956)
This is a bit of a weird request, but in [pixi](https://pixi.sh) we are
making use of this function to lazily instantiate a conda environment.
Well, in actuality we are using a shim to the `BuildDispatch` to
actually to only create a conda prefix, if some package needs to be
built during the resolution phase. Otherwise we can resolve everything
without an enviroment containing a python intepreter.

We are using a method now - that uses the runtime to run async code
inside this function, as `interpreter` is the first method called on a
`BuildContext` when running a source build - using
`tokio::Handle::block_on`.
However was causing a deadlock in very specific situations, me and
@baszalmstra + @wolfv have investigated this thoroughly, but have not
been able to find the root cause. It would hang in a part of the uv code
that hits the index, but that is **after** all of our initialization
*and the blocking call* was completed.
Changing this to be fully async fixes the problem, this requires this
method to be async though.

We get that this is not necessarily required, and we might find a
workaround, but I wanted to try it this way first.

Thanks!
2025-07-31 06:42:27 -05:00
Aaron Ang 3df972f18a
Support installing additional executables in `uv tool install` (#14014)
Close #6314

## Summary

Continuing from #7592. Created a new PR to rebase the old branch with
`main`, cleaned up test errors, and improved readability.

## Test Plan

Same test cases as in #7592.

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2025-07-30 14:50:24 -05:00
Zanie Blue e176e17144
Bump version to 0.8.4 (#14980) 2025-07-30 16:24:20 +00:00
Zanie Blue 630394476e
Copy entrypoints that have a shebang that differs in `python` vs `python3` (#14970)
In https://github.com/astral-sh/uv/issues/14919 it was reported that
uv's behavior differed after the first invocation. I noticed we weren't
copying entrypoints after the first invocation. It turns out the
shebangs were written with `.../python` but on a subsequent invocation
the `sys.executable` was `.../python3` so we didn't detect these as
matching.

This is a pretty naive fix, but it seems much easier than ensuring the
entry point path exactly matches the subsequent `sys.executable` we
find.

I guess we should fix this in reverse too? but I think we might always
prefer `python3` when loading interpreters from environments.

See #14790 for more background.
2025-07-30 11:00:16 -05:00
Zanie Blue c9d3d60a18
Implement `CacheKey` for all `Pep508Url` variants (#14978)
Closes #14973
2025-07-30 10:44:06 -05:00
Charlie Marsh a76e538aa5
Extend wheel filtering to Android tags (#14977)
## Summary

Just while I'm here for https://github.com/astral-sh/uv/pull/14976.
2025-07-30 15:26:44 +00:00
Charlie Marsh 9b8ff44a04
Perform wheel lockfile filtering based on platform and OS intersection (#14976)
## Summary

Ensures that if the user filters to macOS ARM, we don't include macOS
x86_64 wheels.

Closes https://github.com/astral-sh/uv/issues/14901.
2025-07-30 15:12:22 +00:00
Zanie Blue 6856a27711
Add `extra-build-dependencies` (#14735)
Replaces https://github.com/astral-sh/uv/pull/14092

Adds `tool.uv.extra-build-dependencies = {package = [dependency, ...]}`
which extends `build-system.requires` during package builds.

These are lowered via workspace sources, are applied to transitive
dependencies, and are included in the wheel cache shard hash.

There are some features we need to follow-up on, but are out of scope
here:

- Preferring locked versions for build dependencies
- Settings for requiring locked versions for build depencies

There are some quality of life follow-ups we should also do:

- Warn on `extra-build-dependencies` that do not apply to any packages
- Add test cases and improve error messaging when the
`extra-build-dependencies` resolve fails


-------

There ~are~ were a few open decisions to be made here

1. Should we resolve these dependencies alongside the
`build-system.requires` dependencies? Or should we resolve separately?
(I think the latter is more powerful? because you can override things?
but it opens the door to breaking your build)
2. Should we install these dependencies into the same environment? Or
should we layer it on top as we do elsewhere? (I think it's fine to
install into the same environment)
3. Should we respect sources defined in the parent project? (I think
yes, but then we need to lower the dependencies earlier — I don't think
that's a big deal, but it's not implemented)
4. Should we respect sources defined in the child project? (I think no,
this gets really complicated and seems weird to allow)
5. Should we apply this to transitive dependencies? (I think so)

---------

Co-authored-by: Aria Desires <aria.desires@gmail.com>
Co-authored-by: konstin <konstin@mailbox.org>
2025-07-30 09:53:07 -05:00
Boseong Choi b2eff990df
Fix typo in uv-pep440/README.md (#14965)
## Summary

I noticed what appears to be a small typo in the documentation. In the
section describing dev versions, it says `sbpth table releases`. I
believe this was meant to be `both stable releases`, to match the
structure of the previous sentence about post versions.
2025-07-30 12:25:48 +02:00
Charlie Marsh b31d786fe9
Add `UV_` prefix to installer environment variables (#14964)
## Summary

Available as of https://github.com/astral-sh/cargo-dist/pull/46.
2025-07-30 01:24:59 +00:00
Zanie Blue e7c8b47b7a
Clarify messaging when a new resolution needs to be performed (#14938)
We do not just "ignore" the existing lockfile here. We retain the
existing messaging for cases where we do actually throw out the
lockfile, like `--upgrade`.
2025-07-29 21:13:30 -04:00
Zanie Blue 11fe8f70f9
Add `exclude-newer-package` (#14489)
Adds `exclude-newer-package = { package = timestamp, ... } ` and
`--exclude-newer-package package=timestamp`. These take precedence over
`exclude-newer` for a given package.

This does need to be serialized to the lockfile, so the revision is
bumped to 3. I tested a previous version and we can read a lockfile with
this information just fine.

Closes https://github.com/astral-sh/uv/issues/14394
2025-07-29 17:00:25 -05:00
Zanie Blue 00efde06b6
Split platform detection code into a dedicated `uv-platform` crate (#14918)
In service of some subsequent work...
2025-07-28 14:12:04 -05:00
Zanie Blue 5686771464
Cache Python downloads by default in `python install` tests (#14326)
Adds a cache bucket for Python installs and uses it by default during
tests, extending the opt-in cache added in
https://github.com/astral-sh/uv/pull/12175

Updates the `python_install` tests to use a shared cache for Python
installs. This reduces the `python_install` test runtime on my machine
from 23s -> 17s. The difference should be much larger on machines with
slower internet and less cores for test workers :) This should also
improve stability in CI by reducing reliance on the network during test
runs, see #14327
2025-07-28 17:33:57 +00:00
konsti ac135278c3
Better warning chain styling (#14934)
Improve the styling of warning chains for Python installation errors.
Apply the same logic to other internal warning and error formatting
locations.

**Before**

<img width="1232" height="364" alt="Screenshot from 2025-07-28 10-06-41"
src="https://github.com/user-attachments/assets/e3befe14-ad4c-44ed-8b0a-57d9c9a3b815"
/>

**After**

<img width="1232" height="364" alt="Screenshot from 2025-07-28 10-23-49"
src="https://github.com/user-attachments/assets/1bd890c1-5dbb-4662-93bd-14430c060a69"
/>
2025-07-28 16:23:39 +00:00
shikinamiasuka 55df845922
Fix incorrect file permissions in wheel packages (#14930)
Fixes #14920

## Summary

Problem: When building wheel packages, metadata files (such as RECORD,
METADATA, WHEEL, and
license files) were being created with incorrect Unix permissions
(--w--wx---), lacking
  read permissions and having unexpected executable permissions.

Solution: The fix ensures that all metadata files in wheel packages are
created with proper
   644 (rw-r--r--) permissions by:
- Adding explicit unix_permissions(0o644) setting in the write_bytes
method for metadata
  files
  - Updating permission constants to use octal notation for clarity
  - Improving code comments to document the permission settings

Impact: This change ensures wheel packages created by uv have standard
file permissions
consistent with other Python build tools like setuptools, improving
compatibility and
  following Python packaging best practices.
2025-07-28 15:56:08 +02:00
Zanie Blue c97d12bcf3
Unhide `uv` from `--build-backend` options (#14939)
Closes https://github.com/astral-sh/uv/issues/14921
2025-07-28 13:26:23 +00:00
renovate[bot] 8cd8c95071
Update Rust crate criterion to 0.7.0 (#14927)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [criterion](https://bheisler.github.io/criterion.rs/book/index.html)
([source](https://redirect.github.com/bheisler/criterion.rs)) |
dependencies | minor | `0.6.0` -> `0.7.0` |

---

> [!WARNING]
> Some dependencies could not be looked up. Check the Dependency
Dashboard for more information.

---

### Release Notes

<details>
<summary>bheisler/criterion.rs (criterion)</summary>

###
[`v0.7.0`](https://redirect.github.com/bheisler/criterion.rs/blob/HEAD/CHANGELOG.md#070---2025-07-25)

[Compare
Source](https://redirect.github.com/bheisler/criterion.rs/compare/0.6.0...0.7.0)

- Bump version of criterion-plot to align dependencies.

</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:eyJjcmVhdGVkSW5WZXIiOiI0MS40MC4wIiwidXBkYXRlZEluVmVyIjoiNDEuNDAuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiaW50ZXJuYWwiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-28 08:10:06 -05:00
konsti 8cb36d6f40
Move all retry tests to `network.rs` (#14935)
Retry behavior isn't tied to a specific installation method, but
underlies all of them.
2025-07-28 07:33:54 -05:00
Charlie Marsh 0a51489ec4
Remove resolved TODO in `allowed_indexes` (#14912)
## Summary

This got solved in #14858.
2025-07-26 04:04:28 +00:00
Zanie Blue ae1964935f
Remove extra newline (#14907)
Fixes https://github.com/astral-sh/uv/pull/14905#discussion_r2231915714
2025-07-25 20:40:09 +00:00
Zanie Blue 7b8dd5cfaf
Run `cargo update` (#14899) 2025-07-25 15:19:38 -05:00
Zanie Blue 396e198081
Update documentation for preview flags (#14902)
Follows #14823
2025-07-25 15:19:24 -05:00
Zanie Blue c489fcb633
Update validation for `enviroments` and `required-environments` in `uv.toml` (#14905)
See https://github.com/astral-sh/uv/pull/14322/files#r2231891679

Closes https://github.com/astral-sh/uv/issues/14904
2025-07-25 15:19:07 -05:00
Zanie Blue a701d3c447
Use workspace dependencies for crate dev-dependencies (#14903) 2025-07-25 13:57:49 -05:00
Zanie Blue bfb4bc2aeb
Split preview mode into separate feature flags (#14823)
I think this would give us better hygiene than a global flag. It makes
it easier for users to opt-in to overlapping features, such as Python
upgrades and Python bin installations and to disable warnings for
preview mode without opting in to a bunch of other features. In general,
I want to reduce the burden for putting something under preview.

The `--preview` and `--no-preview` flags are retained as global
overrides. A new `--preview-features` option is added which accepts
comma separated features or can be passed multiple times, e.g.,
`--preview-features add-bounds,pylock`. There's a `UV_PREVIEW_FEATURES`
environment variable for that option (I'm not sure if we should overload
`UV_PREVIEW`, but could be convinced).
2025-07-25 11:01:57 -05:00
konsti 9376cf5482
Remove prioritized dist duplication (#14887)
`Candidate` has an optional field `prioritized`, which was mostly
redundant with `CandidateDist`. Specifically, it was only `None`, if
`CandidateDist` was `Installed`. This commit removes this duplication.
2025-07-25 17:18:24 +02:00
Charlie Marsh 1146f3f62d
Avoid invalidating lockfile when path or workspace dependencies define explicit indexes (#14876)
## Summary

This is an alternative to #14003 that takes advantage of the fact that
we already validate that the requirements are up-to-date when validating
the lockfile, and the requirements for pinned requirements include the
index itself -- so rather than collecting all the explicit indexes
upfront, we can just add them to the available list as we iterate over
the lockfile's dependency graph.

This gets all the tests passing from that PR, but with ~no performance
impact and a much less invasive change. It also gets the "circular
dependency" test passing, which is marked with a TODO in that PR.

Closes https://github.com/astral-sh/uv/issues/11419.
2025-07-25 08:18:28 -04:00
Zanie Blue 05031becc3
Fix snapshot for GitHub message (#14881) 2025-07-24 22:40:55 +00:00
Zanie Blue e48a9c0992
Remove redundant `let Some` (#14880) 2025-07-24 17:29:56 -05:00
Zanie Blue cd4cf27d88
Add test cases for dependent conflicting extras (#14879)
Picked from #9130
2025-07-24 17:29:40 -05:00
Zanie Blue 7e78f54e7c
Bump version to 0.8.3 (#14875) 2025-07-24 15:51:15 -05:00
Zanie Blue 23ed31b94d
Consolidate environment hash filtering (#14864) 2025-07-24 12:35:45 +00:00
konsti 1150de3fc5
uv_build: Allow non-standard entrypoint names (#14867)
It seems that non-standard entrypoints are still widely used,
downgrading the error to a tracing warning.

Fixes #14442

---------

Co-authored-by: Ed Morley <501702+edmorley@users.noreply.github.com>
2025-07-24 14:12:36 +02:00
Elijah Hartvigsen 3b59515614
Fix typos in uv_build reference documentation (#14853)
## Summary

Fixes both typos mentioned in #14845.

## Test Plan

It wasn't :D

---------

Co-authored-by: konstin <konstin@mailbox.org>
2025-07-24 09:55:14 +00:00
Charlie Marsh 02e103f867
Respect `--with` versions over base environment versions (#14863)
## Summary

This fixes a regression from https://github.com/astral-sh/uv/pull/14447
that we seemingly didn't have test coverage for. Specifically, if you
have a version of a package in your project, and then install a
different version with `--with`, the environment should import the
`--with` version.

Closes #14860.
2025-07-24 02:00:03 +00:00
Zanie Blue 1ddfcee9e9
Fix missed stabilization of removal of registry entry during Python uninstall (#14859)
Funny enough, I caught this via
https://github.com/astral-sh/uv/pull/14823
2025-07-23 17:44:48 -05:00
Charlie Marsh faa12f50ce
Respect credentials from all defined indexes (#14858)
## Summary

The core problem here is that `allowed_indexes` only includes at most
one "default" index. This is problematic for tool upgrades, since the
index in the receipt will be marked as default, but credentials will be
omitted; if credentials are then defined in a `uv.toml`, we'll never
look at those, since that will _also_ be marked as default, and we only
look at the first default.

Instead, we should consider all defined indexes in priority order.

Closes https://github.com/astral-sh/uv/issues/14806.
2025-07-23 21:23:51 +00:00
Charlie Marsh 4dd0392086
Avoid writing redacted credentials to tool receipt (#14855)
## Summary

Right now, we write index URLs to the tool receipt with redacted
credentials (i.e., a username, and `****` in lieu of a password). This
is always wrong and unusable. Instead, this PR drops them entirely.

Part of https://github.com/astral-sh/uv/issues/14806.
2025-07-23 16:01:10 -04:00
Charlie Marsh 09549c2e71
Use `cache_index_credentials` in `uv venv` (#14854) 2025-07-23 16:00:56 -04:00
konsti f7ac6875c3
Improve concurrency safety of Python downloads into cache (#14846) 2025-07-23 11:52:39 -05:00
github-actions[bot] 310a9d3426
Sync latest Python releases (#14847)
Automated update for Python releases.

Co-authored-by: zanieb <2586601+zanieb@users.noreply.github.com>
2025-07-23 11:01:09 -05:00
Zanie Blue 21fadbcc13
Bump version to 0.8.2 (#14832) 2025-07-22 19:39:53 +00:00
Nils Koch 34cda1be44
expose `tls_built_in_root_certs` from reqwest client (#14816)
<!--
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

We are using UV as a library and need to set `tls_built_in_root_certs`
on the reqwest client.

This PR exposes this property in the `BaseClientBuilder` and in the
`RegistryClientBuilder`. The default is set to `false`, so this does not
change any behaviour unless you explicitly opt into it.

<!-- What's the purpose of the change? What does it do, and why? -->

## Test Plan

<!-- How was it tested? -->
2025-07-22 14:25:33 -05:00
Zanie Blue 02cc49296b
Avoid reading files in the environment bin that are not entrypoints (#14830)
Closes https://github.com/astral-sh/uv/issues/14829

I tested this against the given Dockerfile.
2025-07-22 19:11:15 +00:00
Zanie Blue 8289e38e8f
Add `UV_INIT_BUILD_BACKEND` (#14821)
Closes https://github.com/astral-sh/uv/issues/14820
2025-07-22 14:10:08 -05:00
Charlie Marsh 27ade0676f
Preserve index URL priority order when writing to pyproject.toml (#14831)
## Summary

A little nuanced, but... When you add multiple `--index` URLs on the CLI
(e.g., in `uv pip install`), we check the first-provided index, then the
second index, etc. However, when we _write_ those URLs to the
`pyproject.toml` in `uv add`, we were adding them in reverse-order. We
now add them in a way that preserves the priority order.

Closes https://github.com/astral-sh/uv/issues/14817.
2025-07-22 19:09:59 +00:00
Charlie Marsh 3d1fec2732
Add derivation chains for dependency errors (#14824)
## Summary

This PR adds derivation chain for another class of resolver failures.
For example, if we encounter a transitive URL dependency, we now tell
the user which package included it, and the full derivation chain:

```
  × Failed to resolve dependencies for `foo` (v0.1.0)
  ╰─▶ Package `flask` was included as a URL dependency. URL dependencies must be
      expressed as direct requirements or constraints. Consider adding `flask @
      9d4508e893f34853a30fd769c02e9d/flask-3.1.1-py3-none-any.whl`
      to your dependencies or constraints file.
  help: `foo` (v0.1.0) was included because `baz` (v0.1.0) depends on `foo`
```

Closes #14795.
2025-07-22 15:08:33 -04:00
Zanie Blue 076677da20
Avoid removing empty directories when constructing virtual environments (#14822)
Closes https://github.com/astral-sh/uv/issues/14815

I tested this with the docker-compose reproduction. You can also see a
regression test change at
2ae4464b7e
2025-07-22 13:50:14 -05:00
Zanie Blue f0151f3a18
Bump version to 0.8.1 (#14818) 2025-07-22 11:36:20 -05:00
Zanie Blue 7d41bdb308
Allow removal of virtual environments with missing interpreters (#14812)
Co-authored-by: konsti <konstin@mailbox.org>
2025-07-22 15:16:59 +00:00
Copilot 96b889bce3
Add hint to use `uv self version` when `uv version` cannot find a project (#14738)
When users run `uv version` in a directory without a `pyproject.toml`
file, they often intend to check uv's own version rather than a
project's version. This change adds a helpful hint to guide users to the
correct command.

**Before:**
```
❯ uv version
error: No `pyproject.toml` found in current directory or any parent directory
```

**After:**
```
❯ uv version
error: No `pyproject.toml` found in current directory or any parent directory

hint: If you meant to view uv's version, use `uv self version` instead
```

## Changes

- Modified `find_target()` function in
`crates/uv/src/commands/project/version.rs` to catch
`WorkspaceError::MissingPyprojectToml` specifically and enhance the
error message with a helpful hint
- Added import for `WorkspaceError` to access the specific error type
- Updated existing tests to expect the new hint message in error output
- Added new test case `version_get_missing_with_hint()` to verify
behavior

The hint appears consistently across all scenarios where `uv version`
fails to find a project:
- `uv version` (normal mode)
- `uv version --project .` (explicit project mode)
- `uv version --preview` (preview mode)

The change maintains all existing functionality - when a
`pyproject.toml` is found, `uv version` continues to work normally
without showing the hint.

Fixes #14730.

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: zanieb <2586601+zanieb@users.noreply.github.com>
2025-07-22 08:32:45 -05:00
Zanie Blue e49d61db1f
Emit JSON output with `--quiet` (#14810) 2025-07-22 08:21:54 -05:00
Charlie Marsh 2677e85df9
Disallow writing symlinks outside the source distribution target directory (#12259)
## Summary

Closes #12163.

## Test Plan

Created an offending source distribution with this script:

```python
import io
import tarfile
import textwrap
import time

PKG_NAME  = "badpkg"
VERSION   = "0.1"
DIST_NAME = f"{PKG_NAME}-{VERSION}"
ARCHIVE   = f"{DIST_NAME}.tar.gz"


def _bytes(data: str) -> io.BytesIO:
    """Helper: wrap a text blob as a BytesIO for tarfile.addfile()."""
    return io.BytesIO(data.encode())


def main(out_path: str = ARCHIVE) -> None:
    now = int(time.time())

    with tarfile.open(out_path, mode="w:gz") as tar:

        def add_file(path: str, data: str, mode: int = 0o644) -> None:
            """Add a regular file whose *content* is supplied as a string."""
            buf  = _bytes(data)
            info = tarfile.TarInfo(path)
            info.size   = len(buf.getbuffer())
            info.mtime  = now
            info.mode   = mode
            tar.addfile(info, buf)

        # ── top‑level setup.py ───────────────────────────────────────────────
        setup_py = textwrap.dedent(f"""\
            from setuptools import setup, find_packages
            setup(
                name="{PKG_NAME}",
                version="{VERSION}",
                packages=find_packages(),
            )
        """)
        add_file(f"{DIST_NAME}/setup.py", setup_py)

        # ── minimal package code ─────────────────────────────────────────────
        add_file(f"{DIST_NAME}/{PKG_NAME}/__init__.py", "# placeholder\\n")

        # ── the malicious symlink ────────────────────────────────────────────
        link = tarfile.TarInfo(f"{DIST_NAME}/{PKG_NAME}/evil_link")
        link.type     = tarfile.SYMTYPE
        link.mtime    = now
        link.mode     = 0o777
        link.linkname = "../../../outside.txt"
        tar.addfile(link)

    print(f"Created {out_path}")


if __name__ == "__main__":
    main()
```

Verified that both `pip install` and `uv pip install` rejected it.

I also changed `link.linkname = "../../../outside.txt"` to
`link.linkname = "/etc/outside"`, and verified that the absolute path
was rejected too.
2025-07-22 09:20:09 -04:00
Zanie Blue c8486da495
Update virtual environment removal to delete `pyvenv.cfg` last (#14808)
An alternative to https://github.com/astral-sh/uv/pull/14569

This isn't a complete solution to
https://github.com/astral-sh/uv/issues/13986, in the sense that it's
still "fatal" to `uv sync` if we fail to delete an environment, but I
think that's okay — deferring deletion is much more complicated. This at
least doesn't break users once the deletion fails. The downside is we'll
generally treat this virtual environment is valid, even if we nuked a
bunch of it.

Closes https://github.com/astral-sh/uv/issues/13986
2025-07-22 08:13:38 -05:00
Zanie Blue 8bffa693b4
Copy entry points and Jupyter data directories into ephemeral environments (#14790)
This is an alternative to https://github.com/astral-sh/uv/pull/14788
which has the benefit that it addresses
https://github.com/astral-sh/uv/issues/13327 which would be an issue
even if we reverted #14447.

There are two changes here

1. We copy entry points into the ephemeral environment, and rewrite
their shebangs (or trampoline target) to ensure the ephemeral
environment is not bypassed.
2. We link `etc/jupyter` and `share/jupyter` data directories into the
ephemeral environment, this is in order to ensure the above doesn't
break Jupyter which unfortunately cannot find the `share` directory
otherwise. I'd love not to do this, as it seems brittle and we don't
have a motivating use-case beyond Jupyter. I've opened
https://github.com/jupyterlab/jupyterlab/issues/17716 upstream for
discussion, as there is a viable patch that could be made upstream to
resolve the problem. I've limited the fix to Jupyter directories so we
can remove it without breakage.

Closes https://github.com/astral-sh/uv/issues/14729
Closes https://github.com/astral-sh/uv/issues/13327
Closes https://github.com/astral-sh/uv/issues/14749

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2025-07-22 12:11:05 +00:00
Ping Shuijie c1bf934721
chore: fix some minor issues in comments (#14807)
<!--
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

 fix some minor issues in comments

<!-- What's the purpose of the change? What does it do, and why? -->

## Test Plan

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

Signed-off-by: pingshuijie <pingshuijie@outlook.com>
2025-07-22 10:13:05 +00:00
Charlie Marsh ecfa386088
Error on unknown fields in `dependency-metadata` (#14801)
## Summary

Closes https://github.com/astral-sh/uv/issues/14800.
2025-07-21 22:15:03 +00:00
Charlie Marsh 036c9bef3f
Add a borrowed `Realm` type (#14798)
## Summary

Allows zero-cost comparisons against URL references.
2025-07-21 21:07:35 +00:00
Charlie Marsh a3ea1b69f2
Add support for `HF_TOKEN` (#14797)
## Summary

If `HF_TOKEN` is set, we'll automatically wire it up to authenticate
requests when hitting private `huggingface.co` URLs in `uv run`.

## Test Plan

An unauthenticated request:

```
> cargo run -- run https://huggingface.co/datasets/cmarsh/test/resolve/main/main.py

  File "/var/folders/nt/6gf2v7_s3k13zq_t3944rwz40000gn/T/mainYadr5M.py", line 1
    Invalid username or password.
            ^^^^^^^^
SyntaxError: invalid syntax
```

An authenticated request:

```
> HF_TOKEN=hf_... cargo run run https://huggingface.co/datasets/cmarsh/test/resolve/main/main.py

Hello from main.py!
```
2025-07-21 20:55:33 +00:00
Charlie Marsh 2c8e394f03
Create (e.g.) `python3.13t` executables in `uv venv` (#14764)
## Summary

CPython's `venv` module creates these, so we should too.

On non-Windows, we add `python3.13t`.

On Windows, we add `python3.13t.exe` and `pythonw3.13t.exe` (see:
65d2c51c10/Lib/venv/__init__.py (L362)).

Closes https://github.com/astral-sh/uv/issues/14760.
2025-07-21 16:25:50 +00:00
konsti f3dc457d2a
Introduce a generic type for list operations (#14792)
We currently have two marker keys that a list, `extras` and
`dependency_groups`, both from PEP 751. With the variants PEP, we will
add three more. This change is broken out of the wheel variants PR to
introduce generic marker list support, plus a change to use
`ContainerOperator` in more places.
2025-07-21 18:21:46 +02:00
Charlie Marsh d052427c37
Accept `&Path` when creating executable links (#14791)
## Summary

I don't see a great reason for this to take an owned value. It only
needs an owned value for error cases.
2025-07-21 11:53:28 -04:00
Charlie Marsh 80708dea6e
Use a match for Windows executables in `venv` (#14766)
## Summary

I found it confusing that the `else` case for `== "graalpy"` is still
necessary for the `== "pypy"` branch (i.e., that `pythonw.exe` is copied
for PyPy despite not being in the `== "pypy"` branch).

Instead, we now use a match for PyP, GraalPy, and then everything else.
2025-07-21 14:48:52 +00:00
Charlie Marsh aafeda2253
Enforce `requires-python` in `pylock.toml` (#14787)
## Summary

Turns out we weren't validating this at install-time.
2025-07-21 14:37:14 +00:00
Copilot d768dedff6
Remove `version_get_fallback_unmanaged_json` test (#14786)
The `version_get_fallback_unmanaged_json` test was failing when running
tests outside of a git checkout (e.g., from a release tarball) due to
inconsistent behavior based on git availability.

The test had conditional logic that expected different outcomes
depending on whether `git_version_info_expected()` returned true or
false:
- In git checkouts: Expected failure with "The project is marked as
unmanaged" error
- Outside git checkouts: Expected success with fallback behavior showing
version info

However, the fallback behavior was removed in version 0.8.0, making this
test obsolete. All other similar tests
(`version_get_fallback_unmanaged`,
`version_get_fallback_unmanaged_short`,
`version_get_fallback_unmanaged_strict`) consistently expect failure
when a project is marked as unmanaged, regardless of git availability.

This change removes the problematic test entirely, as suggested by
@zanieb. All remaining version tests (51 total) continue to pass.

Fixes #14785.

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: zanieb <2586601+zanieb@users.noreply.github.com>
2025-07-21 14:17:06 +00:00
Ibraheem Ahmed ba1319450a
Update `toml` to v0.9 (#14571)
## Summary

This should give us some performance and error message improvements.

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
Co-authored-by: Zanie Blue <contact@zanie.dev>
2025-07-21 08:18:16 -05:00
Charlie Marsh b81cce9152
Support `extras` and `dependency_groups` markers on `uv pip install` and `uv pip sync` (#14755)
## Summary

We don't yet support writing these, but we can at least read them
(which, e.g., allows you to install PDM-exported `pylock.toml` files
with uv, since PDM _always_ writes a default group).

Closes #14740.
2025-07-21 12:48:47 +00:00
konsti ab48dfd0cb
Collect contains markers in enum (#14782)
We'll add more contains markers for the wheel variants, so I want to
unify them before rebasing the variants branch on them.
2025-07-21 08:38:33 -04:00
Jo 9983273289
Use sha256 checksum from GitHub API for GraalPy releases (#14779)
## Summary

Follow #14078, use GitHub generated sha256 for GraalPy releases too.

## Test Plan

```console
uv run ./crates/uv-python/fetch-download-metadata.py
```
2025-07-21 08:35:45 -04:00
Jo 98d6ab6632
Improve `CPythonFinder._parse_download_url` a bit (#14780)
## Summary

Rename `_parse_download_url` to `_parse_download_asset` and move the
`asset['digest']` logic into it.

## Test Plan

```console
uv run ./crates/uv-python/fetch-download-metadata.py
```
2025-07-21 12:22:45 +02:00
Zanie Blue 7c2819d1f6
Match `--bounds` formatting for `uv_build` bounds in `uv init` (#14731)
Closes #14724 

https://chatgpt.com/codex/tasks/task_e_687a53ba646c8331baa4140c5b2bec70

---------

Co-authored-by: konstin <konstin@mailbox.org>
2025-07-21 09:48:38 +00:00
Charlie Marsh 0487034e91
Fix bad merge in `warn_uv_toml_masked_fields` (#14767)
## Summary

The branch got stale and merged without flagging that this no longer
compiles.
2025-07-20 20:28:31 -04:00