Rustfmt introduces a lot of formatting changes in the 2024 edition. To
not break everything all at once, we split out the set of formatting
changes compatible with both the 2021 and 2024 edition by first
formatting with the 2024 style, and then again with the currently used
2021 style.
Notable changes are the formatting of derive macro attributes and lines
with overly long strings and adding trailing semicolons after statements
consistently.
We may run on case-sensitive file systems (Linux, generally) or on
case-insensitive file systems (Windows, generally), while modules in
Python may be lower or upper case. For robustness over filesystem
casing, we require an explicit module name for modules with upper cases.
Fixes#13419
Love this tooling! Small adjustment to help on error messaging 🙏
<!--
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 previous message was missing the word **“like,”** which made it read
a tad awkwardly.
This PR inserts the missing word so the error reads naturally:
**After:**
```
$ uvx ch1.py
error: It looks like you tried to run a Python script at `ch1.py`, which is not supported by `uvx`
hint: Use `uv run ch1.py` instead
```
**Before:**
```
$ uvx ch1.py
error: It looks you tried to run a Python script at `ch1.py`, which is not supported by `uvx`
hint: Use `uv run ch1.py` instead
```
## Test Plan
<!-- How was it tested? -->
- `cargo run -- uvx examples/ch1.py` shows the updated message (see
“After” above).
- `cargo test` passes.
Unlike OS APIs, glob inclusion checks don't work when there are relative
path elements such as `./`. We normalize the path before using it for
the glob.
Fixes#13407
We were not correctly falling back to cached realm credentials when an
index URL was provided with only a username. This came up in a [later
comment](https://github.com/astral-sh/uv/issues/13443#issuecomment-2881115301)
on #13443 where credentials in a pip extra index in `uv.toml` were being
ignored when the same URL (but with only a username) was used at the
command line for `--extra-index-url`. I've added a test to catch this
case.
Closes#13443
## Summary
Related to https://github.com/astral-sh/uv/issues/12492
This change makes all progress bars vertically aligned. This is still a
WIP and so is not complete, in the current design I store `max_len` in
`BarState` and update it on every `on_request_start`, however this is
problematic since order matters, and if the largest name is not sent
first, the alignment is not complete. To mitigate this we'd probably
have to update all previous bars by "iterating" through the `bars` field
in `BarState` and update all request bars.
Below is an image of what happens when the largest name
(`nvidia-cusparselt-cu12`) is not the first (in this case, it was the
second to last).

## Test Plan
There are currently no tests, and I'm not sure how to design them since
from what I gather the `uv_snapshot` facilities record the final output,
not the intermediate stages.
---------
Co-authored-by: konstin <konstin@mailbox.org>
This PR redacts credentials in displayed URLs.
It mostly relies on a `redacted_url` function (and where possible
`IndexUrl::redacted`). This is a quick way to prevent leaked credentials
but it's prone to programmer error when adding new trace statements. A
better follow-on would use a `RedactedUrl` type with the appropriate
`Display` implementation. This would allow us to still extract
credentials from the URL while displaying it securely. On the plus side,
the sites where the `redacted_url` function are used serve as easy
signposts for where to use the new type in a future PR.
Closes#1714.
## Summary
We mapped both `.tgz` and `.tar.gz` to the same enum variant; later,
though, we made the assumption that a file marked with that variant
ended with exactly `.tar.gz`. Instead, we need to preserve the
originating suffix.
Closes https://github.com/astral-sh/uv/issues/13372.
## Summary
If a set of wheel tags includes a dot, this code is treating the part
_after_ the dot as an extension, and thereby failing to detect that the
entry is a symlink to an archive (and thereby removing the archive).
This is all an optimization, so this code just makes it a little
targeted: we skip specific known extensions, rather than anything with
any extension.
Closes https://github.com/astral-sh/uv/issues/13270.
This follows on from #13334 to fix another case.
<!--
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
If a dependency group contained any `{ include-group = "..." }` entries,
the sort detection would bail out. The root cause of the problem was
gating the sort detection behind `deps.iter().all(Value::is_str)`.
A public code search reveals that keeping include-groups at the top is
by far the most common, but keeping them at the bottom isn't uncommon.
In both of these cases, uv will now preserve the convention that is in
use.
Unless I've missed it, I don't think uv supports `uv add`ing an
include-group, and so that wasn't tested here.
## Test Plan
cargo test
---------
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
This also omits bounds on constraints, and is useful for that. This
retains `--raw-sources` as an alias. I've had this on my mind for a
while, but https://github.com/astral-sh/uv/pull/12946 reminded me of it
again.
## Summary
Closes#13253
## Test Plan
```sh
❯ cat pyproject.toml | rg required
required-version = ">=0.7.3, <0.8"
❯ cargo run -q --features self-update --manifest-path ~/uv/Cargo.toml add black
error: Required uv version `>=0.7.3, <0.8` does not match the running version `0.7.2`.
hint: Update `uv` by running `uv self update`.
❯ cat pyproject.toml | rg required
required-version = ">=0.7.3"
❯ cargo run -q --features self-update --manifest-path ~/uv/Cargo.toml add black
error: Required uv version `>=0.7.3` does not match the running version `0.7.2`.
hint: Update `uv` by running `uv self update`.
❯ cat pyproject.toml | rg required
required-version = "<0.7"
❯ cargo run -q --features self-update --manifest-path ~/uv/Cargo.toml add black
error: Required uv version `<0.7` does not match the running version `0.7.2`.
❯ cat pyproject.toml | rg required
required-version = ">=0.4,<0.7"
❯ cargo run -q --features self-update --manifest-path ~/uv/Cargo.toml add black
error: Required uv version `>=0.4, <0.7` does not match the running version `0.7.2`.
```
---------
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
## Summary
The prior implementation only looks for dependencies which are sorted by
name then specifier.
I knew uv was meant to preserve sorted dependencies, but it never seemed
to work for me.
I've always used the "sort lines" feature of PyCharm/Sublime to sort
these lists, and I guess I'm not the only one. In such a case,
`flask-wtf>=1.2.1` is sorted before `flask>=3.0.2`.
After digging into the code I realised what was happening, hence this
merge request.
Maybe there's a tool I'm not aware of that people are using to sort
dependencies "properly", or are doing it by hand, but I think this is
worth supporting.
Relevant issues: https://github.com/astral-sh/uv/issues/9076,
https://github.com/astral-sh/uv/issues/10738
## Test Plan
`cargo test`
e.g., these are misleading cruft in the error message at
https://github.com/astral-sh/uv/pull/12168#discussion_r2078204601
```
❯ uv python find /foo/bar
error: No interpreter found for path `/foo/bar` in virtual environments, managed installations, or search path
❯ cargo run -q -- python find /foo/bar
error: No interpreter found at path `/foo/bar`
```
When removing a Python interpreter underneath an existing venv, uv
currently shows a not found error:
```
error: Failed to inspect Python interpreter from active virtual environment at `.venv/bin/python3`
Caused by: Python interpreter not found at `/home/konsti/projects/uv/.venv/bin/python3`
```
This is unintuitive, as the file for the Python interpreter does exist,
it is a broken symlink that needs to be replaced with `uv venv`.
I've been encountering those occasionally, and I expect users that
switch between versions a lot will, too, especially when they also use
pyenv or a similar Python manager.
The new error hints at this solution:
```
error: Failed to inspect Python interpreter from active virtual environment at `.venv/bin/python3`
Caused by: Broken symlink at `.venv/bin/python3`, was the underlying Python interpreter removed?
hint: To recreate the virtual environment, run `uv venv`
```
PEP 639 does not allow any characters that aren't in either their
limited glob syntax or the alphanumeric Unicode characters. This means
there's no way to express a glob such as `**/@test` for the excludes.
We extend the glob syntax from PEP 639 by introducing backslash escapes,
which can escape all characters but path separators (forward and
backwards slashes) to be parsed verbatim.
This means we have two glob parsers: The strict PEP 639 parser for
`project.license-files`, and our extended parser for `tool.uv`, with a
slight difference if you need to use special characters, to both adhere
to PEP 639 and to support cases such as #13280.
Fixes#13280
We have test coverage for this elsewhere, but managed Python versions
are a distinct case because we know the _full_ version before querying
the interpreter (whereas, when we find them on the `PATH`, we usually
only know `X.y` from the file name).
This pre-filter logic now matches our subsequent logic at
060be9cef1/crates/uv-python/src/discovery.rs (L2146-L2149)060be9cef1
shows the snapshot change.
## Summary
Add a `--show-extras` argument to the `uv tool list` cli, to show which
extra dependencies were installed with the tool.
i.e.
```bash
$ uv tool install fastapi --with requests --with typer==0.14
```
```bash
$ uv tool list --show-extras
fastapi v0.115.12 [extras: requests, typer==0.14]
- fastapi
```
## Test Plan
Added a new test function based on the others in the same file, with the
other arguments tested with the new argument as well.
The goal of this PR is to support reproducible builds and best-effort
platform-independent builds. Previously, while the build backend would
build the same source dist and wheel on the same machine, they would
look different across different operating systems. This PR fixes the
platform-dependent walk dir order by sorting and removes
platform-specific permissions from the source dist that had caused those
differences.
The reproducibility goal does not extend to platform-dependent
filesystem features, such as permissions and links, especially in
interaction with Git. Since most users share code across platforms
through Git, we're focusing on cross-platform behavior under Git. One of
those caveats is intentional: If a file, such as a bash script, has an
executable bit, we preserve it. This means that E.g. builds of Git
checkout of a repository with an executable shell script in the sources
will have different archives on Unix and Windows. Another relevant case
are symlinks: By default, Git on Windows replaces symlinks with a file
that contains the path to the target file
(https://stackoverflow.com/q/5917249/3549270). (This example comes from
Cargo, where it means that the package archive is different on Windows
when symlinking license from the repository root to a workspace package)
Best reviewed commit-by-commit
## Summary
This adds GraalPy download metadata so that `uv python install graalpy`
works. See https://github.com/astral-sh/uv/issues/13114
## Test Plan
The existing integration test was changed to test this functionality.
In #13302, there was an IO error without context. This error seems to be
caused by a symlink error. Switching as symlinking to `fs_err` ensures
these errors will carry context in the future.
## Summary
We now show a user-visible warning if we're using a "stale" virtual
environment due to `--no-sync`. I'd also be fine erroring here.
Closes https://github.com/astral-sh/uv/issues/13235.
Add configuration documentation for the build backend and make it the
preview default.
The build backend should generally work with default configuration
unless you want specific features such as flat layout or module
renaming, there is only a dedicated configuration, but no concept or
guide page for the build backend. Once the build backend is stable, we
can update the guide documentation to explain that uv defaults to its
own build backend, but other build backends are also supported.
The uv build backend becomes the default in preview, giving it more
exposure from users and preparing it to make it the default proper. The
current documentation retains warnings that the build backend is in
preview.
To see current uses of `uv_build` on GitHub:
https://github.com/search?q=path%3A**%2Fpyproject.toml+uv_build%3E%3D0&type=code
---------
Co-authored-by: Zanie Blue <contact@zanie.dev>
## Summary
If a script has some requirements, and you provide `--with`, we
currently ignore any constraints from those requirements. We might want
to treat them as hard constraints in the future. For now, though, we
just treat them as preferences -- so we _prefer_ those versions, but
don't require them to match and still run the `--with` resolution in
isolation.
Closes https://github.com/astral-sh/uv/issues/13173.
See commentary at
https://github.com/astral-sh/uv/issues/9828#issuecomment-2537542100
regarding the limitations and future upstream changes needed.
```
❯ cargo build --features self-update
Compiling uv v0.5.8 (/Users/zb/workspace/uv/crates/uv)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 7.28s
❯ cp ./target/debug/uv ~/.cargo/bin
❯ uv self update --dry-run
info: Checking for updates...
Nothing to do. You're on the latest version of uv (v0.5.8)
❯ uv self update --dry-run 0.5.7
info: Checking for updates...
Would update uv from v0.5.8 to v0.5.7
❯ vi ~/.config/uv/uv-receipt.json # Edit the receipt to think its on an older version
❯ uv self update --dry-run
info: Checking for updates...
Would update uv from v0.5.8 to the latest version
```
---------
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
## Summary
Part of https://github.com/astral-sh/uv/issues/13173, but doesn't close
the issue. This just respects preferences if your script uses a
lockfile, since we already support that for locked _projects_.
#5577 fixed a bug on macos due to dynamically linking lzma/xz through
static linking. In #7686, this feature was moved to the performance
category.
This PR moves the `xz2/static` back to the general default features,
and, inspired by https://github.com/Homebrew/homebrew-core/pull/222211,
it structures and documents the feature flags cleaner.
We need to take care that this feature does not accidentally disable
features we want.
---------
Co-authored-by: Zanie Blue <contact@zanie.dev>
## Summary
The only thing that changed for #12175 relevant to the existing
downloads is the order of nesting, so we're checking all nested IO
errors instead of only the first one.
See #13238
## Test Plan
This is an educated guess based on what happens if I turn off the
network during a download.
```
Downloading cpython-3.13.3-linux-x86_64-gnu (download) (20.3MiB)
TRACE Considering retry of error: ExtractError("cpython-3.13.3-20250409-x86_64-unknown-linux-gnu-install_only_stripped.tar.gz", Io(Custom { kind: Other, error: TarError { desc: "failed to unpack `/home/konsti/.local/share/uv/python/.temp/.tmpe3AIvt/python/lib/libpython3.13.so.1.0`", io: Custom { kind: Other, error: TarError { desc: "failed to unpack `python/lib/libpython3.13.so.1.0` into `/home/konsti/.local/share/uv/python/.temp/.tmpe3AIvt/python/lib/libpython3.13.so.1.0`", io: Custom { kind: Other, error: reqwest::Error { kind: Decode, source: reqwest::Error { kind: Body, source: TimedOut } } } } } } }))
TRACE Cannot retry IO error: not one of `ConnectionReset` or `UnexpectedEof`
TRACE Cannot retry IO error: not one of `ConnectionReset` or `UnexpectedEof`
TRACE Cannot retry error: not an IO error
error: Failed to install cpython-3.13.3-linux-x86_64-gnu
Caused by: Failed to extract archive: cpython-3.13.3-20250409-x86_64-unknown-linux-gnu-install_only_stripped.tar.gz
Caused by: failed to unpack `/home/konsti/.local/share/uv/python/.temp/.tmpe3AIvt/python/lib/libpython3.13.so.1.0`
Caused by: failed to unpack `python/lib/libpython3.13.so.1.0` into `/home/konsti/.local/share/uv/python/.temp/.tmpe3AIvt/python/lib/libpython3.13.so.1.0`
Caused by: error decoding response body
Caused by: request or response body error
Caused by: operation timed out
```
<!--
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#11970.
## Test Plan
<!-- How was it tested? -->
Ran `cargo nextest`
There is a new idna version of testpypi. While we don't select that
version due to the exclude-newer cutoff, the version is still available
to pubgrub as an incompatible choice, changing the error message on
conflicts.
## Summary
Part of #12838. Allow users to configure `python-downloads-json-url` in
`uv.toml` and not just from env.
I followed similar PR #8695, so same as there it's also available in the
CLI (I think maybe it's better not to be configurable from the CLI, but
since the mirror parameters are, I think it's better to do the same)
## Test Plan
<!-- How was it tested? -->
## Summary
In #10939 I added the generated
`crates/uv-python/src/download-metadata-minified.json` file which is a
minified version of `crates/uv-python/download-metadata.json`.
The main reason for this PR is to avoid bloating the git objects as this
is a single-line file.
As a bonus, I also filtered the embed json to include only the versions
for the compiled target. Which should improve the binary size and
performance by a bit.
## Test Plan
<!-- How was it tested? -->
Previously, we were using the wrong `Workspace` discovery and would
report the version of the workspace root, which would iterate up from
the `--project` directory and return the workspace root (with or without
a project in the root). Instead, we need `ProjectWorkspace` discovery
that returns the closest project.
This fixes `uv version --project <path>` where `<path>` belongs to a
workspace member.
Fixes#13213
I think this regressed in https://github.com/astral-sh/uv/pull/13027 — I
misunderstood what versions could be represented in the `pyvenv.cfg` (I
assumed they _never_ included pre-release components).
Closes#13233
uv’s default index strategy was designed with dependency confusion
attacks in mind. [According to the
docs](https://docs.astral.sh/uv/configuration/indexes/#searching-across-multiple-indexes),
“if a package exists on an internal index, it should always be installed
from the internal index, and never from PyPI”. Unfortunately, this is
not true in the case where authentication fails on that internal index.
In that case, uv will simply try the next index (even on the
`first-index` strategy). This means that uv is not secure by default in
this common scenario.
This PR causes uv to stop searching for a package if it encounters an
authentication failure at an index. It is possible to opt out of this
behavior for an index with a new `pyproject.toml` option
`ignore-error-codes`. For example:
```
[[tool.uv.index]]
name = "my-index"
url = "<index-url>"
ignore-error-codes = [401, 403]
```
This will also enable users to handle idiosyncratic registries in a more
fine-grained way. For example, PyTorch registries return a 403 when a
package is not found. In this PR, we special-case PyTorch registries to
ignore 403s, but users can use `ignore-error-codes` to handle similar
behaviors if they encounter them on internal registries.
Depends on #12651Closes#9429Closes#12362
If you pass a TOML file to `uv pip install` that isn't recognized, we
should just reject it instead of assuming `requirements.txt`. I just
don't see a real case where it's better to let the command proceed.
This is a reimplementation of #7248 with a new CLI interface.
The old `uv version` is now `uv self version` (also it has gained a
`--short` flag for parity).
The new `uv version` is now an interface for getting/setting the project
version.
To give a modicum of support for migration, if `uv version` is run and
we fail to find/read a `pyproject.toml` we will fallback to `uv self
version`. `uv version --project .` prevents this fallback from being
allowed.
The new API of `uv version` is as follows:
* pass nothing to read the project version
* pass a version to set the project version
* `--bump major|minor|patch` to semver-bump the project version
* `--dry-run` to show the result but not apply it
* `--short` to have the final printout contain only the final version
* `--output-format json` to get the final printout as json
```
$ uv version
myfast 0.1.0
$ uv version --bump major --dry-run
myfast 0.1.0 => 1.0.0
$ uv version 1.2.3 --dry-run
myfast 0.1.0 => 1.2.3
$ uv version 1.2.3
myfast 0.1.0 => 1.2.3
$ uv version --short
1.2.3
$ uv version --output-format json
{
"package_name": "myfast",
"version": "1.2.3",
"commit_info": null
}
```
Fixes#6298
Some registries (like Azure Artifact) can require you to authenticate
separately for every package URL if you do not authenticate for the
/simple endpoint. These changes make the auth middleware aware of index
URL endpoints and attempts to fetch keyring credentials for such an
index URL when making a request to any URL it's a prefix of.
The current uv behavior is to cache credentials either at the request
URL or realm level. But with these changes, we also need to cache
credentials at the index level. Note that when uv does not detect an
index URL for a request URL, it will continue to apply the old behavior.
Addresses part of #4056Closes#4583Closes#11236Closes#11391Closes#11507
Closes https://github.com/astral-sh/uv/issues/7804
Includes a few small minor changes to the messaging, but the primary
change is that in, e.g., `uvx foo`, if the `foo` package does not
provide the `foo` executable we will no longer execute an arbitrary
`foo` executable if present on the `PATH`. This prevents confusing and
surprising behavior, such as the user reported where they did `uv tool
install foobar` (which provides `foo`) then `uvx foo` (which does not
provide `foo`) later falls back to the executable provided by `foobar`
since it's on the `PATH`. We don't enforce this for `--from`, so things
like `uvx --from foo bash -c "..."` are still totally valid. We also
still allow `uvx foo` where the `foo` executable is provided by a
_dependency_ of `foo` instead of `foo` itself.
Most of the diff here is consolidating the logic of the
`hint_on_not_found` and `warn_executable_not_provided_by_package `
utilities.
## Summary
If you use `--torch-backend=auto`, we want to avoid selecting (e.g.) a
`+cu124` build of `torch` alongside a `+cu126` build of `torchvision`.
<!--
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 adds `poetry-core` as a build backend choice.
## Test Plan
<!-- How was it tested? -->
---------
Co-authored-by: konstin <konstin@mailbox.org>
## Summary
Part of #8607. This is a pure refactor aimed at paving the way for
supporting the `default-extras` configuration in the `pyproject.toml`
file.
The `ExtraSpecification` struct has been refactored to align more
closely with the
[`DependencyGroups`](256b100a9e/crates/uv-configuration/src/dependency_groups.rs (L9))
struct.
## Test Plan
Existing tests.
## Summary
In https://github.com/astral-sh/uv/pull/12968, we added support for
upload time to `uv.lock`, but stylized as `upload_time`. The other keys
in `uv.lock` use kebab casing, as in common in Python formats, so this
really should've been `upload-time`. I want to change it ASAP to
minimize churn for users. Any users that already upgraded will of course
experience churn in their files a second time. But if we don't change it
now, we'll only increase the surface area of affected users.
So, this PR uses `upload-time` instead, but continues reading
`upload_time` to make it non-breaking.
Part of #11834
Currently, all Python installation are a streaming download-and-extract.
With this PR, we add the `UV_PYTHON_CACHE_DIR` variable. When set, the
installation is split into downloading the interpreter into
`UV_PYTHON_CACHE_DIR` and extracting it there from a second step. If the
archive is already present in `UV_PYTHON_CACHE_DIR`, we skip the
download.
The feature can be used to speed up tests and CI. Locally for me, `cargo
test -p uv -- python_install` goes from 43s to 7s (1,7s in release mode)
when setting `UV_PYTHON_CACHE_DIR`. It can also be used for offline
installation of Python interpreter, by copying the archives to a
directory in the offline machine, while the path rewriting is still
performed on the target machine on installation.
This PR restores #13041 and integrates two PRs from @zanieb:
* #13038
* #13040
It also adds tests for relative URI and fragment handling.
Closes#13037.
---------
Co-authored-by: Zanie Blue <contact@zanie.dev>
Just a small PR to add mentions to `pylock.toml` in the CLI manual where
appropriate.
I tried to say "PEP-751 compatible lock files" when appropriate to also
include the case `r"^pylock\.([^.]+)\.toml$"`. Feel free to change that
if you think it's cluttery.
I also tried to include the "single-use" wording when it made sense.
I also have almost never used the `uv pip` interface, so maybe there are
some other minor things to add here and there about the usage of
`pylock.toml` that I missed.
---------
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
When working on #13025 I noticed this message was lacking versions,
which seems frustrating if you're debugging things.
I refactored the general `matches_interpreter` utilities that were added
in https://github.com/astral-sh/uv/pull/12884 into a more purpose-fit
function that returns an `Option` with the versions if there's a
mismatch.
This PR restores the `bogus_redirect` test that was
non-deterministically hanging (reverting #13076).
Mismatched package and distribution names were causing uv to hang prior
to #12917 (which added the `bogus_redirect` test). But with that fix, uv
was only checking for mismatched package names on the main thread (and
not the resolver thread). This allowed for a race condition which would
prevent uv from ever doing the check, triggering the original hang
condition. This PR adds the check to the resolver thread to prevent this
race condition.
When an index performs a bogus redirect or otherwise returns a different
distribution name than expected, uv currently hangs.
In the example case, requesting the simple index page for any package
returns the page for anyio. This mean querying the sniffio version map
returns only anyio entries, and the version maps resolves to an anyio
version. When the resolver makes a query for sniffio and waits for it to
resolve, the main thread finds an anyio and resolves only that in the
wait map, causing the hang.
We fix this by checking the name of the returned distribution against
the name of the requested distribution. For good measure, we add the
same check in `Request::Dist` and `Request::Installed`. For performance
and complexity reasons, we don't perform this check in the version map
itself, but only after a candidate distribution has been selected.
---------
Co-authored-by: Zanie Blue <contact@zanie.dev>
## Summary
Fixes several occurrences of the minor typo “This options” for “This
option.”
<!-- What's the purpose of the change? What does it do, and why? -->
## Test Plan
<!-- How was it tested? -->
Since this is just a typo fix in documentation and comment strings, no
particular testing was conducted.
## Notes
The typo fixes in `crates/uv-cli/src/lib.rs` would affect
`docs/reference/cli.md`. I assumed you might want to just re-generate
the reference documention, but fixing it up manually would look like:
```diff
diff --git a/docs/reference/cli.md b/docs/reference/cli.md
index 338fa0ff9..8851ca2c0 100644
--- a/docs/reference/cli.md
+++ b/docs/reference/cli.md
@@ -355,7 +355,7 @@ uv run [OPTIONS] [COMMAND]
</dd><dt id="uv-run--no-group"><a href="#uv-run--no-group"><code>--no-group</code></a> <i>no-group</i></dt><dd><p>Disable the specified dependency group.</p>
-<p>This options always takes precedence over default groups, <code>--all-groups</code>, and <code>--group</code>.</p>
+<p>This option always takes precedence over default groups, <code>--all-groups</code>, and <code>--group</code>.</p>
<p>May be provided multiple times.</p>
@@ -1757,7 +1757,7 @@ uv sync [OPTIONS]
</dd><dt id="uv-sync--no-group"><a href="#uv-sync--no-group"><code>--no-group</code></a> <i>no-group</i></dt><dd><p>Disable the specified dependency group.</p>
-<p>This options always takes precedence over default groups, <code>--all-groups</code>, and <code>--group</code>.</p>
+<p>This option always takes precedence over default groups, <code>--all-groups</code>, and <code>--group</code>.</p>
<p>May be provided multiple times.</p>
@@ -2492,7 +2492,7 @@ uv export [OPTIONS]
</dd><dt id="uv-export--no-group"><a href="#uv-export--no-group"><code>--no-group</code></a> <i>no-group</i></dt><dd><p>Disable the specified dependency group.</p>
-<p>This options always takes precedence over default groups, <code>--all-groups</code>, and <code>--group</code>.</p>
+<p>This option always takes precedence over default groups, <code>--all-groups</code>, and <code>--group</code>.</p>
<p>May be provided multiple times.</p>
@@ -2855,7 +2855,7 @@ uv tree [OPTIONS]
</dd><dt id="uv-tree--no-group"><a href="#uv-tree--no-group"><code>--no-group</code></a> <i>no-group</i></dt><dd><p>Disable the specified dependency group.</p>
-<p>This options always takes precedence over default groups, <code>--all-groups</code>, and <code>--group</code>.</p>
+<p>This option always takes precedence over default groups, <code>--all-groups</code>, and <code>--group</code>.</p>
<p>May be provided multiple times.</p>
```
<!--
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
Provide an in-code switch to permit using the `uv build-backend` command
rather than the default `uv-build` in the Python PEP517 backend. This
option is intended to be used by downstream packagers to provide an
option of reusing `uv` that was built already instead of having to build
a second `uv-build` executable that largely overlaps with `uv`.
Fixes#12389
## Test Plan
The option is intended for downstream consumption only, and it is tested
downstream (via attempting to build a package using the `uv_build`
backend). The backend itself is covered by tests already.
---------
Co-authored-by: konstin <konstin@mailbox.org>
## Summary
We accept `pylock.toml` as a requirements file (e.g., `uv sync
pylock.toml` or `uv pip install -r pylock.toml`). When you provide a
`pylock.toml` file, we don't allow you to provide other requirements, or
constraints, etc. And you can only provide one `pylock.toml` file, not
multiple.
We might want to remove this from `uv pip install` for now, since `pip`
may end up with a different interface (whereas `uv pip sync` is already
specific to uv), and most of the arguments aren't applicable (like
`--resolution`, etc.). Regardless, it's behind `--preview` for both
commands.
## Summary
This PR adds `uv export` support for [PEP
751](https://peps.python.org/pep-0751). We don't yet expose a way to
consume the generated lockfile, but it's a first step.
The logic to go from `uv.lock` to "flat set of packages to include, with
markers telling us when to include them" is all shared with the
`requirements.txt` export (and extracted in
https://github.com/astral-sh/uv/pull/12956). So most of the code is just
converting from our internal types to the PEP 751 schema.
As I suspected quite some time ago
(https://github.com/astral-sh/uv/pull/6738#issuecomment-2315466033),
it's problematic that we don't handle _every_ signal here. This PR adds
handling for all of the Unix signals except `SIGCHLD`, `SIGIO`, and
`SIGPOLL` which seem incorrect to forward. Also notable, we _cannot_
handle `SIGKILL` so if someone sends that to the PID instead of the
PGID, they will leave dangling subprocesses.
Instead, we could use `exec` and avoid this handling. However, we'd lose
the ability to add nice error message on failure (e.g., as someone is
trying to add in https://github.com/astral-sh/uv/pull/12201) and, more
critically, we'd need to figure out how to clean up resources properly
(i.e., temporary directories) which currently happens on `Drop`. In the
long-term, we'll probably want an option to use `exec` — but we'll need
to figure out when to clean up resources or accept that they will
dangle. This was last discussed in
https://github.com/astral-sh/uv/issues/3095 — discussion on that
approach should continue there.
A note on the implementation: I spent time time trying to write the
handler using a tokio stream, so we could dynamically iterate over a
list of signals instead of copy/pasting the implementation — I couldn't
get it to work though and it didn't seem critical.
Closes https://github.com/astral-sh/uv/issues/12830
## Summary
Before:
```console
$ uv python list py --managed-python
error: Interpreter discovery for `executable name `py`` requires `search path` but only only managed is allowed
```
After:
```console
$ uv python list py --managed-python
error: Interpreter discovery for `executable name `py`` requires `search path` but only `only managed` is allowed
```
Closes: #4567
## Summary
When adding a package with Git reference options (`--rev`, `--tag`,
`--branch`) that already has a Git source defined, use the existing Git
URL with the new reference instead of reporting an error.
This allows commands like `uv add requests --branch main` to work when
requests is already defined with a Git source in the project
configuration.
Previously, you would need to provide the whole Git url again for this
to work:
```bash
uv add git+https://github.com/psf/requests --branch main
```
<!-- What's the purpose of the change? What does it do, and why? -->
## Test Plan
- [x] Add unit tests for project
- [x] Add unit tests for script
- [x] Tested locally for project and script environments like below
### Testing Project
In a directory using the `uv` executable from this PR (via replacing
every `uv` with `cargo run --`) initialize a project and virtual
environment
```bash
uv init
uv venv
```
move into the environment
```bash
# on mac
source .venv/bin/activate
```
and add a dependency with a git url
```bash
uv add git+https://github.com/Textualize/rich --branch master
```
Then change the branch of the project to see that the branch can be
changed without need of the whole git url:
```bash
uv add rich --branch py310
```
### Testing Script
Create the following file, e.g. `script.py`:
```python
import time
from rich.progress import track
print("Starting")
for i in track(range(20), description="For example:"):
time.sleep(0.05)
print("Done")
```
Now using `uv` (referencing the executable of this PR) add the
dependency
```bash
uv add --script script.py 'git+https://github.com/Textualize/rich' --branch master
```
and check we can execute the script:
```bash
uv run script.py
```
To test the change update the branch
```bash
uv add --script script.py rich --branch py310
```
and check that the dependency is updated and the script is executed:
```bash
uv run script.py
```
<!-- How was it tested? -->
----
This is my first time contributing to `uv` (yay, 🤗) so let me know if
there is something obvious i am missing.
Unit tests will follow soon.
---------
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
## Summary
This is included in PEP 751, so we lose it when converting from
`uv.lock`. I think it's a good piece of information to include in the
`uv.lock` anyway.
I noticed in the trace output that we weren't obfuscating the
`Credentials` password in a trace message. This PR creates a `Password`
newtype with a custom `Debug` implementation.
uv was failing to authenticate on 302 redirects when credentials were
available. This was because it was relying on `reqwest_middleware`'s
default redirect behavior which bypasses the middleware pipeline when
trying the redirect request (and hence bypasses our authentication
middleware). This PR updates uv to retrigger the middleware pipeline
when handling a 302 redirect, correctly using credentials from the URL,
the keyring, or `.netrc`.
Closes#5595Closes#11097
Fixes#12914.
When `PythonDownloadRequest` does not have the `implementation` set, do
not set it to CPython when calling `fill`, otherwise only CPython
interpreters are shown when listing interpreters available for download,
with `uv python list`.
## Summary
This PR simplifies the version formatting by replacing `.white()` with
`.cyan()` styling for consistency.
Resolves#12940
## Test Plan
I manually recreated the code and tested it with this patch:
```diff
diff --git i/crates/uv/src/lib.rs w/crates/uv/src/lib.rs
index b9c01b002..cf051351f 100644
--- i/crates/uv/src/lib.rs
+++ w/crates/uv/src/lib.rs
@@ -1019,6 +1019,20 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
}) => commands::self_update(target_version, token, printer).await,
#[cfg(not(feature = "self-update"))]
Commands::Self_(_) => {
+ eprintln!("{}: {}", "error".cyan().bold(), "fake error message");
+
+ let version_information = format!(
+ "from {} to {}",
+ "v0.1.1".bold().cyan(),
+ "v0.1.2".bold().cyan(),
+ );
+ eprintln!(
+ "{}{} Upgraded uv {}! {}",
+ "success".green().bold(),
+ ":".bold(),
+ version_information,
+ format!("https://github.com/astral-sh/uv/releases/tag/{}", "v0.1.2").cyan()
+ );
anyhow::bail!(
"uv was installed through an external package manager, and self-update \
is not available. Please use your package manager to update uv."
```
In a light terminal, this is what it looks like:
<img width="750" alt="image"
src="https://github.com/user-attachments/assets/dc0d283c-e845-41fb-9821-80b0a3f1c4fe"
/>
Closes#12929
## Summary
Untag the `config-settings` value to support JSON schema according to
the
[docs](https://docs.astral.sh/uv/reference/settings/#config-settings).
```toml
[tool.uv]
config-settings = { editable_mode = "compat" }
```
<!-- What's the purpose of the change? What does it do, and why? -->
## Test Plan
Verified using the "Even Better TOML" extension with paths to old and
new `uv.schema.json`.
## Notes
I could not reproduce the issue with either the `taplo` (on which Even
Better Toml is built, afaik) and `check-jsonschema` CLI tools; with both
old and new versions of the `uv.schema.json` validated the
`pyproject.toml`.
Maybe for these there is some additional regularization going on and
that's also how a breaking case ended up in the docs?
I'm unsure on how to test for this.
After about an hour, the Even better TOML VSCode extension was the only
way to reproduce failing validation.
Let me know if I can do something else.
<!-- How was it tested? -->
Currently, `uv init` works without a `git` executable, and with a
working `git` executable, but not with a broken `git`, be it from GitHub
Action's Windows CI or from the shim we insert.
`uv init` calls git twice: Once `git rev-parse` to check whether a git
repo already exists, and then `git init` (if there is no git repository
yet and no `--vcs none`).
By separately handling the cases where git failed during `git rev-parse`
doesn't work vs. where the is no repository when checking for an
existing repo work tree, we can avoid calling `git init` for broken git
and erroring. We have to hardcode the expected git command outputs to be
able to check.
This is a rebased and updated version of #11925 based on my review (I
didn't have permission to push to their branch).
For posterity I've preserved their commits but my final commit
essentially rewrites the whole thing anyway.
Fixes#11637
---------
Co-authored-by: Chris Lieb <clieb@bitsighttech.com>
"Only show Python downloads, exclude installed distributions." might be
misunderstood as excluding installed distributions from `uv python list
--only-downloads`, implying that versions already installed won’t be
shown.