Clap does not perform global validation, so flag that are declared as
overriding can be set at the same time:
https://github.com/clap-rs/clap/issues/6049. This would previously cause
a panic. We work around this by choosing the yes-value always and
writing a warning.
An alternative would be erroring when both are set, but it's unclear to
me if this may break things we want to support. (`UV_OFFLINE=1 cargo run
-q pip --no-offline install tqdm --no-cache` is already banned).
Fixes https://github.com/astral-sh/uv/pull/14299
**Test Plan**
```
$ cargo run -q pip --offline install --no-offline tqdm --no-cache
warning: Boolean flags on different levels are not correctly supported (https://github.com/clap-rs/clap/issues/6049)
× No solution found when resolving dependencies:
╰─▶ Because tqdm was not found in the cache and you require tqdm, we can conclude that your requirements are unsatisfiable.
hint: Packages were unavailable because the network was disabled. When the network is disabled, registry packages may only be read from the cache.
```
We do not currently support passing index names to `--index` for
installing packages. However, we do accept relative paths that can look
like index names. This PR adds the requirement that `--index` values
must be disambiguated with a prefix (`./` or `../` on Unix and Windows
or `.\\` or `..\\` on Windows). For now, if an ambiguous value is
provided, uv will warn that this will not be supported in the future.
Currently, if you provide an index name like `--index test` when there
is no `test` directory, uv will error with a `Directory not found...`
error. That's not very informative if you thought index names were
supported. The new warning makes the context clearer.
Closes#13921
> NOTE: The PRs that were merged into this feature branch have all been
independently reviewed. But it's also useful to see all of the changes
in their final form. I've added comments to significant changes
throughout the PR to aid discussion.
This PR introduces transparent Python version upgrades to uv, allowing
for a smoother experience when upgrading to new patch versions.
Previously, upgrading Python patch versions required manual updates to
each virtual environment. Now, virtual environments can transparently
upgrade to newer patch versions.
Due to significant changes in how uv installs and executes managed
Python executables, this functionality is initially available behind a
`--preview` flag. Once an installation has been made upgradeable through
`--preview`, subsequent operations (like `uv venv -p 3.10` or patch
upgrades) will work without requiring the flag again. This is
accomplished by checking for the existence of a minor version symlink
directory (or junction on Windows).
### Features
* New `uv python upgrade` command to upgrade installed Python versions
to the latest available patch release:
```
# Upgrade specific minor version
uv python upgrade 3.12 --preview
# Upgrade all installed minor versions
uv python upgrade --preview
```
* Transparent upgrades also occur when installing newer patch versions:
```
uv python install 3.10.8 --preview
# Automatically upgrades existing 3.10 environments
uv python install 3.10.18
```
* Support for transparently upgradeable Python `bin` installations via
`--preview` flag
```
uv python install 3.13 --preview
# Automatically upgrades the `bin` installation if there is a newer patch version available
uv python upgrade 3.13 --preview
```
* Virtual environments can still be tied to a patch version if desired
(ignoring patch upgrades):
```
uv venv -p 3.10.8
```
### Implementation
Transparent upgrades are implemented using:
* Minor version symlink directories (Unix) or junctions (Windows)
* On Windows, trampolines simulate paths with junctions
* Symlink directory naming follows Python build standalone format: e.g.,
`cpython-3.10-macos-aarch64-none`
* Upgrades are scoped to the minor version key (as represented in the
naming format: implementation-minor version+variant-os-arch-libc)
* If the context does not provide a patch version request and the
interpreter is from a managed CPython installation, the `Interpreter`
used by `uv python run` will use the full symlink directory executable
path when available, enabling transparently upgradeable environments
created with the `venv` module (`uv run python -m venv`)
New types:
* `PythonMinorVersionLink`: in a sense, the core type for this PR, this
is a representation of a minor version symlink directory (or junction on
Windows) that points to the highest installed managed CPython patch
version for a minor version key.
* `PythonInstallationMinorVersionKey`: provides a view into a
`PythonInstallationKey` that excludes the patch and prerelease. This is
used for grouping installations by minor version key (e.g., to find the
highest available patch installation for that minor version key) and for
minor version directory naming.
### Compatibility
* Supports virtual environments created with:
* `uv venv`
* `uv run python -m venv` (using managed Python that was installed or
upgraded with `--preview`)
* Virtual environments created within these environments
* Existing virtual environments from before these changes continue to
work but aren't transparently upgradeable without being recreated
* Supports both standard Python (`python3.10`) and freethreaded Python
(`python3.10t`)
* Support for transparently upgrades is currently only available for
managed CPython installations
Closes#7287Closes#7325Closes#7892Closes#9031Closes#12977
---------
Co-authored-by: Zanie Blue <contact@zanie.dev>
We always ignore the `clippy::struct_excessive_bools` rule and formerly
annotated this at the function level. This PR specifies the allow in
`workspace.lints.clippy` in `Cargo.toml`.
## Summary
Implemented as suggested in #13761
eg.
```
$ uv tool install 'harlequin[postgres]'
$ uv tool list --show-extras
harlequin v2.1.2 [extras: postgres]
- harlequin
```
## Test Plan
Added a new test with the argument along with the others from the `uv
tool list` cli.
By default, uv uses only a lower bound in `uv add`, which avoids
dependency conflicts due to upper bounds. With this PR, this cna be
changed by setting a different bound kind. The bound kind can be
configured in `uv.toml`, as a user preference, in `pyproject.toml`, as a
project preference, or on the CLI, when adding a specific project.
We add two options that add an upper bound on the constraint, one for
SemVer (`>=1.2.3,<2.0.0`, dubbed "major", modeled after the SemVer
caret) and another one for dependencies that make breaking changes in
minor version (`>=1.2.3,<1.3.0`, dubbed "minor", modeled after the
SemVer tilde). Intuitively, the major option bumps the most significant
version component, while the minor option bumps the second most
significant version component. There is also an exact bounds option
(`==1.2.3`), though generally we recommend setting a wider bound and
using the lockfile for pinning.
Versions can have leading zeroes, such as `0.1` or `0.0.1`. For a single
leading 0, we shift the the meaning of major and minor similar to cargo.
For two or more leading zeroes, the difference between major and minor
becomes inapplicable, instead both bump the most significant component:
- major: `0.1` -> `>=0.1,<0.2`
- major: `0.0.1` -> `>=0.0.1,<0.0.2`
- major: `0.0.1.1` -> `>=0.0.1.1,<0.0.2.0`
- major: `0.0.0.1` -> `>=0.0.0.1,<0.0.0.2`
- minor: `0.1` -> `>=0.1,<0.1.1`
- minor: `0.0.1` -> `>=0.0.1,<0.0.2`
- minor: `0.0.1.1` -> `>=0.0.1.1,<0.0.2.0`
- minor: `0.0.0.1` -> `>=0.0.0.1,<0.0.0.2`
For a consistent appearance, we try to preserve the number of components
in the upper bound. For example, adding a version `2.17` with the major
option is stored as `>=2.17,<3.0`. If a version uses three components
and is greater than 0, both bounds will also use three components
(SemVer versions always have three components). Of the top 100 PyPI
packages, 8 use a non-three-component version (docutils, idna, pycparser
and soupsieve with two components, packaging, pytz and tzdata with two
component, CalVer and trove-classifiers with four component CalVer).
Example `pyproject.toml` files with the top 100 packages: [`--bounds
major`](https://gist.github.com/konstin/0aaffa9ea53c4834c22759e8865409f4)
and [`--bounds
minor`](https://gist.github.com/konstin/e77f5e990a7efe8a3c8a97c5c5b76964).
While many projects follow version scheme that roughly or directly
matches the major or minor options, these compatibility ranges are
usually not applicable for the also popular CalVer versioning.
For pre-release versions, there are two framings we could take: One is
that pre-releases generally make no guarantees about compatibility
between them and are used to introduce breaking changes, so we should
pin them exactly. In many cases however, pre-release specifiers are used
because a project needs a bugfix or a feature that hasn't made it into a
stable release, or because a project is compatible with the next version
before a final version for that release is published. In those cases,
compatibility with other packages that depend on the same library is
more important, so the desired bound is the same as it would be for the
stable release, except with the lower bound lowered to include
pre-release.
The names of the bounds and the name of the flag is up for bikeshedding.
Currently, the option is call `tool.uv.bounds`, but we could also move
it under `tool.uv.edit.bounds`, where it would be the first/only entry.
Fixes#6783
---------
Co-authored-by: Zanie Blue <contact@zanie.dev>
Prior to this PR, there were numerous places where uv would leak
credentials in logs. We had a way to mask credentials by calling methods
or a recently-added `redact_url` function, but this was not secure by
default. There were a number of other types (like `GitUrl`) that would
leak credentials on display.
This PR adds a `DisplaySafeUrl` newtype to prevent leaking credentials
when logging by default. It takes a maximalist approach, replacing the
use of `Url` almost everywhere. This includes when first parsing config
files, when storing URLs in types like `GitUrl`, and also when storing
URLs in types that in practice will never contain credentials (like
`DirectorySourceUrl`). The idea is to make it easy for developers to do
the right thing and for the compiler to support this (and to minimize
ever having to manually convert back and forth). Displaying credentials
now requires an active step. Note that despite this maximalist approach,
the use of the newtype should be zero cost.
One conspicuous place this PR does not use `DisplaySafeUrl` is in the
`uv-auth` crate. That would require new clones since there are calls to
`request.url()` that return a `&Url`. One option would have been to make
`DisplaySafeUrl` wrap a `Cow`, but this would lead to lifetime
annotations all over the codebase. I've created a separate PR based on
this one (#13576) that updates `uv-auth` to use `DisplaySafeUrl` with
one new clone. We can discuss the tradeoffs there.
Most of this PR just replaces `Url` with `DisplaySafeUrl`. The core is
`uv_redacted/lib.rs`, where the newtype is implemented. To make it
easier to review the rest, here are some points of note:
* `DisplaySafeUrl` has a `Display` implementation that masks
credentials. Currently, it will still display the username when there is
both a username and password. If we think is the wrong choice, it can
now be changed in one place.
* `DisplaySafeUrl` has a `remove_credentials()` method and also a
`.to_string_with_credentials()` method. This allows us to use it in a
variety of scenarios.
* `IndexUrl::redacted()` was renamed to
`IndexUrl::removed_credentials()` to make it clearer that we are not
masking.
* We convert from a `DisplaySafeUrl` to a `Url` when calling `reqwest`
methods like `.get()` and `.head()`.
* We convert from a `DisplaySafeUrl` to a `Url` when creating a
`uv_auth::Index`. That is because, as mentioned above, I will be
updating the `uv_auth` crate to use this newtype in a separate PR.
* A number of tests (e.g., in `pip_install.rs`) that formerly used
filters to mask tokens in the test output no longer need those filters
since tokens in URLs are now masked automatically.
* The one place we are still knowingly writing credentials to
`pyproject.toml` is when a URL with credentials is passed to `uv add`
with `--raw`. Since displaying credentials is no longer automatic, I
have added a `to_string_with_credentials()` method to the `Pep508Url`
trait. This is used when `--raw` is passed. Adding it to that trait is a
bit weird, but it's the simplest way to achieve the goal. I'm open to
suggestions on how to improve this, but note that because of the way
we're using generic bounds, it's not as simple as just creating a
separate trait for that method.
This adopts the logic from `uv remove` for locking and syncing, as the
scope of the changes made are ultimately similar. Unlike `uv remove`
there is no support for modifying PEP723 scripts, as these are not
versioned.
In doing this the `version` command gains a truckload of args for
configuring lock/sync behaviour. Presumably most of these are passed via
settings or env files, and not of particular concern.
The most interesting additions are:
* `--frozen`: makes `uv version` work ~exactly as it did before this PR
* `--locked`: errors if the lockfile is out of date
* `--no-sync`: updates the lockfile, but doesn't run the equivalent of
`uv sync`
* `--package name`: a convenience for referring to a package in the
workspace
Note that the existing `--dry-run` flag effectively implies `--frozen` for sets and bumps.
Fixes#13254Fixes#13548
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.
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
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.
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 #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? -->
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
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>
## 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>
```
## 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.
"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.
## Summary
Closes#12687.
<!-- What's the purpose of the change? What does it do, and why? -->
## Test Plan
<!-- How was it tested? -->
Added the corresponding integration tests for:
- `uv sync --dry-run --locked`
- [x] Preview lock changes
- [x] Errors if lockfile is out-of-date
- `uv sync --dry-run --frozen`
- [x] Preview lock changes
---------
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
## Summary
Closes#12806
Split `UV_INDEX` by any whitespace rather than only ASCII 32, which does
not align with the behavior of `PIP_EXTRA_INDEX_URL` and can possibly
lead to difficulties when migrating from pip to uv.
Clap unfortunately does not support passing multiple delimiters, writing
a custom parsing function involved parsing index into a Vec<Vec<Index>>
and flattening it afterwards in order to avoid breaking the --index
command line option.
There might be a prettier solution I overlooked, let me know if there is
anything I should change!
<!--
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? -->
Adds the env arg `UV_NO_EDITABLE`.
Closes#12735
## Test Plan
<!-- How was it tested? -->

I could not find a place where to add tests, any help would be
appreciated
---------
Co-authored-by: Aria Desires <aria.desires@gmail.com>
@jtfmumm mentioned a desire for this. I'm not sure how we should do
this. I kind of want to change this to something like...
```
$ uv python find
CPython 3.13 @ <path>
$ uv python find --only-path
<path>
$ uv python find --short
<path>
$ uv python find --only-version
3.13
```
The change in defaults would be breaking though.
uv has a global `--no-config` option, which indeed has an effect.
## Test Plan
```console
❯ cat pyproject.toml
[project]
name = "hello"
version = "0.1.0"
[[tool.uv.index]]
url = "http://non-exist-host.com/simple"
default = true
❯ echo requests | uv pip compile -
⠦ Resolving dependencies... error: Failed to fetch: `http://non-exist-host.com/simple/requests/`
Caused by: Could not connect, are you offline?
Caused by: Request failed after 3 retries
Caused by: error sending request for url (http://non-exist-host.com/simple/requests/)
Caused by: client error (Connect)
Caused by: dns error: failed to lookup address information: nodename nor servname provided, or not known
Caused by: failed to lookup address information: nodename nor servname provided, or not known
# Before
❯ echo requests | uv pip compile --no-config -
warning: pip-compile's `--no-config` has no effect (uv does not use a configuration file)
Resolved 5 packages in 13ms
# This file was autogenerated by uv via the following command:
# uv pip compile --no-config -
certifi==2025.1.31
# via requests
charset-normalizer==3.4.1
# via requests
idna==3.10
# via requests
requests==2.32.3
urllib3==2.3.0
# via requests
# After
❯ echo requests | uv pip compile --no-config -
Resolved 5 packages in 13ms
# This file was autogenerated by uv via the following command:
# uv pip compile --no-config -
certifi==2025.1.31
# via requests
charset-normalizer==3.4.1
# via requests
idna==3.10
# via requests
requests==2.32.3
urllib3==2.3.0
# via requests
```
## Summary
<!-- What's the purpose of the change? What does it do, and why? -->
Support the `UV_PROJECT` environment variable to set the project
directory.
#11946
## Test Plan
<!-- How was it tested? -->
`cargo nextest run` passed except the cache_prune.
```
export UV_PROJECT=/path/to/project
uv sync
```
works.
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
Adding dependency trace/parent comments ("via ...") to the export
command output.
This is a similar behavior to the pip compile output.
#### Note to the eager reviewer:
First of all - thanks!
Secondly, this is still a very rough draft. These are the first lines of
code I've ever written in Rust. This is still mostly an educational/fun
exercise for myself. If opening a Draft PR is creating too much noise -
I apologize and I will close it until it is ready.
## Summary
Resolves#7777
## Test Plan
- [X] manual command execution
- [x] update expected output in tests
---------
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
The idea here is that we introduce a new stdout_important method for
things that want to care about the difference between "quiet" and
"silent".
This PR is WIP because it has no actual uses of stdout_important, and we
should have at least one before landing this. Perhaps someone has a
suggestion for commands that would really benefit from this distinction?
Fixes#10431
## Summary
This fixes https://github.com/astral-sh/uv/issues/12426 which helps use
a more accurate arg name in the help output.
## Test Plan
I didn't test it locally, @charliermarsh gave me guidance on what to
change so I looked around that file for another example of `value_name`
and repeated what I saw. I kept it formatted to 1 line based on it not
being a long line. The other example of `value_name` had everything on
separate lines because there were a bunch of parameters passed in.
---------
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
Allows `uv python list <request>` to filter the installed list. I often
want this and it's not hard to add.
I tested the remote download filtering locally (#12381 is needed for
snapshot tests)
```
❯ cargo run -q -- python list --all-versions 3.13
cpython-3.13.2-macos-aarch64-none <download available>
cpython-3.13.1-macos-aarch64-none /opt/homebrew/opt/python@3.13/bin/python3.13 -> ../Frameworks/Python.framework/Versions/3.13/bin/python3.13
cpython-3.13.1-macos-aarch64-none <download available>
cpython-3.13.0-macos-aarch64-none /Users/zb/.local/share/uv/python/cpython-3.13.0-macos-aarch64-none/bin/python3.13
❯ cargo run -q -- python list --all-versions 3.13 --only-installed
cpython-3.13.1-macos-aarch64-none /opt/homebrew/opt/python@3.13/bin/python3.13 -> ../Frameworks/Python.framework/Versions/3.13/bin/python3.13
cpython-3.13.0-macos-aarch64-none /Users/zb/.local/share/uv/python/cpython-3.13.0-macos-aarch64-none/bin/python3.13
```
## Summary
Resolves#11794.
When `uv python find` is given a `--script` option, either the existing
environment for that script or the Python executable that would be used
to create it will be returned. If neither are found, the command exits
with exit code 1.
`--script` is incompatible with all other options to the same command.
## Test Plan
Unit tests.
There was a bug where `UV_MANAGED_PYTHON` and `UV_NO_MANAGED_PYTHON`
only accepted `true` or `false`. This switches to the boolish value
parser for those flags.
Closes#12336
## Summary
This is a prototype that I'm considering shipping under `--preview`,
based on [`light-the-torch`](https://github.com/pmeier/light-the-torch).
`light-the-torch` patches pip to pull PyTorch packages from the PyTorch
indexes automatically. And, in particular, `light-the-torch` will query
the installed CUDA drivers to determine which indexes are compatible
with your system.
This PR implements equivalent behavior under `--torch-backend auto`,
though you can also set `--torch-backend cpu`, etc. for convenience.
When enabled, the registry client will fetch from the appropriate
PyTorch index when it sees a package from the PyTorch ecosystem (and
ignore any other configured indexes, _unless_ the package is explicitly
pinned to a different index).
Right now, this is only implemented in the `uv pip` CLI, since it
doesn't quite fit into the lockfile APIs given that it relies on feature
detection on the currently-running machine.
## Test Plan
On macOS, you can test this with (e.g.):
```shell
UV_TORCH_BACKEND=auto UV_CUDA_DRIVER_VERSION=450.80.2 cargo run \
pip install torch --python-platform linux --python-version 3.12
```
On a GPU-enabled EC2 machine:
```shell
ubuntu@ip-172-31-47-149:~/uv$ UV_TORCH_BACKEND=auto cargo run pip install torch -v
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.31s
Running `target/debug/uv pip install torch -v`
DEBUG uv 0.6.6 (e95ca063b 2025-03-14)
DEBUG Searching for default Python interpreter in virtual environments
DEBUG Found `cpython-3.13.0-linux-x86_64-gnu` at `/home/ubuntu/uv/.venv/bin/python3` (virtual environment)
DEBUG Using Python 3.13.0 environment at: .venv
DEBUG Acquired lock for `.venv`
DEBUG At least one requirement is not satisfied: torch
warning: The `--torch-backend` setting is experimental and may change without warning. Pass `--preview` to disable this warning.
DEBUG Detected CUDA driver version from `/sys/module/nvidia/version`: 550.144.3
...
```