Commit Graph

148 Commits

Author SHA1 Message Date
Charlie Marsh 66211cb028 Use more precise error messages for preparation failures 2024-10-16 22:08:45 -04:00
Charlie Marsh 5b391770df Add support for named and explicit indexes (#7481)
## Summary

This PR adds a first-class API for defining registry indexes, beyond our
existing `--index-url` and `--extra-index-url` setup.

Specifically, you now define indexes like so in a `uv.toml` or
`pyproject.toml` file:

```toml
[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cu121"
```

You can also provide indexes via `--index` and `UV_INDEX`, and override
the default index with `--default-index` and `UV_DEFAULT_INDEX`.

### Index priority

Indexes are prioritized in the order in which they're defined, such that
the first-defined index has highest priority.

Indexes are also inherited from parent configuration (e.g., the
user-level `uv.toml`), but are placed after any indexes in the current
project, matching our semantics for other array-based configuration
values.

You can mix `--index` and `--default-index` with the legacy
`--index-url` and `--extra-index-url` settings; the latter two are
merely treated as unnamed `[[tool.uv.index]]` entries.

### Index pinning

If an index includes a name (which is optional), it can then be
referenced via `tool.uv.sources`:

```toml
[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cu121"

[tool.uv.sources]
torch = { index = "pytorch" }
```

If an index is marked as `explicit = true`, it can _only_ be used via
such references, and will never be searched implicitly:

```toml
[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cu121"
explicit = true

[tool.uv.sources]
torch = { index = "pytorch" }
```

Indexes defined outside of the current project (e.g., in the user-level
`uv.toml`) can _not_ be explicitly selected.

(As of now, we only support using a single index for a given
`tool.uv.sources` definition.)

### Default index

By default, we include PyPI as the default index. This remains true even
if the user defines a `[[tool.uv.index]]` -- PyPI is still used as a
fallback. You can mark an index as `default = true` to (1) disable the
use of PyPI, and (2) bump it to the bottom of the prioritized list, such
that it's used only if a package does not exist on a prior index:

```toml
[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cu121"
default = true
```

### Name reuse

If a name is reused, the higher-priority index with that name is used,
while the lower-priority indexes are ignored entirely.

For example, given:

```toml
[[tool.uv.index]]
name = "pytorch"
url = "https://download.pytorch.org/whl/cu121"

[[tool.uv.index]]
name = "pytorch"
url = "https://test.pypi.org/simple"
```

The `https://test.pypi.org/simple` index would be ignored entirely,
since it's lower-priority than `https://download.pytorch.org/whl/cu121`
but shares the same name.

Closes #171.

## Future work

- Users should be able to provide authentication for named indexes via
environment variables.
- `uv add` should automatically write `--index` entries to the
`pyproject.toml` file.
- Users should be able to provide multiple indexes for a given package,
stratified by platform:
```toml
[tool.uv.sources]
torch = [
  { index = "cpu", markers = "sys_platform == 'darwin'" },
  { index = "gpu", markers = "sys_platform != 'darwin'" },
]
```
- Users should be able to specify a proxy URL for a given index, to
avoid writing user-specific URLs to a lockfile:
```toml
[[tool.uv.index]]
name = "test"
url = "https://private.org/simple"
proxy = "http://<omitted>/pypi/simple"
```
2024-10-15 18:24:23 -04:00
samypr100 01c44af3c3 chore: unify all env vars used (#8151)
## Summary

This PR declares and documents all environment variables that are used
in one way or another in `uv`, either internally, or externally, or
transitively under a common struct.

I think over time as uv has grown there's been many environment
variables introduced. Its harder to know which ones exists, which ones
are missing, what they're used for, or where are they used across the
code. The docs only documents a handful of them, for others you'd have
to dive into the code and inspect across crates to know which crates
they're used on or where they're relevant.

This PR is a starting attempt to unify them, make it easier to discover
which ones we have, and maybe unlock future posibilities in automating
generating documentation for them.

I think we can split out into multiple structs later to better organize,
but given the high influx of PR's and possibly new environment variables
introduced/re-used, it would be hard to try to organize them all now
into their proper namespaced struct while this is all happening given
merge conflicts and/or keeping up to date.

I don't think this has any impact on performance as they all should
still be inlined, although it may affect local build times on changes to
the environment vars as more crates would likely need a rebuild. Lastly,
some of them are declared but not used in the code, for example those in
`build.rs`. I left them declared because I still think it's useful to at
least have a reference.

Did I miss any? Are their initial docs cohesive?

Note, `uv-static` is a terrible name for a new crate, thoughts? Others
considered `uv-vars`, `uv-consts`.

## Test Plan

Existing tests
2024-10-14 16:48:13 -05:00
Amos Wenger 715f28fd39 chore: Move all integration tests to a single binary (#8093)
As per
https://matklad.github.io/2021/02/27/delete-cargo-integration-tests.html

Before that, there were 91 separate integration tests binary.

(As discussed on Discord — I've done the `uv` crate, there's still a few
more commits coming before this is mergeable, and I want to see how it
performs in CI and locally).
2024-10-11 16:41:35 +02:00
Charlie Marsh f0659e76cf Rename install-wheel-rs library (#7855)
## Summary

I missed this one in the rename (the crate was renamed, but not the
library).
2024-10-01 20:45:39 -04:00
Charlie Marsh 14507a1793 Add uv- prefix to all internal crates (#7853)
## Summary

Brings more consistency to the repo and ensures that all crates
automatically show up in `--verbose` logging.
2024-10-01 20:15:32 -04:00
Charlie Marsh b6ce39f45e Remove lossy resolution-to-requirements conversion in install plan (#7798)
## Summary

This is a longstanding piece of technical debt. After we resolve, we
have a bunch of `ResolvedDist` entries. We then convert those to
`Requirement` (which is lossy -- we lose information like "the index
that the package was resolved to"), and then back to `Dist`.
2024-09-30 10:13:09 -04:00
Charlie Marsh 66d7ec541a Avoid reusing cached downloaded binaries with --no-binary (#7772)
## Summary

Historically, we've allowed the use of wheels that were downloaded from
PyPI even when the user passes `--no-binary`, if the wheel exists in the
cache. This PR modifies the cache lookup code such that we respect
`--no-build` and `--no-binary` in those paths.

Closes https://github.com/astral-sh/uv/issues/2154.
2024-09-29 17:34:52 +00:00
Charlie Marsh f895c40a4e Avoid removing seed packages for uv venv --seed environments (#7410)
## Summary

Closes https://github.com/astral-sh/uv/issues/7121.
2024-09-15 22:27:52 +00:00
Charlie Marsh a8bd0211e0 Invalidate cache when --config-settings change (#7139)
## Summary

If `--config-settings` are provided, we cache the built wheels under one
more subdirectory.

We _don't_ invalidate the actual source (i.e., trigger a re-download) or
metadata, though -- those can be reused even when `--config-settings`
change.

Closes https://github.com/astral-sh/uv/issues/7028.
2024-09-10 01:49:16 +00:00
Charlie Marsh 4f2349119c Add support for dynamic cache keys (#7136)
## Summary

This PR adds a more flexible cache invalidation abstraction for uv, and
uses that new abstraction to improve support for dynamic metadata.

Specifically, instead of relying solely on a timestamp, we now pass
around a `CacheInfo` struct which (as of now) contains
`Option<Timestamp>` and `Option<Commit>`. The `CacheInfo` is saved in
`dist-info` as `uv_cache.json`, so we can test already-installed
distributions for cache validity (along with testing _cached_
distributions for cache validity).

Beyond the defaults (`pyproject.toml`, `setup.py`, and `setup.cfg`
changes), users can also specify additional cache keys, and it's easy
for us to extend support in the future. Right now, cache keys can either
be instructions to include the current commit (for `setuptools_scm` and
similar) or file paths (for `hatch-requirements-txt` and similar):

```toml
[tool.uv]
cache-keys = [{ file = "requirements.txt" }, { git = true }]
```

This change should be fully backwards compatible.

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

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

Closes https://github.com/astral-sh/uv/issues/6860.
2024-09-09 20:19:15 +00:00
Charlie Marsh bb61513952 Respect hashes in constraints files (#7093)
## Summary

Like pip, if hashes are present on both the requirement and the
constraint, we prefer the requirement.

Closes #7089.
2024-09-05 14:30:10 -04:00
Michal Čihař 01f4beeafe Differentiate startup and compile timeouts (#6958)
<!--
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

Separate exceptions for different timeouts to make it easier to debug
issues like #6105.

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

## Test Plan

<!-- How was it tested? -->
Not tested at all.
2024-09-03 10:32:43 +02:00
Charlie Marsh 56cc0c9b3c Avoid using editable tag in lockfile for non-package dependencies (#6728)
## Summary

Use a dedicated source type for non-package requirements. Also enables
us to support non-package `path` dependencies _and_ removes the need to
have the member `pyproject.toml` files available when we sync _and_
makes it explicit which dependencies are virtual vs. not (as evidenced
by the snapshot changes). All good things!
2024-08-28 01:19:05 +00:00
Charlie Marsh 51723a2699 Ignore send errors in installer (#6667)
## Summary

Similar to https://github.com/astral-sh/uv/pull/6182.
2024-08-27 12:59:17 +00:00
Charlie Marsh a7850d2a1c Use separate types to represent raw vs. resolver markers (#6646)
## Summary

This is similar to https://github.com/astral-sh/uv/pull/6171 but more
expansive... _Anywhere_ that we test requirements for platform
compatibility, we _need_ to respect the resolver-friendly markers. In
fixing the motivating issue (#6621), I also realized that we had a bunch
of bugs here around `pip install` with `--python-platform` and
`--python-version`, because we always performed our `satisfy` and `Plan`
operations on the interpreter's markers, not the adjusted markers!

Closes https://github.com/astral-sh/uv/issues/6621.
2024-08-26 18:00:21 +00:00
Charlie Marsh f7835243c5 Only use relative paths in lockfile (#6490)
For users who were using absolute paths in the `pyproject.toml`
previously, this is a behavior change: We now convert all absolute paths
in `path` entries to relative paths. Since i assume that no-one relies
on absolute path in their lockfiles - they are intended to be portable -
I'm tagging this as a bugfix.

Closes https://github.com/astral-sh/uv/pull/6438
Fixes https://github.com/astral-sh/uv/issues/6371
2024-08-23 22:19:10 -04:00
Charlie Marsh 611a9003c9 Don't canonicalize paths to user requirements (#6560) 2024-08-24 02:02:14 +00:00
Charlie Marsh 19ac9af167 Use consistent canonicalization for URLs (#5980)
Right now, the URL gets out-of-sync with the install path, since the
install path is canonicalized. This leads to a subtle error on Windows
(in CI) in which we don't preserve caching across resolution and
installation.
2024-08-09 21:43:36 -04:00
konsti fcbee9ce25 Support relative path wheels (#5969)
Surprisingly, this is a lockfile schema change: We can't store relative
paths in urls, so we have to store a `filename` entry instead of the
whole url.

Fixes #4355
2024-08-09 21:57:16 +00:00
Charlie Marsh 21408c1f35 Enforce extension validity at parse time (#5888)
## Summary

This PR adds a `DistExtension` field to some of our distribution types,
which requires that we validate that the file type is known and
supported when parsing (rather than when attempting to unzip). It
removes a bunch of extension parsing from the code too, in favor of
doing it once upfront.

Closes https://github.com/astral-sh/uv/issues/5858.
2024-08-08 21:39:47 -04:00
Charlie Marsh e4ec6e4025 Avoid panic when re-locking with precise commit (#5863)
## Summary

Very subtle bug. The scenario is as follows:

- We resolve: `elmer-circuitbuilder = { git =
"https://github.com/ElmerCSC/elmer_circuitbuilder.git" }`

- The user then changes the request to: `elmer-circuitbuilder = { git =
"https://github.com/ElmerCSC/elmer_circuitbuilder.git", rev =
"44d2f4b19d6837ea990c16f494bdf7543d57483d" }`

- When we go to re-lock, we note two facts:

1. The "default branch" resolves to
`44d2f4b19d6837ea990c16f494bdf7543d57483d`.
2. The metadata for `44d2f4b19d6837ea990c16f494bdf7543d57483d` is
(whatever we grab from the lockfile).

- In the resolver, we then ask for the metadata for
`44d2f4b19d6837ea990c16f494bdf7543d57483d`. It's already in the cache,
so we return it; thus, we never add the
`44d2f4b19d6837ea990c16f494bdf7543d57483d` ->
`44d2f4b19d6837ea990c16f494bdf7543d57483d` mapping to the Git resolver,
because we never have to resolve it.

This would apply for any case in which a requested tag or branch was
replaced by its precise SHA. Replacing with a different commit is fine.

It only applied to `tool.uv.sources`, and not PEP 508 URLs, because the
underlying issue is that we aren't consistent about "automatically"
extracting the precise commit from a Git reference.

Closes https://github.com/astral-sh/uv/issues/5860.
2024-08-07 10:56:15 -04:00
Charlie Marsh 9346946c7f Allow downloading wheels for metadata with --no-binary (#5707)
## Summary

We allow the use of (e.g.) `.whl.metadata` files when `--no-binary` is
enabled, so it makes sense that we'd also also allow wheels to be
downloaded for metadata extraction. So now, we validate `--no-binary` at
install time, rather than metadata-fetch time.

Closes https://github.com/astral-sh/uv/issues/5699.
2024-08-06 18:14:12 +00:00
Charlie Marsh c5052bc36c Respect malformed .dist-info directories in tool installs (#5756)
## Summary

Closes https://github.com/astral-sh/uv/issues/5749.
2024-08-03 19:43:03 -04:00
Charlie Marsh 51b7e9bff1 Retain editable designation for cached wheel installs (#5545)
## Summary

The package was being installed as editable, but it wasn't marked as
such in `uv pip list`, as the `direct-url.json` was wrong.

Closes https://github.com/astral-sh/uv/issues/5543.
2024-07-28 22:39:48 -04:00
Charlie Marsh 9af0ae2bef Add relocatable installs to support concurrency-safe cached environments (#5509)
## Summary

The idea here is similar to what we do for wheels: we create the
`CachedEnvironment` in the `archive-v0` bucket, then symlink it to its
content-addressed location. This ensures that we can always recreate
these environments without concern for whether anyone else is accessing
them.

Part of the challenge here is that we want the virtual environments to
be relocatable, because we're now building them in one location but
persisting them in another. This requires that we write relative (rather
than absolute) paths to scripts and entrypoints. The main risk with
relocatable virtual environments is that the scripts and entrypoints
_themselves_ are not relocatable, because they use a relative shebang.
But that's fine for cached environments, which are never intended to
leave the cache.

Closes https://github.com/astral-sh/uv/issues/5503.
2024-07-28 20:32:11 -04:00
Pavel Dikov cb47aed9de feat(venv): add relocatable flag (#5515)
## Summary

Adds a `--relocatable` CLI arg to `uv venv`. This flag does two things:

* ensures that the associated activation scripts do not rely on a
hardcoded
absolute path to the virtual environment (to the extent possible; `.csh`
and
  `.nu` left as-is)
* persists a `relocatable` flag in `pyvenv.cfg`.

The flag in `pyvenv.cfg` in turn instructs the wheel `Installer` to
create script
entrypoints in a relocatable way (use `exec` trick + `dirname $0` on
POSIX;
use relative path to `python[w].exe` on Windows).

Fixes: #3863

## Test Plan

* Relocatable console scripts covered as additional scenarios in
existing test cases.
* Integration testing of boilerplate generation in `venv`.
* Manual testing of `uv venv` with and without `--relocatable`
2024-07-29 00:10:11 +00:00
Charlie Marsh 83412837e5 Warn, but don't error, when encountering tilde .dist-info directories (#5520)
## Summary

Closes https://github.com/astral-sh/uv/issues/3668.
2024-07-28 19:13:06 +00:00
Charlie Marsh b0c841ee3b Ban --no-cache with --link-mode=symlink (#5519)
## Summary

Closes https://github.com/astral-sh/uv/issues/5360.
2024-07-28 15:01:17 -04:00
Charlie Marsh 88340fbd0d Remove some unused methods (#5512) 2024-07-28 17:20:12 +00:00
Charlie Marsh d798bb3973 Avoid always rebuilding dynamic metadata (#5206)
## Summary

I don't think that "always reinstall" is tenable for `uv run`. My
perspective on this is that if you want "always reinstall", you can now
set it persistently in your `pyproject.toml` or `uv.toml`.

As a smaller change, we could instead disable this _only_ for the
Project API.

Closes https://github.com/astral-sh/uv/issues/4946.
2024-07-22 00:04:03 +00:00
Charlie Marsh a253913288 Don't apply irrelevant constraints when validating site-packages (#5231)
## Summary

The current code was checking every constraint against every
requirement, regardless of whether they were applicable. In general,
this isn't a big deal, because this method is only used as a fast-path
to skip resolution -- so we just had way more false-negatives than we
should've when constraints were applied. But it's clearly wrong :)

## Test Plan

- `uv venv`
- `uv pip install flask`
- `uv pip install --verbose flask -c constraints.txt` (with `numpy<1.0`)

Prior to this change, Flask was reported as not satisfied.
2024-07-19 20:49:22 +00:00
Charlie Marsh ed9b820815 Remove trailing period from user-facing messages (#5218)
## Summary

Per #5209, we only show periods in messages when the message itself
spans more than a single sentence.
2024-07-19 10:43:49 -04:00
Charlie Marsh f7c52fdbfb Add reference documentation for global settings (#5123)
## Summary

Second part of: https://github.com/astral-sh/uv/issues/5093.
2024-07-16 20:50:04 +00:00
Charlie Marsh 55b41d7d3d Lock directories to synchronize wheel-install copies (#4978)
## Summary

Closes https://github.com/astral-sh/uv/issues/4831.
2024-07-12 00:53:20 +00:00
Ibraheem Ahmed aff9c9bd91 Switch to Current-Thread Tokio Runtime (#4934)
## Summary

Move completely off tokio's multi-threaded runtime. We've slowly been
making changes to be smarter about scheduling in various places instead
of depending on tokio's general purpose work-stealing, notably
https://github.com/astral-sh/uv/pull/3627 and
https://github.com/astral-sh/uv/pull/4004. We now no longer benefit from
the multi-threaded runtime, as we run on all I/O on the main thread.
There's one remaining instance of `block_in_place` that can be swapped
for `rayon::spawn`.

This change is a small performance improvement due to removing some
unnecessary overhead of the multi-threaded runtime (e.g. spawning
threads), but nothing major. It also removes some noise from profiles.

## Test Plan

```
Benchmark 1: ./target/profiling/uv (resolve-warm)
  Time (mean ± σ):      14.9 ms ±   0.3 ms    [User: 3.0 ms, System: 17.3 ms]
  Range (min … max):    14.1 ms …  15.8 ms    169 runs
 
Benchmark 2: ./target/profiling/baseline (resolve-warm)
  Time (mean ± σ):      16.1 ms ±   0.3 ms    [User: 3.9 ms, System: 18.7 ms]
  Range (min … max):    15.1 ms …  17.3 ms    162 runs
 
Summary
  ./target/profiling/uv (resolve-warm) ran
    1.08 ± 0.03 times faster than ./target/profiling/baseline (resolve-warm)
```
2024-07-09 18:21:16 -04:00
Charlie Marsh 98a720ec08 Skip installing --with requirements if present in base environment (#4879)
## Summary

Closes #4547.
2024-07-08 01:23:59 +00:00
Zanie Blue dd7da6af5f Change "toolchain" to "python" (#4735)
Whew this is a lot.

The user-facing changes are:

- `uv toolchain` to `uv python` e.g. `uv python find`, `uv python
install`, ...
- `UV_TOOLCHAIN_DIR` to` UV_PYTHON_INSTALL_DIR`
- `<UV_STATE_DIR>/toolchains` to `<UV_STATE_DIR>/python` (with
[automatic
migration](https://github.com/astral-sh/uv/pull/4735/files#r1663029330))
- User-facing messages no longer refer to toolchains, instead using
"Python", "Python versions" or "Python installations"

The internal changes are:

- `uv-toolchain` crate to `uv-python`
- `Toolchain` no longer referenced in type names
- Dropped unused `SystemPython` type (previously replaced)
- Clarified the type names for "managed Python installations"
- (more little things)
2024-07-03 07:44:29 -05:00
Ibraheem Ahmed be2a67cd9b Replace map_or(false, ..) uses with is_some_and and is_ok_and (#4703)
## Summary

Looks like there isn't a clippy lint for this yet.
2024-07-01 19:28:42 +00:00
Ibraheem Ahmed 8a2af8bc83 More uv pip tree cleanup (#4702)
## Summary

Follow up to https://github.com/astral-sh/uv/pull/4700.
2024-07-01 15:21:38 -04:00
Charlie Marsh ac87fd4006 Disable Clippy's too-many-arguments rule (#4663)
## Summary

We allow this constantly, I think it's just too pedantic for us.
2024-06-30 19:30:38 +00:00
Zanie Blue 25cde888ae Rename SitePackages::from_environment for clarity (#4497) 2024-06-24 23:32:45 +00:00
renovate[bot] 3251690327 Update Rust crate rustc-hash to v2 (#4461) 2024-06-24 01:13:05 +00:00
Zanie Blue 9a3b8511f1 Treat mismatched directory and file urls as unsatisfied requirements (#4393)
Closes https://github.com/astral-sh/uv/issues/4391
2024-06-19 14:50:13 +00:00
Zanie Blue f219f88553 Rename Downloader for clarity (#4395)
Follow-up to https://github.com/astral-sh/uv/pull/4394 with internal
refactor
2024-06-18 16:00:10 -05:00
Zanie Blue 5a007b6b9f Add BuildOptions for centralized combination of NoBuild and NoBinary (#4284)
As requested in review of https://github.com/astral-sh/uv/pull/4067
2024-06-12 21:33:33 +00:00
Zanie Blue 1ab4041baa Allow specific --only-binary and --no-binary packages to override :all: (#4067)
Updates `--no-binary <package>` to take precedence over `--only-binary
:all:` and `--only-binary <package>` to take precedence over
`--no-binary :all:`.

I'm not entirely sure about this behavior, e.g. maybe I provided
`--only-binary :all:` later on the command line and really want it to
override those earlier arguments of `--no-binary <package>` for safety.
Right now we just fail to solve though since we can't satisfy the
overlapping requests.

Closes https://github.com/astral-sh/uv/issues/4063
2024-06-12 15:47:45 -05:00
Charlie Marsh d8f1de6134 Use separate path types for directories and files (#4285)
## Summary

This is what I consider to be the "real" fix for #8072. We now treat
directory and path URLs as separate `ParsedUrl` types and
`RequirementSource` types. This removes a lot of `.is_dir()` forking
within the `ParsedUrl::Path` arms and makes some states impossible
(e.g., you can't have a `.whl` path that is editable). It _also_ fixes
the `direct_url.json` for direct URLs that refer to files. Previously,
we wrote out to these as if they were installed as directories, which is
just wrong.
2024-06-12 15:59:21 -04:00
Charlie Marsh c32667caec Avoid treating direct path archives as always dynamic (#4283)
## Summary

Right now, we're _always_ reinstalling local wheel archives, even if the
timestamp didn't change.

I want to fix the TODO properly but I will do so in a separate PR.
2024-06-12 17:28:29 +00:00
konsti 44833801b3 Support locking relative paths (#4205)
By splitting `path` into a lockable, relative (or absolute) and an
absolute installable path and by splitting between urls and paths by
dist type, we can store relative paths in the lockfile.
2024-06-11 11:58:03 +00:00