Commit Graph

1888 Commits

Author SHA1 Message Date
Zanie Blue d313d9b1fa
Add initial implementation of `uv tool run` (#3657)
This is mostly a shorter version of `uv run` that infers a requirement
name from the command. The main goal here is to do the smallest amount
of work necessary to get #3560 started.

Closes #3613 

e.g.
```shell
$ uv tool run -- ruff check
warning: `uv tool run` is experimental and may change without warning.
Resolved 1 package in 34ms
Installed 1 package in 2ms
 + ruff==0.4.4
error: Failed to parse example.py:1:5: Expected an expression
example.py:1:5: E999 SyntaxError: Expected an expression
Found 1 error.
```
2024-05-21 19:51:30 +00:00
Zanie Blue d540d0f28b
Rewrite Python interpreter discovery (#3266)
Updates our Python interpreter discovery to conform to the rules
described in #2386, please see that issue for a full description of the
behavior. Briefly, we now will search for interpreters that satisfy a
requested version without stopping at the first Python executable.
Additionally, if retrieving information about an interpreter fails we
will continue to search for a working interpreter. We also add the
plumbing necessary to request Python implementations other than CPython,
though we do not add support for other implementations at this time.

A major internal goal of this work is to prepare for user-facing managed
toolchains i.e. fetching a requested version during `uv run`. These APIs
are not introduced, but there is some managed toolchain handling as
required for our test suite.

Some noteworthy implementation changes:

- The `uv_interpreter::find_python` module has been removed in favor of
a `uv_interpreter::discovery` module.
- There are new types to help structure interpreter requests and track
sources
- Executable discovery is implemented as a big lazy iterator and is a
central authority for source precedence
- `uv_interpreter::Error` variants were split into scoped types in each
module
- There's much more unit test coverage, but not for Windows yet

Remaining work:

- [x] Write new test cases
- [x] Determine correct behavior around executables in the current
directory
- _Future_: Combine `PythonVersion` and `VersionRequest`
- _Future_: Consider splitting `ManagedToolchain` into local and remote
variants
- _Future_: Add Windows unit test coverage
- _Future_: Explore behavior around implementation precedence (i.e.
CPython over PyPy)

Refactors split into:

- #3329 
- #3330 
- #3331
- #3332

Closes #2386
2024-05-21 14:37:23 -05:00
Zanie Blue c14a7dbef3
Improve display of root package in range errors (#3711)
Instead of saying 

> we can conclude that you require==0a0.dev0 and
pandas-stubs==2.0.3.230814 are incompatible.

we'll say

> we can conclude that your requirements and pandas-stubs==2.0.3.230814
are incompatible.

Closes #3710 

I'm not sure how to get unit test coverage for this, might look into
that. Ideally we'd skip this branch entirely?
2024-05-21 19:28:23 +00:00
Zanie Blue dfd6ccf0f9
Move maturin test coverage into CI (#3714)
This test can take over 60s to run, which is too much for a unit test.
We'll run it in a separate CI job to retain coverage.
2024-05-21 19:17:48 +00:00
Charlie Marsh cf997080b0
Rename `DistInfoMetadata` to `CoreMetadata` (#3699)
## Summary

This reflects the change codified in PEP 714.
2024-05-21 18:26:59 +00:00
Charlie Marsh fee344db6f
Add PEP 714 support for HTML API client (#3697)
## Summary

If `data-core-metadata` is set, we need to respect that over
`data-dist-info-metadata` in the HTML client.

See: https://github.com/astral-sh/uv/issues/3689
2024-05-21 18:05:40 +00:00
konsti e6a5da7424
Fix clippy on main by boxing large error variant (#3707)
I don't really understand why this only happens on windows clippy and
not on linux too, but as usual, boxing the error variant fixes it.

Fixup for #3585
2024-05-21 17:55:43 +00:00
konsti 2ffd453003
Discover workspaces without using them in resolution (#3585)
Add minimal support for workspace discovery, only used for determining
paths in the bluejay commands.

We can now discover the workspace structure, namely that the
`pyproject.toml` of a package belongs to a workspace `pyproject.toml`
with members and exclusion. The globbing logic is inspired by cargo. We
don't resolve `workspace = true` metadata declarations yet.
2024-05-21 17:17:26 +00:00
Charlie Marsh 5205165d42
Add PEP 714 support for JSON API client (#3698)
## Summary

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

## Test Plan

Manually verified we pick up `core-metadata` from PyPI if I remove the
aliases.
2024-05-21 15:52:37 +00:00
konsti 95af1db0bb
Let `RequirementSource::Path.editable` be `bool`, not `Option<bool>` (#3693)
Small refactoring of the internal representation. This does not change
`tool.uv.sources`.
2024-05-21 14:34:43 +00:00
konsti f396c6c33e
Revert "Support editables in `uv sync` (#3692)" (#3696)
This reverts commit #3692 until we get the editables from the lockfile.
2024-05-21 14:11:36 +00:00
konsti 76418f5bdf
Arc-wrap `PubGrubPackage` for cheap cloning in pubgrub (#3688)
Pubgrub stores incompatibilities as (package name, version range)
tuples, meaning it needs to clone the package name for each
incompatibility, and each non-borrowed operation on incompatibilities.
https://github.com/astral-sh/uv/pull/3673 made me realize that
`PubGrubPackage` has gotten large (expensive to copy), so like `Version`
and other structs, i've added an `Arc` wrapper around it.

It's a pity clippy forbids `.deref()`, it's less opaque than `&**` and
has IDE support (clicking on `.deref()` jumps to the right impl).

## Benchmarks

It looks like this matters most for complex resolutions which, i assume
because they carry larger `PubGrubPackageInner::Package` and
`PubGrubPackageInner::Extra` types.

```bash
hyperfine --warmup 5 "./uv-main pip compile -q ./scripts/requirements/jupyter.in" "./uv-branch pip compile -q ./scripts/requirements/jupyter.in"
hyperfine --warmup 5 "./uv-main pip compile -q ./scripts/requirements/airflow.in" "./uv-branch pip compile -q ./scripts/requirements/airflow.in"
hyperfine --warmup 5 "./uv-main pip compile -q ./scripts/requirements/boto3.in" "./uv-branch pip compile -q ./scripts/requirements/boto3.in"
```

```
Benchmark 1: ./uv-main pip compile -q ./scripts/requirements/jupyter.in
  Time (mean ± σ):      18.2 ms ±   1.6 ms    [User: 14.4 ms, System: 26.0 ms]
  Range (min … max):    15.8 ms …  22.5 ms    181 runs

Benchmark 2: ./uv-branch pip compile -q ./scripts/requirements/jupyter.in
  Time (mean ± σ):      17.8 ms ±   1.4 ms    [User: 14.4 ms, System: 25.3 ms]
  Range (min … max):    15.4 ms …  23.1 ms    159 runs

Summary
  ./uv-branch pip compile -q ./scripts/requirements/jupyter.in ran
    1.02 ± 0.12 times faster than ./uv-main pip compile -q ./scripts/requirements/jupyter.in
```

```
Benchmark 1: ./uv-main pip compile -q ./scripts/requirements/airflow.in
  Time (mean ± σ):     153.7 ms ±   3.5 ms    [User: 165.2 ms, System: 157.6 ms]
  Range (min … max):   150.4 ms … 163.0 ms    19 runs

Benchmark 2: ./uv-branch pip compile -q ./scripts/requirements/airflow.in
  Time (mean ± σ):     123.9 ms ±   4.6 ms    [User: 152.4 ms, System: 133.8 ms]
  Range (min … max):   118.4 ms … 138.1 ms    24 runs

Summary
  ./uv-branch pip compile -q ./scripts/requirements/airflow.in ran
    1.24 ± 0.05 times faster than ./uv-main pip compile -q ./scripts/requirements/airflow.in
```

```
Benchmark 1: ./uv-main pip compile -q ./scripts/requirements/boto3.in
  Time (mean ± σ):     327.0 ms ±   3.8 ms    [User: 344.5 ms, System: 71.6 ms]
  Range (min … max):   322.7 ms … 334.6 ms    10 runs

Benchmark 2: ./uv-branch pip compile -q ./scripts/requirements/boto3.in
  Time (mean ± σ):     311.2 ms ±   3.1 ms    [User: 339.3 ms, System: 63.1 ms]
  Range (min … max):   307.8 ms … 317.0 ms    10 runs

Summary
  ./uv-branch pip compile -q ./scripts/requirements/boto3.in ran
    1.05 ± 0.02 times faster than ./uv-main pip compile -q ./scripts/requirements/boto3.in
```

<!--
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?
-->
2024-05-21 13:49:35 +02:00
konsti fbae55019e
Support editables in `uv sync` (#3692)
This is bare-bones support for editables in `uv sync` as basis for
workspace support, notably without lockfile integration. It leverages
the existing `ResolvedEditables` infrastructure.
2024-05-21 11:30:15 +00:00
konsti d326e1f5e9
Better error message for `uv run` failures (#3691)
Attach path context to `uv run` failures since those function calls are
not covered by `fs_err`.
2024-05-21 11:24:18 +00:00
konsti 2c4088a518
Improve `DirWithoutEntrypoint` error message (#3690)
Ran into this and couldn't tell what the problem was without the path
attached.
2024-05-21 11:21:20 +00:00
Charlie Marsh 49f0e84f3d
Write relative paths with unnamed requirement syntax (#3682)
## Summary

This PR falls back to writing an unnamed requirement if it appears to be
a relative URL. pip is way more flexible when providing an unnamed
requirement than when providing a PEP 508 requirement. For example,
_only_ this works:

```
black @ file:///Users/crmarsh/workspace/uv/scripts/packages/black_editable
```

Any other form will fail.

Meanwhile, _all_ of these work:

```
file:///Users/crmarsh/workspace/uv/scripts/packages/black_editable
scripts/packages/black_editable
./scripts/packages/black_editable
file:./scripts/packages/black_editable
file:scripts/packages/black_editable
```

Closes https://github.com/astral-sh/uv/issues/3180.
2024-05-20 21:22:06 -04:00
Charlie Marsh 0362918196
Evaluate arbitrary markers to `false` (#3681)
## Summary

See: https://github.com/astral-sh/uv/pull/3679#issuecomment-2121387428.

Closes: https://github.com/astral-sh/uv/issues/3675 (although I think we
have another improvement to make there -- will file separately).
2024-05-21 01:01:11 +00:00
Andrew Gallant 776a7e47f3 uv-resolver: add `Option<MarkerTree>` to `PubGrubPackage`
This just adds the field to the type and always sets it to `None`. There
are semantic changes in this commit.

Closes #3359
2024-05-20 19:56:24 -04:00
Andrew Gallant d0435ef20a pep508: add `PartialOrd` and `Ord` implementations to `MarkerTree`
Since we're adding a `Option<MarkerTree>` to `PubGrubPackage`, and since
we just make `PubGrubPackage` implement `Ord`, it follows that we want
`MarkerTree` to also implement `Ord`.
2024-05-20 19:56:24 -04:00
Andrew Gallant 1ed3555bf0 uv-resolver: sort in `format_terms`
This makes use of the newly added `Ord` impl on `PubGrubPackage` to make
the output of `format_terms` independent of hashmap iteration order.

This was already collecting the terms into an intermediate `Vec`, so
sorting probably isn't going to add any significant overhead here.
(Plus, this is only running when formatting an error message after a
solution could not be found, so an extra sort doesn't seem like a big
deal here.)

Note that some tests are updated in this commit as a result of this
change. As far as I can tell, the semantic meaning of the output remains
the same. But the order of the listed packages does not.

Specific thing motivating this change is, in a subsequent, I added
`Option<MarkerTree>` to `PubGrubPackage::Package`, and this caused
similar changes in test output. So I backtracked and isolated this
change from the addition of `Option<MarkerTree>`.
2024-05-20 19:56:24 -04:00
Andrew Gallant 976bc9ba0e uv-resolver: make PubGrubPackage orderable
It turns out that we use PubGrubPackage as the key in hashmaps in a fair
few places. And when we iterate over hashmaps, the order is unspecified.
This can in turn result in changes in output as a result of changes in
the PubGrubPackage definition, purely as a function of its changing
hash. This is confusing as there should be no semantic difference.

Thus, this is a precursor to introducing some more determinism to places
I found in the error reporting whose output depending on hashmap
iteration order.
2024-05-20 19:56:24 -04:00
Andrew Gallant 9f109f243c uv-resolver: remove 'derive(Derivative)' from PubGrubPackage
It looks like the last vestiges of `Derivative` were removed in commit
7eaed07f6c, but the then rendered
superfluous `derive(Derivative)` wasn't removed.
2024-05-20 19:56:24 -04:00
Andrew Gallant eac8221718 uv-resolver: use named fields for some PubGrubPackage variants
I'm planning to add another field here (markers), which puts a lot of
stress on the positional approach. So let's just switch over to named
fields.
2024-05-20 19:56:24 -04:00
Charlie Marsh 44fe0f6749
Add rustdoc links to `marker.rs` documentation (#3680) 2024-05-20 23:29:15 +00:00
Charlie Marsh a33a05e2d9
Bump version to v0.1.45 (#3674) 2024-05-20 16:34:05 -04:00
Charlie Marsh 223980e4bc
Always print JSON output with --format json (#3671)
## Summary

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

## Test Plan

```
uv on  charlie/list:main
❯ cargo run pip list --editable
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.15s
     Running `target/debug/uv pip list --editable`
uv on  charlie/list:main
❯ cargo run pip list --editable --format json
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.16s
     Running `target/debug/uv pip list --editable --format json`
[]
uv on  charlie/list:main
❯ cargo run pip list --editable --format freeze
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.15s
     Running `target/debug/uv pip list --editable --format freeze`
uv on  charlie/list:main
❯ cargo run pip list --editable --format columns
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.15s
     Running `target/debug/uv pip list --editable --format columns`
```
2024-05-20 12:39:31 -04:00
konsti 95c9621541
Refactor editables for supporting them in bluejay commands (#3639)
This is split out from workspaces support, which needs editables in the
bluejay commands. It consists mainly of refactorings:

* Move the `editable` module one level up.
* Introduce a `BuiltEditableMetadata` type for `(LocalEditable,
Metadata23, Requirements)`.
* Add editables to `InstalledPackagesProvider` so we can use
`EmptyInstalledPackages` for them.
2024-05-20 16:22:12 +00:00
Charlie Marsh c32fb8647f
Apply combination logic to merge CLI and persistent configuration (#3618)
## Summary

If you have (e.g.) `extra-index-url` in your configuration file _and_
provide `--extra-index-url` on the command-line, we now merge the
options rather than ignoring those in the configuration file. As such,
merging the CLI and the persistent configuration is now semantically
identical to how we merge (project persistent configuration) with (user
persistent configuration).

Closes https://github.com/astral-sh/uv/issues/3541.
2024-05-20 13:37:02 +00:00
Charlie Marsh f3965fef5e
Use filename trait for `WheelWire` conversion (#3651)
## Summary

The main motivation here is that the `.filename()` method that we
implement on `Url` will do URL decoding for the last segment, which we
were missing here.

The errors are a bit awkward, because in
`crates/uv-resolver/src/lock.rs`, we wrap in `failed to extract filename
from URL: {url}`, so in theory we want the underlying errors to _omit_
the URL? But sometimes they use `#[error(transparent)]`?
2024-05-20 09:25:31 -04:00
Charlie Marsh 657eebd50b
Remove `SourceDistFilename` from `RegistrySourceDist` (#3650)
## Summary

Uncertain about this, but we don't actually need the full
`SourceDistFilename`, only the name and version -- and we often have
that information already (as in the lockfile routines). So by flattening
the fields onto `RegistrySourceDist`, we can avoid re-parsing for
information we already have.
2024-05-20 09:25:23 -04:00
Charlie Marsh 1124df9bc5
Remove subdirectory from direct wheel URL type (#3667)
## Summary

Closes #3665.
2024-05-20 02:01:57 +00:00
Zanie Blue d8971c1eb0
Move `update_environment` from `run` to the `project` namespace (#3659)
Prompted by
https://github.com/astral-sh/uv/pull/3657#discussion_r1606041239

There's still some level of discomfort here, as the `tool` module needs
needs to import the `project` module to manage an environment. We should
probably move most of the basic operations in the `project` module root
into some sort of shared module for behind the scenes operations?

Regardless, this change should simplify that future move.
2024-05-19 20:48:24 -05:00
renovate[bot] e3ae876801
Update Rust crate itertools to 0.13.0 (#3664) 2024-05-20 00:49:42 +00:00
Charlie Marsh 0718705c21
Track parsed Git URL components in `GitSourceUrl` (#3656)
## Summary

Closes https://github.com/astral-sh/uv/issues/3571.
2024-05-20 00:43:30 +00:00
Charlie Marsh a0745d0d9d
Add registry file size to lockfile (#3652)
## Summary

Mentioned in #3611.
2024-05-19 02:27:05 +00:00
Charlie Marsh 98b3325cd4
Add `UV_CONFIG_FILE` environment variable to documentation (#3653)
## Summary

Closes https://github.com/astral-sh/uv/issues/3648.
2024-05-19 02:25:32 +00:00
Charlie Marsh 963f2a778b
URL-decode hashes in HTML fragments (#3655)
## Summary

Closes https://github.com/astral-sh/uv/issues/3654
2024-05-18 22:19:55 -04:00
Ben Beasley 53c2551fac
Pin the zip crate to 0.6 (#3645)
## Summary

Restore API-compatibility with pre-1.1.0 versions of the `zip` crate,
and pin the dependency to the 0.6 series, due to concerns discussed in
https://github.com/astral-sh/uv/issues/3642.

## Test Plan

```
cargo run -p uv-dev -- fetch-python
cargo test
```
2024-05-18 17:31:53 +00:00
Charlie Marsh 18b095ce28
Make `from_rev` take an owned value (#3631)
## Summary

We always clone internally, and in most case we're already passing
`&String`.
2024-05-18 17:26:15 +00:00
Charlie Marsh 47f4114a1b
Add registry source distribution support to lockfile (#3649)
## Summary

One TODO but going to resolve that separately.
2024-05-18 16:54:27 +00:00
Ibraheem Ahmed 53633392c3
Add `UV_CONCURRENT_INSTALLS` variable in favor of `RAYON_NUM_THREADS` (#3646)
## Summary

Continuation of https://github.com/astral-sh/uv/pull/3493. This gives us
more flexibility in case we decide to move away from `rayon` in the
future.
2024-05-17 23:12:37 -04:00
Charlie Marsh fe2bc079bc
Use `ParsedGitUrl` to recreate Git source kind URL (#3647) 2024-05-17 21:45:46 +00:00
Charlie Marsh e2d7d2026b
Add direct URL conversion to lockfile (#3633)
## Summary

Similar to #3630, but for direct URL distributions (for both wheels and
source distributions).
2024-05-17 21:32:42 +00:00
Charlie Marsh 0d512be46c
Support lossless serialization for Git dependencies in lockfile (#3630)
## Summary

This PR adds lossless deserialization for `GitSourceDist` distributions
in the lockfile. Specifically, we now properly preserve the requested
revision, the subdirectory, and the precise Git commit SHA.

## Test Plan

`cargo test`
2024-05-17 21:23:40 +00:00
Ibraheem Ahmed 0f67a6ceea
Use `FxHasher` in resolver (#3641)
## Summary

We can use `FxHasher` in a few more places for string and version keys.
This gives a consistent ~2% improvement to warm resolves.
2024-05-17 15:04:22 -04:00
Ibraheem Ahmed 39af09f09b
Parallelize resolver (#3627)
## Summary

This PR introduces parallelism to the resolver. Specifically, we can
perform PubGrub resolution on a separate thread, while keeping all I/O
on the tokio thread. We already have the infrastructure set up for this
with the channel and `OnceMap`, which makes this change relatively
simple. The big change needed to make this possible is removing the
lifetimes on some of the types that need to be shared between the
resolver and pubgrub thread.

A related PR, https://github.com/astral-sh/uv/pull/1163, found that
adding `yield_now` calls improved throughput. With optimal scheduling we
might be able to get away with everything on the same thread here.
However, in the ideal pipeline with perfect prefetching, the resolution
and prefetching can run completely in parallel without depending on one
another. While this would be very difficult to achieve, even with our
current prefetching pattern we see a consistent performance improvement
from parallelism.

This does also require reverting a few of the changes from
https://github.com/astral-sh/uv/pull/3413, but not all of them. The
sharing is isolated to the resolver task.

## Test Plan

On smaller tasks performance is mixed with ~2% improvements/regressions
on both sides. However, on medium-large resolution tasks we see the
benefits of parallelism, with improvements anywhere from 10-50%.

```
./scripts/requirements/jupyter.in
Benchmark 1: ./target/profiling/baseline (resolve-warm)
  Time (mean ± σ):      29.2 ms ±   1.8 ms    [User: 20.3 ms, System: 29.8 ms]
  Range (min … max):    26.4 ms …  36.0 ms    91 runs
 
Benchmark 2: ./target/profiling/parallel (resolve-warm)
  Time (mean ± σ):      25.5 ms ±   1.0 ms    [User: 19.5 ms, System: 25.5 ms]
  Range (min … max):    23.6 ms …  27.8 ms    99 runs
 
Summary
  ./target/profiling/parallel (resolve-warm) ran
    1.15 ± 0.08 times faster than ./target/profiling/baseline (resolve-warm)
```
```
./scripts/requirements/boto3.in   
Benchmark 1: ./target/profiling/baseline (resolve-warm)
  Time (mean ± σ):     487.1 ms ±   6.2 ms    [User: 464.6 ms, System: 61.6 ms]
  Range (min … max):   480.0 ms … 497.3 ms    10 runs
 
Benchmark 2: ./target/profiling/parallel (resolve-warm)
  Time (mean ± σ):     430.8 ms ±   9.3 ms    [User: 529.0 ms, System: 77.2 ms]
  Range (min … max):   417.1 ms … 442.5 ms    10 runs
 
Summary
  ./target/profiling/parallel (resolve-warm) ran
    1.13 ± 0.03 times faster than ./target/profiling/baseline (resolve-warm)
```
```
./scripts/requirements/airflow.in 
Benchmark 1: ./target/profiling/baseline (resolve-warm)
  Time (mean ± σ):     478.1 ms ±  18.8 ms    [User: 482.6 ms, System: 205.0 ms]
  Range (min … max):   454.7 ms … 508.9 ms    10 runs
 
Benchmark 2: ./target/profiling/parallel (resolve-warm)
  Time (mean ± σ):     308.7 ms ±  11.7 ms    [User: 428.5 ms, System: 209.5 ms]
  Range (min … max):   287.8 ms … 323.1 ms    10 runs
 
Summary
  ./target/profiling/parallel (resolve-warm) ran
    1.55 ± 0.08 times faster than ./target/profiling/baseline (resolve-warm)
```
2024-05-17 11:47:30 -04:00
Ahmed Ilyas e3e7895605
Fix source annotation in pip compile `annotation-style=line` output (#3637)
## Summary

Fixes a small discrepancy between the pip compile outputs for
`annotation-style=split` and `annotation-style=line` commands.

### Problem

Consider the following `pyproject.toml` file.
```sh
$ cat pyproject.toml
[project]
name = "uv_test"
dynamic = ["version"]
dependencies = ["click"]
```

Running uv pip compile with annotation-style=split on uv 0.1.44 version
yields the following:
```sh
❯ uv pip compile pyproject.toml --annotation-style=split
Resolved 1 package in 2ms
# This file was autogenerated by uv via the following command:
#    uv pip compile pyproject.toml --annotation-style=split
click==8.1.7
    # via uv-test (pyproject.toml)
```

However, running uv pip compile with annotation-style=line doesn't
include source info for root level dependencies.
```sh
❯ uv pip compile pyproject.toml --annotation-style=line
Resolved 1 package in 1ms
# This file was autogenerated by uv via the following command:
#    uv pip compile pyproject.toml --annotation-style=line
click==8.1.7
```

With this PR:
```sh
❯ ../target/debug/uv pip compile --annotation-style=line pyproject.toml
Resolved 1 package in 6ms
# This file was autogenerated by uv via the following command:
#    uv pip compile --annotation-style=line pyproject.toml
click==8.1.7              # via uv-test (pyproject.toml)
```

This also now matches `pip-tools` output:
```sh
❯ pip-compile --annotation-style=line pyproject.toml
#
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
#    pip-compile --annotation-style=line pyproject.toml
#
click==8.1.7              # via uv_test (pyproject.toml)

```

## Test Plan

`cargo test`
2024-05-17 09:57:11 -04:00
Adolfo Ochagavía 3383510b1d
Fix copy-paste error (#3634)
There was an error in the docs for the installer's `Reporter`. I assume
it's a copy-paste error from the `Reporter` in `resolver.rs`.
2024-05-17 13:28:43 +02:00
Charlie Marsh ed91b1d562
Parse and store extras on editables (#3629)
## Summary

As a follow-up to #3622, we now parse and store (but don't respect)
markers on editable requirements.
2024-05-16 17:12:52 -04:00
Charlie Marsh 7f73f7b3c2
Discard markers on editable requirements (#3622)
## Summary

If a user includes markers after an editable, we now ignore them (rather
than including them in the parsed URL). This matches pip's behavior. In
the future, we could further improve by respecting them, but that
_would_ be a deviation from pip.

For example, given:

```
-e ./scripts/packages/black_editable ; python_version >= "3.9" and python_ver
```

We now split at the first whitespace (just before the `;`), parse
everything before, and throw out everything after.

This logic also extends to extras. So given:

```
-e ./scripts/packages/black_editable[dev, colorama]
```

We'll now parse this as the URL
`./scripts/packages/black_editable[dev,`, and throw out ` colorama]`.
Instead, you need to do:

```
-e ./scripts/packages/black_editable[dev,colorama]
```

(I.e., remove the space.)

This _also_ matches pip's behavior. I could "fix" this but I'm unsure if
I should -- it means requirements files will be parseable by uv that
won't work with pip. Open to input. My gut reaction is that we _should_
properly support `-e ./scripts/packages/black_editable[dev, colorama]`
even if pip would reject it, but `requirements.txt` is
implementation-defined so it'd be a "deviation".

Closes https://github.com/astral-sh/uv/issues/3604.
2024-05-16 20:53:52 +00:00
Charlie Marsh 3b8e8de495
Add basic tests for lockfile generation (#3623) 2024-05-16 11:18:09 -04:00
Andrew Gallant 0a055b7942
distribution-types: allow RegistrySourceDist to have wheels attached to it (#3610)
Following from #3595, we'd like wheels to make their way into the lock
file even if the current environment selects an sdist. With #3595, this
didn't happen:

$ cargo run -p uv -- pip compile -p3.10 <(echo psycopg2)
--unstable-uv-lock-file
    $ cat uv.lock
    version = 1

    [[distribution]]
    name = "psycopg2"
    version = "2.9.9"
    source = "registry+https://pypi.org/simple"

    [distribution.sdist]
url =
"dc6acaf46d76fce95daac5e0f0301b/psycopg2-2.9.9.tar.gz"
hash =
"sha256:d1454bde93fb1e224166811694d600e746430c006fbb031ea06ecc2ea41bf156"

The above example uses `psycopg2`, which has an sdist and wheels only on
Windows. Since I ran the above on Linux, an sdist was selected. But no
wheels appeared in the lock file.

With this PR, wheels are now correctly plumbed through:

$ cargo run -p uv -- pip compile -p3.10 <(echo psycopg2)
--unstable-uv-lock-file
    $ cat uv.lock
    version = 1

    [[distribution]]
    name = "psycopg2"
    version = "2.9.9"
    source = "registry+https://pypi.org/simple"

    [distribution.sdist]
url =
"dc6acaf46d76fce95daac5e0f0301b/psycopg2-2.9.9.tar.gz"
hash =
"sha256:d1454bde93fb1e224166811694d600e746430c006fbb031ea06ecc2ea41bf156"

    [[distribution.wheel]]
url =
"2767d96391f5cde90b82cb3e8c2a12/psycopg2-2.9.9-cp310-cp310-win32.whl"
hash =
"sha256:38a8dcc6856f569068b47de286b472b7c473ac7977243593a288ebce0dc89516"

    [[distribution.wheel]]
url =
"6572dec6831f85491a5e4dda606a98/psycopg2-2.9.9-cp310-cp310-win_amd64.whl"
hash =
"sha256:426f9f29bde126913a20a96ff8ce7d73fd8a216cfb323b1f04da402d452853c3"

    [[distribution.wheel]]
url =
"1fc5b9d33c858a602868a592cdc1b0/psycopg2-2.9.9-cp311-cp311-win32.whl"
hash =
"sha256:ade01303ccf7ae12c356a5e10911c9e1c51136003a9a1d92f7aa9d010fb98372"

    [[distribution.wheel]]
url =
"5133dd3183e671b278ce248810b7f7/psycopg2-2.9.9-cp311-cp311-win_amd64.whl"
hash =
"sha256:121081ea2e76729acfb0673ff33755e8703d45e926e416cb59bae3a86c6a4981"

    [[distribution.wheel]]
url =
"f74ffe6b6fe119ccb8a6546c3fb893/psycopg2-2.9.9-cp312-cp312-win32.whl"
hash =
"sha256:d735786acc7dd25815e89cc4ad529a43af779db2e25aa7c626de864127e5a024"

    [[distribution.wheel]]
url =
"c4a26e1918ab7ee854fb5247f16c40/psycopg2-2.9.9-cp312-cp312-win_amd64.whl"
hash =
"sha256:a7653d00b732afb6fc597e29c50ad28087dcb4fbfb28e86092277a559ae4e693"

    [[distribution.wheel]]
url =
"ffeb9ac356ce0d6c4f2f34e396dbc0/psycopg2-2.9.9-cp37-cp37m-win32.whl"
hash =
"sha256:5e0d98cade4f0e0304d7d6f25bbfbc5bd186e07b38eac65379309c4ca3193efa"

    [[distribution.wheel]]
url =
"0a39176d36fd7105774e57996f63cd/psycopg2-2.9.9-cp37-cp37m-win_amd64.whl"
hash =
"sha256:7e2dacf8b009a1c1e843b5213a87f7c544b2b042476ed7755be813eaf4e8347a"

    [[distribution.wheel]]
url =
"86b90d30c4420cc3c0f6da2b8f3a9a/psycopg2-2.9.9-cp38-cp38-win32.whl"
hash =
"sha256:ff432630e510709564c01dafdbe996cb552e0b9f3f065eb89bdce5bd31fabf4c"

    [[distribution.wheel]]
url =
"c439b378ef79997a935f10374f3c0d/psycopg2-2.9.9-cp38-cp38-win_amd64.whl"
hash =
"sha256:bac58c024c9922c23550af2a581998624d6e02350f4ae9c5f0bc642c633a2d5e"

    [[distribution.wheel]]
url =
"5080c0e61ad5f08b9503e508aac116/psycopg2-2.9.9-cp39-cp39-win32.whl"
hash =
"sha256:c92811b2d4c9b6ea0285942b2e7cac98a59e166d59c588fe5cfe1eda58e72d59"

    [[distribution.wheel]]
url =
"ec73fe66d4d65f5bbe54efb191d9e6/psycopg2-2.9.9-cp39-cp39-win_amd64.whl"
hash =
"sha256:de80739447af31525feddeb8effd640782cf5998e1a4e9192ebdf829717e3913"

Ref #3351
2024-05-15 15:16:00 -04:00
Charlie Marsh a735f6d80c
Add serialization and deserialization for `--find-links` (#3619)
## Summary

Closes https://github.com/astral-sh/uv/issues/3617.
2024-05-15 19:11:07 +00:00
Andrew Gallant 018a7150d6
uv-distribution: include all wheels in distribution types (#3595)
Our current flow of data from "simple registry package" to "final
resolved distribution" goes through a number of types:

* `SimpleMetadata` is the API response from a registry that includes all
published versions for a package. Each version has an assortment of
metadata
associated with it.
* `VersionFiles` is the aforementioned metadata. It is split in two: a
group of files for source distributions and a group of files for wheels.
* `PrioritizedDist` collects a subset of the files from `VersionFiles`
to form a selection of the "best" sdist and the "best" wheel for the
current environment.
* `CompatibleDist` is created from a borrowed `PrioritizedDist` that,
perhaps among other things, encapsulates the decision of whether to pick
an sdist or a wheel. (This decision depends both on compatibility and
the action being performed. e.g., When doing installation, a
`CompatibleDist` will sometimes select an sdist over a wheel.)
* `ResolvedDistRef` is like a `ResolvedDist`, but borrows a `Dist`.
* `ResolvedDist` is the almost-final-form of a distribution in a
resolution and is created from a `ResolvedDistRef`.
* `AnnotatedResolvedDist` is a new data type that is the actual final
form of a distribution that a universal lock file cares about. It
bundles a `ResolvedDist` with some metadata needed to generate a lock
file.

One of the requirements of a universal lock file is that we include all
wheels (and maybe all source distributions? but at least one if it's
present) associated with a distribution. But the above flow of data (in
the step from `VersionFiles` to `PrioritizedDist`) drops all wheels
except for the best one.

To remedy this, in this PR, we rejigger `PrioritizedDist`,
`CompatibleDist` and `ResolvedDistRef` so that all wheel data is
preserved. And when a `ResolvedDistRef` is finally turned into a
`ResolvedDist`, we copy all of the wheel data. And finally, we adjust
the `Lock` constructor to read this new data and include it in the lock
file. To make this work, we also modify `RegistryBuiltDist` so that it
can contain one or more wheels instead of just one.

One shortcoming here (called out in the code as a FIXME) is that if a
source distribution is selected as the "best" thing to use (perhaps
there are no compatible wheels), then the wheels won't end up in the
lock file. I plan to fix this in a follow-up PR.

We also aren't totally consistent on source distribution naming.
Sometimes we use `sdist`. Sometimes `source`. Sometimes `source_dist`.
I think it'd be nice to just use `sdist` everywhere, but I do prefer
the type names to be `SourceDist`. And sometimes you want function
names to match the type names (i.e., `from_source_dist`), which in turn
leads to an appearance of inconsistency. I'm open to ideas.

Closes #3351
2024-05-15 15:07:28 -04:00
Charlie Marsh 8d68d45ff5
Add `Combine` implementations for non-`Vec` types (#3616)
## Summary

Now, we just call `.combine` on all types, rather than needing to be
aware of whether or not it's a vector.
2024-05-15 18:40:55 +00:00
Ibraheem Ahmed a962a65302
Add routine for verifying two marker trees are disjoint (#3583)
## Summary

Implements https://github.com/astral-sh/uv/issues/3355.
2024-05-15 13:01:05 -04:00
Charlie Marsh d0c6b0a93e
Add local path conversions from lockfile (#3609)
## Summary

Just does the most basic thing to convert from `Distribution` back to
the installable type.
2024-05-15 12:46:45 -04:00
Charlie Marsh 55aedda379
Separate cache construction from initialization (#3607)
## Summary

Ensures that we only initialize the cache for commands that require it.

Closes https://github.com/astral-sh/uv/issues/3539.
2024-05-15 12:29:39 -04:00
Charlie Marsh 647f38be31
Add missing `"directory"` branch in source match (#3608)
## Summary

Just my oversight.
2024-05-15 16:25:55 +00:00
Charlie Marsh d76b023cd6
Remove `resolve_cli.rs` and `resolve_many.rs` (#3606)
## Summary

These depend on some APIs that I want to be internal-only for the
resolver crate, and we're no longer using them.
2024-05-15 16:04:47 +00:00
Charlie Marsh 913fc91afe
Remove binary from `uv-virtualenv` crate (#3605)
## Summary

I'm doing some refactoring and it requires updating this binary, but I
doubt we really use it?
2024-05-15 16:02:44 +00:00
Charlie Marsh ef068f1c01
Respect installed packages in `uv run` (#3603)
Closes #3601.
2024-05-15 15:48:32 +00:00
Charlie Marsh 85c71d6987
Rename `pinned_package` to `dist` (#3598) 2024-05-15 00:42:27 +00:00
Charlie Marsh 9a18d4ff46
Split `resolution.rs` into multiple files (#3597)
## Summary

No code changes.
2024-05-15 00:16:04 +00:00
Charlie Marsh c598f86476
Allow local versions in wheel filenames (#3596)
## Summary

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

## Test Plan

`cargo run pip install --verbose
https://github.com/Dao-AILab/flash-attention/releases/download/v2.5.8/flash_attn-2.5.8+cu122torch2.3cxx11abiFALSE-cp310-cp310-linux_x86_64.whl
--no-deps`
2024-05-15 00:02:09 +00:00
Charlie Marsh 8971944a01
Move `extras` onto annotated distribution (#3592)
## Summary

Like hashes, we can now store these on `AnnotatedDist` rather than
creating a parallel hash map and performing lookups later on.
2024-05-14 23:25:06 +00:00
Charlie Marsh c7348589fa
Remove some editable branches in resolution (#3591)
## Summary

Editables should always go down the `Some(url)` branch.
2024-05-14 23:16:06 +00:00
Charlie Marsh 4a42730cae
Add hashes and versions to all distributions (#3589)
## Summary

In `ResolutionGraph::from_state`, we have mechanisms to grab the hashes
and metadata for all distributions -- but we then throw that information
away. This PR preserves it on a new `AnnotatedDist` (yikes, open to
suggestions) that wraps `ResolvedDist` and includes (1) the hashes
(computed or from the registry) and (2) the `Metadata23`, which lets us
extract the version.

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

Closes https://github.com/astral-sh/uv/issues/3357.
2024-05-14 23:07:24 +00:00
Charlie Marsh 7363f31ceb
Rename `sourcedist` to `sdist` in lockfile (#3590)
## Summary

I think this is more consistent with Brett's proposal and looks more
natural to me as a user. What do you think, @BurntSushi?
2024-05-14 16:56:00 -04:00
Charlie Marsh f4cd7d627a
Split extra validation from graph construction (#3586)
## Summary

Splits this into two loops that each handle independent cases, to make
the code a little easier to reason about. No behavioral or logic changes
-- just splitting the `match` across two loops.
2024-05-14 16:41:16 -04:00
Charlie Marsh 30a7475029
Create lib64 symlink for 64-bit, non-macOS, POSIX environments (#3584)
## Summary

Closes
https://github.com/astral-sh/uv/issues/3578#issuecomment-2110675382.

## Test Plan

Verified that in the OpenSUSE test, we create both, and they're
symlinks:

```text
INFO: Creating virtual environment with `venv`...
INFO: Installing into `venv` virtual environment...
DEBUG Found a virtualenv named .venv at: /tmp/tmp4nape29h/.venv
DEBUG Cached interpreter info for Python 3.10.14, skipping probing: .venv/bin/python
DEBUG Using Python 3.10.14 environment at .venv/bin/python
DEBUG Trying to lock if free: .venv/.lock
purelib: "/tmp/tmp4nape29h/.venv/lib/python3.10/site-packages"
platlib: "/tmp/tmp4nape29h/.venv/lib64/python3.10/site-packages"
is_same_file(purelib, platlib): Ok(true)
```
2024-05-14 14:33:44 -04:00
Michał Górny e64c337cc5
Fix install_registry_source_dist_cached on Gentoo (#3569)
## Summary

Increment the removed file counts in filters
in install_registry_source_dist_cached test, to make it work again on
Gentoo. The tested counts were updated
in 9a92a3ad37, but the filters were not.
That said, the respective count increased in Gentoo as well, so adjust
both input and output strings. I'm updating Windows as a guesswork,
though I suspect that filter may not be necessary anymore, given that CI
was passing.

## Test Plan

`cargo test` on Gentoo :-).
2024-05-14 13:51:51 -04:00
Charlie Marsh 27c8c5ad44
Explain hash tie-breaking in distribution comparisons (#3581) 2024-05-14 13:34:32 -04:00
Ibraheem Ahmed 8ce9051296
Parse marker tree before evaluation (#3520)
## Summary

Parse `MarkerTree` expressions upfront, instead of lazily during
evaluation.

This makes implementing https://github.com/astral-sh/uv/issues/3355 a
lot easier.
2024-05-14 11:02:30 -04:00
Charlie Marsh 732410f255
Reduce sensitivity of unknown option error (#3580)
Closes https://github.com/astral-sh/uv/issues/3579.
2024-05-14 14:40:02 +00:00
Zanie Blue d417daad7e
Bump version to v0.1.44 (#3577) 2024-05-14 09:05:31 -05:00
Adolfo Ochagavía 0ef925aa92
Fix typo in traits.rs (#3574)
## Summary

Fixes a typo in a comment

## Test Plan

I assume there's no need to test comment changes, other than having a
human check they make sense. That's what this PR is for 😉
2024-05-14 06:57:38 -05:00
Charlie Marsh 7c1c5df968
Unify editable handling between `sync` and `install` (#3568)
## Summary

Uses the editable handling from `pip sync`, and improves the
abstractions such that we can pass those resolved editables into the
resolver.

---------

Co-authored-by: konstin <konstin@mailbox.org>
2024-05-14 09:18:29 +00:00
Charlie Marsh c666e43b90
Move dry-run method to the top-level (#3567)
Trying to pull out some small, no-op refactors.
2024-05-14 02:28:39 +00:00
konsti 025368965e
Reduce `GitSourceDist` URL usage (#3458)
Refactor the easy-to-remove usage of the `VerbatimUrl` on
`GitSourceDist`
2024-05-14 02:03:55 +00:00
Charlie Marsh 66eea7a5fb
Remove unused `installed` field from `Plan` (#3566) 2024-05-14 01:53:48 +00:00
konsti b263fcff9c
Preserve parsed url in ResolvedDist -> Requirement (#3457)
Lose less information in the `ResolvedDist` -> `Requirement` conversion.
2024-05-14 01:47:20 +00:00
konsti a24124571a
Use the term path instead of local file consistently (#3430)
Rename `ParsedLocalFileUrl` to `ParsedPathUrl`, eliminating the term
`LocalFile` in favor of path.
2024-05-14 01:35:52 +00:00
Charlie Marsh 325265ec16
Move `pip` commands into their own module (#3565)
## Summary

Matching the structure of the `project` module and API.
2024-05-14 01:34:14 +00:00
konsti c22c7cad4c
Add parsed URL fields to `Dist` variants (#3429)
Avoid reparsing urls by storing the parsed parts across resolution on
`Dist`.

Part 2 of https://github.com/astral-sh/uv/issues/3408 and part of #3409

Closes #3408
2024-05-14 01:23:27 +00:00
konsti 0010954ca7
Add parsed URL to `PubGrubPackage` (#3426)
Avoid reparsing urls by storing the parsed parts across resolution on
`PubGrubPackage`.

Part 1 of #3408
2024-05-14 00:55:21 +00:00
Charlie Marsh 5132c6a6e2
Bump version to v0.1.43 (#3564) 2024-05-14 00:38:11 +00:00
Charlie Marsh 8cec217eff
Avoid attempting to build editables when fetching metadata (#3563)
## Summary

If we see an editable as a dependency, we currently attempt to fetch its
metadata, when we shouldn't.

Closes https://github.com/astral-sh/uv/issues/3562.
2024-05-14 00:03:53 +00:00
Zanie Blue 88069e1c43
Add test case demonstrating failure with `--only-binary` and dependent editables (#3561)
As discussed at
https://github.com/astral-sh/uv/issues/3513#issuecomment-2108572246

See https://github.com/astral-sh/uv/issues/3562
2024-05-13 19:55:28 -04:00
Charlie Marsh 7ed14fa124
Make isolated a global argument (#3558)
Closes https://github.com/astral-sh/uv/issues/3557.
2024-05-13 17:51:32 +00:00
Charlie Marsh 44363d25c2
Respect constraints on editable dependencies (#3554)
## Summary

Ensures that constraints are enforced for editable requirements.

Closes #3548.
2024-05-13 17:06:27 +00:00
Charlie Marsh 10ec48299e
Add a `PubGrubRequirement` struct (#3553)
## Summary

Formalize some of the patterns in here. No behavior changes, just moving
this method onto a struct.
2024-05-13 16:59:10 +00:00
Charlie Marsh eb8e733790
Rename "constraints" to "dependencies" in resolver (#3552)
## Summary

It's confusing that we use `constraints` here because constraints mean
something else for us (e.g., `--constraint constraints.txt`). These are
really the dependencies of a given `PubGrubPackage` -- the type is even
called `PubGrubDependencies`.
2024-05-13 16:30:16 +00:00
Bas Schoenmaeckers 1218766ea5
Clone individual files on windows ReFS (#3551)
Windows does not support cloning whole directories so clone each file
instead.

closes #3547 

## Test Plan

Ran ` uv pip install setuptools --link-mode=clone` manually
2024-05-13 12:03:39 -04:00
Zanie Blue b596b460a8
Increase verbosity of credential fetch logs (#3550)
So users do not need to turn on trace logging to see fetch results e.g.
https://github.com/astral-sh/uv/issues/3542

This is more reasonable now that we cache fetches.
2024-05-13 15:55:57 +00:00
Charlie Marsh 9a92a3ad37
Apply advisory locks when building source distributions (#3525)
## Summary

I don't love this, but it turns out that setuptools is not robust to
parallel builds: https://github.com/pypa/setuptools/issues/3119. As a
result, if you run uv from multiple processes, and they each attempt to
build the same source distribution, you can hit failures.

This PR applies an advisory lock to the source distribution directory.
We apply it unconditionally, even if we ultimately find something in the
cache and _don't_ do a build, which helps ensure that we only build the
distribution once (and wait for that build to complete) rather than
kicking off builds from each thread.

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

## Test Plan

Ran:

```sh
#!/bin/bash
make_venv(){
    target/debug/uv venv $1
    source $1/bin/activate
    target/debug/uv pip install opentracing --no-deps --verbose
}

for i in {1..8}
do
   make_venv ./$1/$i &
done
```
2024-05-13 10:42:20 -04:00
Charlie Marsh 42c3bfa351
Make `Directory` its own distribution kind (#3519)
## Summary

I think this is overall good change because it explicitly encodes (in
the type system) something that was previously implicit. I'm not a huge
fan of the names here, open to input.

It covers some of https://github.com/astral-sh/uv/issues/3506 but I
don't think it _closes_ it.
2024-05-13 10:03:14 -04:00
Zanie Blue 6bbfe555be
Add test case for `--only-binary` with editable requirement (#3521) 2024-05-13 14:00:11 +00:00
Dimitri Papadopoulos Orfanos d2ee567fe7
Fix a few typos found by codespell (#3543)
<!--
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

Just fix typos.

While `alpha-numeric` is not really a misspelling:
- it is missing from mainstream curated dictionaries, all of them
suggest `alphanumeric`;
- it is less used than `alphanumeric` (more than ⨉10 less) according to
the Google [Ngram
Viewer](https://books.google.com/ngrams/graph?content=alpha-numeric%2Calphanumeric&year_start=1900&year_end=2019&corpus=en-2019);
- it is [missing from
SCOWL](http://app.aspell.net/lookup?dict=en_US-large;words=alpha-numeric).

## Test Plan

CI jobs.
2024-05-13 11:55:10 +00:00
Charlie Marsh 106c3b583c
Add HTTPS and SSH hints to scheme error (#3536)
Closes https://github.com/astral-sh/uv/issues/3483.
2024-05-13 02:14:58 +00:00
Charlie Marsh b6f6f58831
Fix `cfg_attr` ignore for macOS (#3535) 2024-05-13 01:53:04 +00:00
Charlie Marsh e0da977fc9
Get `cargo shear` passing (#3533)
## Summary

Remove a few unused deps, and ignore `flate2` (which we include for
feature control).
2024-05-13 01:43:45 +00:00
Fred Stober 457d4526fa
Update activate_this.py to use runpy instead of exec in the docstring (#3442)
## Summary

runpy.run_path was added in python 2.7 and 3.2 - and every python that
is not EOL supports it.

It is arguably nicer to read and the path is only given once in the
command.

At least right now, runpy - unlike exec with S102 - is not flagged by
any bandit-derived ruff check.
(I guess because it loads from a file instead of a simple string...)

Because of the import, it is also not a one-liner anymore. (But that
could be fixed with an __import__('runpy').run_path...)

## Test Plan

import runpy
runpy.run_path('/path/to/venv/bin/activate_this.py')
2024-05-13 01:21:24 +00:00
Charlie Marsh c2452957f9
Remove unused dependencies (#3527)
Surfaced with `cargo shear`.
2024-05-11 13:33:49 -04:00
Charlie Marsh 2c3a6796aa
Remove unused `seek` methods (#3526) 2024-05-11 17:31:32 +00:00
Charlie Marsh 3b728c16cc
Make cache clearing robust to directories without read permissions (#3524)
## Summary

If you run the script included in the linked issue, then `uv cache
clean`, we hit permissions errors on certain directories created by
`setuptools`. The permissions on those directories look like:

```
❯ sudo ls -l /Users/crmarsh/Library/Caches/uv/built-wheels-v3/pypi/opentracing/2.4.0/M-fYsaHAaQQvedmPMUl9D/opentracing-2.4.0.tar.gz/build/bdist.macosx-14.2-arm64/wheel/opentracing
Password:
total 0
drwxr-xr-x  3 crmarsh  staff  96 May 11 12:51 harness
```

This PR adds logic to make those directories readable by the current
user.

Closes https://github.com/astral-sh/uv/issues/3515.
2024-05-11 17:02:25 +00:00
Charlie Marsh 1ba3414dd6
Avoid keyword arguments for PEP 517 build hooks (#3517)
## Summary

pip passes these as positional arguments, and at least one build backend
relies on that. My personal opinion is that it's a spec violation, and
the build backend should be updated, but I'd prefer to favor
compatibility over strictness here.

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

## Test Plan

`cargo run pip install cryptacular==1.6.2`
2024-05-10 17:15:08 -04:00
konsti 45a2594de6
Allow unknown pyproject.toml fields (#3511)
Fixes #3510, we use typo error messages though.

Tested manually by adding `[tool.uv.pip]`, we should add proper tests
for this feature.
2024-05-10 18:50:24 +00:00
Ibraheem Ahmed 783df8f657
Consolidate concurrency limits (#3493)
## Summary

This PR consolidates the concurrency limits used throughout `uv` and
exposes two limits, `UV_CONCURRENT_DOWNLOADS` and
`UV_CONCURRENT_BUILDS`, as environment variables.

Currently, `uv` has a number of concurrent streams that it buffers using
relatively arbitrary limits for backpressure. However, many of these
limits are conflated. We run a relatively small number of tasks overall
and should start most things as soon as possible. What we really want to
limit are three separate operations:
- File I/O. This is managed by tokio's blocking pool and we should not
really have to worry about it.
- Network I/O.
- Python build processes.

Because the current limits span a broad range of tasks, it's possible
that a limit meant for network I/O is occupied by tasks performing
builds, reading from the file system, or even waiting on a `OnceMap`. We
also don't limit build processes that end up being required to perform a
download. While this may not pose a performance problem because our
limits are relatively high, it does mean that the limits do not do what
we want, making it tricky to expose them to users
(https://github.com/astral-sh/uv/issues/1205,
https://github.com/astral-sh/uv/issues/3311).

After this change, the limits on network I/O and build processes are
centralized and managed by semaphores. All other tasks are unbuffered
(note that these tasks are still bounded, so backpressure should not be
a problem).
2024-05-10 12:43:08 -04:00
Andrew Gallant eab2b832a6
uv-resolver: make hashes optional (#3505)
This only makes hashes optional for wheels/sdists that come from
registires or direct URLs. For wheels/sdists that come from other
sources, a hash should not be present.

For path dependencies, a hash should not be present because the state of
the path dependency is not intended to be tracked in the lock file. This
is consistent with how other tools deal with path dependencies, and if
it were otherwise, the hash would I believe need to be updated for every
change to the path dependency.

For git dependencies (source dists only), a hash should not be present
because the lock will contain the specific commit revision hash. This is
functionally equivalent to a hash, and so a hash is redundant.

As part of this change, we validate the presence or absence of a hash
based on the dependency source. We also add our first regression tests.
2024-05-10 10:32:30 -04:00
Charlie Marsh 835ebe60c6
Create virtualenv if it doesn't exist in project API (#3499)
## Summary

This doesn't yet respect `--python` or the `requires-python` in the
project itself.

Closes #3449.
2024-05-10 14:10:13 +00:00
konsti 5f8c3b7e45
Re-add dummy serde feature to pep440-rs and pep508-rs (#3501)
This keeps us in sync with the published pep440-rs and pep508-rs crates
for prefix.
2024-05-10 13:46:29 +00:00
Chan Kang 76a39c76f5
add `sys_path` to `Interpreter` struct (#3500)
<!--
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
likely necessary to resolve https://github.com/astral-sh/uv/issues/2500

made this a separate PR in an attempt to make the changes as small as
possible; let me know if it's preferred to keep them as a single PR.
<!-- What's the purpose of the change? What does it do, and why? -->

## Test Plan
- edited the test in `interpreter.rs`
- tested manually via `println!` 

```
$ cargo run --quiet pip show test
["/Users/chankang/Library/Caches/uv/.tmpKzNEPN", "/Users/chankang/.pyenv/versions/3.12.2/lib/python312.zip", "/Users/chankang/.pyenv/versions/3.12.2/lib/python3.12", "/Users/chankang/.pyenv/versions/3.12.2/lib/python3.12/lib-dynload", "/Users/chankang/repos/uv/.venv/lib/python3.12/site-packages"]
warning: Package(s) not found for: test
chankang@chans-Air ~/repos/uv -  (syspath)
$ git diff
diff --git a/crates/uv-interpreter/src/environment.rs b/crates/uv-interpreter/src/environment.rs
index 33b785ce..8ebf0864 100644
--- a/crates/uv-interpreter/src/environment.rs
+++ b/crates/uv-interpreter/src/environment.rs
@@ -106,6 +106,7 @@ impl PythonEnvironment {
     /// Some distributions also create symbolic links from `purelib` to `platlib`; in such cases, we
     /// still deduplicate the entries, returning a single path.
     pub fn site_packages(&self) -> impl Iterator<Item = &Path> {
+        println!("{:?}", self.interpreter.sys_path());
         if let Some(target) = self.interpreter.target() {
             Either::Left(std::iter::once(target.root()))
         } else {
chankang@chans-Air ~/repos/uv -  (syspath)
$ python -c "import sys; print(sys.path)"
['', '/Users/chankang/.pyenv/versions/3.12.2/lib/python312.zip', '/Users/chankang/.pyenv/versions/3.12.2/lib/python3.12', '/Users/chankang/.pyenv/versions/3.12.2/lib/python3.12/lib-dynload', '/Users/chankang/.pyenv/versions/3.12.2/lib/python3.12/site-packages']
chankang@chans-Air ~/repos/uv -  (syspath)
```

<!-- How was it tested? -->
2024-05-10 08:41:32 +02:00
Charlie Marsh d68b740af7
Read and write `uv.lock` based on project root (#3497)
## Summary

The `uv.lock` location is no longer based on the current working
directory, but rather, on the discovered project name.
2024-05-09 19:54:10 +00:00
Charlie Marsh 3dd34e218a
Read package name from `pyproject.toml` in `uv run` (#3496)
## Summary

Right now, the project name is hard-coded.

Closes https://github.com/astral-sh/uv/issues/3491.
2024-05-09 19:42:53 +00:00
Charlie Marsh 51f4ab1c8d
Use defaults in `RequirementsSpecification` constructors (#3495) 2024-05-09 19:27:59 +00:00
Charlie Marsh 3bd89ce5b3
Discover `uv run` projects hierarchically (#3494)
## Summary

Ensures that running `uv run` in a subdirectory of a project behaves
just as-if in the project root.

Closes https://github.com/astral-sh/uv/issues/3490.
2024-05-09 19:16:07 +00:00
Andrew Gallant ad01a768bc
uv-resolver: push resolver state to its own type (#3492)
This still keeps the resolver state on the stack, but it organizes it
into a more structured representation. This is a precursor to
implementing resolver forking, where we will ultimately put this state
on the heap. The idea is that this will let us maintain multiple
independent resolver states that will all produce their own resolution
(and potentially other forked states).

Closes #3354
2024-05-09 14:16:43 -04:00
Charlie Marsh 2d70303d56
Rebrand workspace API as project API (#3489)
## Summary

I've started to refer to this as the "project" API in various places, it
seems less duplicative than the "workspace" API which is a little
different.
2024-05-09 13:05:31 -04:00
Zanie Blue 7585c8be5d
Add test case for authenticated index url from requirements file (#3485)
Investigating https://github.com/astral-sh/uv/issues/3471
2024-05-09 11:33:15 -05:00
Charlie Marsh f342d39f8c
Change error value detection for glibc (#3487)
## Summary

See: #3486. This just fixes the error message, not the underlying bug.
2024-05-09 15:24:03 +00:00
Andrew Gallant 58d1cd2acb pep508: use Arc inside of MarkerEnvironment
Now that the type is fully encapsulated, we can pretty easily
migrate to using an Arc inside of a MarkerEnvironment.

It looks like the pyo3 macros can't deal with an Arc, so we
write out the getter methods by hand.
2024-05-09 10:06:02 -04:00
Andrew Gallant 7d67b7bb49 pep508: un-export fields for MarkerEnvironment
We now use the getters and setters everywhere.

There were some places where we wanted to build a `MarkerEnvironment`
out of whole cloth, usually in tests. To facilitate those use cases, we
add a `MarkerEnvironmentBuilder` that provides a convenient constructor.
It's basically like a `MarkerEnvironment::new`, but with named
parameters. That's useful here because there are so many fields (and
they many have the same type).
2024-05-09 10:06:02 -04:00
Andrew Gallant be12cfb2b8 pep508: add getters and setters to MarkerEnvironment
This preps a change over to a world where MarkerEnvironment is fully
encapsulated. To facilitate this, we add getters and setters for each
field.
2024-05-09 10:06:02 -04:00
Andrew Gallant 342cac8b18 pep508: fix pyo3 related failing test
This test was failing on master. I guess we don't test
this crate with the pyo3 feature enabled? I think this
regression was due to a recent change in the error reporting
of the pep440 crate.
2024-05-09 10:06:02 -04:00
Charlie Marsh b6bb2ac548
Remove `Optional` from `with_origin` API (#3482) 2024-05-09 13:40:51 +00:00
Charlie Marsh 3e4365301e
Track origin for setup.py files and friends (#3481)
## Summary

Ensures that we track the origins for requirements regardless of whether
they come from `pyproject.toml` or `setup.py` or `setup.cfg`.

Closes #3480.
2024-05-09 09:30:40 -04:00
Andrew Gallant 8b0fad3560 uv-resolver: make MarkerEnvironment optional
This commit touches a lot of code, but the conceptual change here is
pretty simple: make it so we can run the resolver without providing a
`MarkerEnvironment`. This also indicates that the resolver should run in
universal mode. That is, the effect of a missing marker environment is
that all marker expressions that reference the marker environment are
evaluated to `true`. That is, they are ignored. (The only markers we
evaluate in that context are extras, which are the only markers that
aren't dependent on the environment.)

One interesting change here is that a `Resolver` no longer needs an
`Interpreter`. Previously, it had only been using it to construct a
`PythonRequirement`, by filling in the installed version from the
`Interpreter` state. But we now construct a `PythonRequirement`
explicitly since its `target` Python version should no longer be tied to
the `MarkerEnvironment`. (Currently, the marker environment is mutated
such that its `python_full_version` is derived from multiple sources,
including the CLI, which I found a touch confusing.)

The change in behavior can now be observed through the
`--unstable-uv-lock-file` flag. First, without it:

```
$ cat requirements.in
anyio>=4.3.0 ; sys_platform == "linux"
anyio<4 ; sys_platform == "darwin"
$ cargo run -qp uv -- pip compile -p3.10 requirements.in
anyio==4.3.0
exceptiongroup==1.2.1
    # via anyio
idna==3.7
    # via anyio
sniffio==1.3.1
    # via anyio
typing-extensions==4.11.0
    # via anyio
```

And now with it:

```
$ cargo run -qp uv -- pip compile -p3.10 requirements.in --unstable-uv-lock-file
  x No solution found when resolving dependencies:
  `-> Because you require anyio>=4.3.0 and anyio<4, we can conclude that the requirements are unsatisfiable.
```

This is expected at this point because the marker expressions are being
explicitly ignored, *and* there is no forking done yet to account for
the conflict.
2024-05-09 09:24:37 -04:00
Andrew Gallant 21f5999b57 pep508: provide extra-only marker evaluation
We provide a new API on a `Requirement` that specifically
ignores the marker environment and only evaluates a requirement's
marker expression with respect to extras. Any marker expressions
that reference the marker environment automatically evaluate to
true.

Instead of duplicating the evaluation code, we just make a marker
environment optional on the lower level APIs. In theory, we could
just writer a separate evaluation routine that ignores everything
except extras, but the evaluator has a fair bit of other stuff in it
(such as emitting warnings) that would be good to keep DRY IMO.
2024-05-09 09:24:37 -04:00
Andrew Gallant 624f92b3f8 pep508: fix doc test
This doc test seems to fail due to the recent change making
`Requirement` generic on its URL type. While the type parameter
was given a default of `VerbatimUrl`, this default doesn't always
apply. For example, the `FromStr` impl on `Requirement` is still
generic on any URL type, and so callers must indicate the type
of the URL to return. (An alternative would be to define the
`FromStr` impl for just the default URL type.)
2024-05-09 09:24:37 -04:00
Charlie Marsh 3d7a0a2ba1
Filter irrelevant requirements from source annotations (#3479)
## Summary

If a requirement is omitted due to a marker expression, we shouldn't
include it as the "source" of a package in the output.

For example, if your constraints include `pathspec ; python_version <
'3.12'`, and you're on Python 3.12, we should _not_ include the
constraint file as a "source" in the output annotations.
2024-05-09 04:51:23 +00:00
Charlie Marsh f16cbfda7e
Add a dedicated struct for source annotations (#3478) 2024-05-09 04:40:35 +00:00
Charlie Marsh d131055d18
Clean up and document some requirements.txt filters (#3477) 2024-05-08 23:55:54 -04:00
Charlie Marsh 5ad373b2ec
Skip Python 2 versions when locating Python (#3476)
## Summary

Unfortunately, the `-I` flag was added in Python 3.4. So if we query a
Python version prior to 3.4 (e.g., Python 2.7), we can't run our script
at all, and lose the ability to match against our structured error.

This PR adds an additional check against the stderr output for these
cases.

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

## Test Plan

Installed Python 2.7, and verified that it was skipped (and that we
instead found my `python3`).
2024-05-09 03:25:21 +00:00
Tom Parker-Shemilt bc963d13cb
Annotate sources of requirements (#3269)
## Summary

Fixes https://github.com/astral-sh/uv/issues/1343. This is kinda a first
draft at the moment, but does at least mostly work locally (barring some
bits of the test suite that seem to not work for me in general).

## Test Plan

Mostly running the existing tests and checking the revised output is
sane

## Outstanding issues

Most of these come down to "AFAIK, the existing tools don't support
these patterns, but `uv` does" and so I'm not sure there's an existing
good answer here! Most of the answers so far are "whatever was easiest
to build"

- [x] ~~Is "-r pyproject.toml" correct? Should it show something else or
get skipped entirely~~ No it wasn't. Fixed in
3044fa8b86
- [ ] If the requirements file is stdin, that just gets skipped. Should
it be recorded?
- [ ] Overrides get shown as "--override<override.txt>". Correct?
- [x] ~~Some of the tests (e.g.
`dependency_excludes_non_contiguous_range_of_compatible_versions`) make
assumptions about the order of package versions being outputted, which
this PR breaks. I'm not sure if the text is fairly arbitrary and can be
replaced or whether the behaviour needs fixing?~~ - fixed by removing
the custom pubgrub PartialEq/Hash
- [ ] Are all the `TrackedFromStr` et al changes needed, or is there an
easier way? I don't think so, I think it's necessary to track these sort
of things fairly comprehensively to make this feature work, and this
sort of invasive change feels necessary, but happy to be proved wrong
there :)
- [x] ~~If you have a requirement coming in from two or more different
requirements files only one turns up. I've got a closed-source example
for this (can go into more detail if needed), mostly consisting of a
complicated set of common deps creating a larger set. It's a rarer case,
but worth considering.~~ 042432b200
- [ ] Doesn't add annotations for `setup.py` yet
- This is pretty hard, as the correct location to insert the path is
`crates/pypi-types/src/metadata.rs`'s `parse_pkg_info`, which as it's
based off a source distribution has entirely thrown away such matters as
"where did this package requirement get built from". Could add "`built
package name`" as a dep, but that's a little odd.
2024-05-08 23:19:22 -04:00
Charlie Marsh 367958e6b2
Bump version to v0.1.42 (#3472) 2024-05-08 17:47:16 -04:00
Charlie Marsh fa4328880b
Use environment layering for `uv run --with` (#3447)
## Summary

This PR takes a different approach to `--with` for `uv run`. Now,
instead of merging the requirements and re-resolving, we have two
phases: (1) sync the workspace requirements to the workspace
environment; then (2) sync the ephemeral `--with` requirements to an
ephemeral environment. The two environments are then layered by setting
the `PATH` and `PYTHONPATH` variables appropriately.

I think this approach simplifies a few things:

1. Once we have a lockfile, the semantics are much clearer, and we can
actually reuse it for the workspace. If we had to add arbitrary
dependencies via `--with`, then it's not really clear how the lockfile
would/should behave.
2. Caching becomes simpler, because we can just cache the ephemeral
environment based on the requirements.

The current version of this PR loses a few behaviors though that I need
to restore:

- `--python` support -- but I'm not yet sure how this is supposed to
behave within projects? It's also left unclear in `uv sync` and `uv
lock`.
- The "reuse the workspace environment if it already satisfies the
ephemeral requirements" behavior.

Closes #3411.
2024-05-08 21:24:24 +00:00
Charlie Marsh 7d41e7d260
Respect `MACOSX_DEPLOYMENT_TARGET` in `--python-platform` (#3470)
## Summary

This is universal environment variable used to determine the mac OS
deployment target. We now respect it in `--python-platform` -- so we
default to 12.0, but users can override it as needed.
2024-05-08 20:03:41 +00:00
Charlie Marsh ca809addf8
Use last non-EOL version for `--python-platform` macOS (#3469)
## Summary

I think, as a a rule, we can just use the last non-EOL version here for
x86 and ARM.

Closes https://github.com/astral-sh/uv/issues/3454.
2024-05-08 19:54:40 +00:00
Charlie Marsh a3c98e8e52
Disallow `pyproject.toml` files for non-project configuration (#3463)
## Summary

We already _don't_ discover a `pyproject.toml` in `~/.config/uv` -- it
must be `uv.toml`. This PR makes the same change for `--config-file` --
it _has_ to be a `uv.toml`.

I think this is reasonable and more consistent, though I'm not sure. A
`pyproject.toml` "means" something -- it defines a project itself, in
which case we should be using project configuration. But creating a
`pyproject.toml` outside the project and passing it via `--config-file`
seems like an anti-pattern.
2024-05-08 14:49:52 -04:00
Charlie Marsh 1aa8ff8268
Merge user and workspace settings (#3462)
## Summary

This PR follows Cargo's strategy for merging configuration, albeit in a
more limited way (we don't support as many configuration locations).
Specifically, we merge the user configuration with the workspace
configuration if both are present. The workspace configuration has
priority, such that we take values from the workspace configuration and
ignore those in the user configuration if both are specified for a given
setting -- with the exception of arrays and maps, which are
concatenated.

For now, if a user provides a configuration file with `--config-file`,
we _don't_ merge in the user settings.

See:
https://doc.rust-lang.org/cargo/reference/config.html#hierarchical-structure.

Closes #3420.
2024-05-08 14:49:43 -04:00
Charlie Marsh 74f53729d8
Set stack size for remaining `install` and `sync` tests (#3464)
## Summary

These are failing on various branches now.

## Test Plan

`cargo test`
2024-05-08 14:05:07 -04:00
Charlie Marsh b2adb96ec7
Ignore `compile_invalid_pyc_invalidation_mode` on macOS (#3465)
## Summary

This is annoying both locally in CI. If anyone wants to fuss with the
filters to fix it, that's fine too, but IMO it's better to disable than
leave it enabled on macOS for now.
2024-05-08 14:04:57 -04:00
konsti 7c7c9e2189
Warn when missing minimal bounds when using `tool.uv.sources` (#3452)
When using `tool.uv.sources`, we warn that requirements have a bound,
i.e. at least a lower version constraint.

When using a library, the symbols you import were introduced in
different versions, creating an implicit lower bound. This warning makes
this explicit. This is crucial to prevent backtracking resolvers from
selecting an ancient versions that is not compatible (or worse, doesn't
build), and a performance optimization on top.

This feature is gated to `tool.uv.sources` (as it should have been to
begin with for #3263/#3443) to not unnecessarily break legacy workflows.
It is also helpful specifically when using a `tool.uv.sources` section
that contains constraints that are not published to pypi, e.g. for
workspace dependencies. We can adjust those later to e.g. not constrain
workspace dependencies with `publish = false`, but i think it's the
right setting to start with.
2024-05-08 13:16:25 -04:00
Charlie Marsh 7c6632114b
Improve JSON Schema and add export script (#3461)
## Summary

A few errors I noticed after generating the schema.
2024-05-08 16:15:16 +00:00
Charlie Marsh 18d229e2bb
Upgrade `async_http_range_reader` to v0.8.0 (#3460)
## Summary

Closes #2025.
Closes https://github.com/astral-sh/uv/issues/3255.
Closes https://github.com/astral-sh/uv/pull/2843.
2024-05-08 10:54:08 -04:00
Charlie Marsh 76a3ceb2ca
Add basic `uv sync` and `uv lock` commands (#3436)
## Summary

These aren't intended for production use; instead, I'm just trying to
frame out the overall data flows and code-sharing for these commands. We
now have `uv sync` (sync the environment to match the lockfile, without
refreshing or resolving) and `uv lock` (generate the lockfile). Both
_require_ a virtual environment to exist (something we should change).
`uv sync`, `uv run`, and `uv lock` all share code for the underlying
subroutines (resolution and installation), so the commands themselves
are relatively small (~100 lines) and mostly consist of reading
arguments and such.

`uv lock` and `uv sync` don't actually really work yet, because we have
no way to include the project itself in the lockfile (that's a TODO in
the lockfile implementation).

Closes https://github.com/astral-sh/uv/issues/3432.
2024-05-08 14:51:51 +00:00
konsti 0228b15baf
Improve trailing version string error message (#3453)
We would previously show the parsed version when erroring due to
trailing content after a valid version, which can look different than
the input. E.g. when encountering `0.1-bulbasaur`, we would display:

```
after parsing '0.1b0', found 'ulbasaur', which is not part of a valid version
```

With storing the input string instead of the input version, we now show:

```
after parsing '0.1-b', found 'ulbasaur', which is not part of a valid version
```
2024-05-08 14:50:29 +02:00
Shantanu 5a07923eb4
Use Metadata10 to parse PKG-INFO of legacy editable (#3450)
It turns out setuptools often uses Metadata-Version 2.1 in their
PKG-INFO:
4e766834d7/setuptools/dist.py (L64)
`Metadata23` requires Metadata-Version of at least 2.2.

This means that uv doesn't actually recognise legacy editable
installations from the most common way you'd actually get legacy
editable installations (works great for most legacy editables I make at
work though!)

Anyway, over here we only need the version and don't care about anything
else. Rather than make a `Metadata21`, I just add a version field to
`Metadata10`. The one slightly tricky thing is that only
Metadata-Version 1.2 and greater guarantee that the [version number is
PEP 440 compatible](https://peps.python.org/pep-0345/#version), so I
store the version in `Metadata10` as a `String` and only parse to
`Version` at time of use.

Also did you know that back in 2004, paramiko had a pokemon based
versioning system?
2024-05-08 10:58:18 +02:00
Shantanu 962fde29b2
Apply normcase to line from easy-install.pth (#3451)
Thanks for the suggestion from
https://github.com/astral-sh/uv/pull/3415#discussion_r1591772942

Also it looks like you improved `egg-link` parsing in
e23c91f52e
so copying the changes over to the other parse site (happy to move this
to a helper too, if so lmk where to put it)
2024-05-08 10:40:21 +02:00
konsti 1ad6aa8a23
Use generic pubgrub incompatibility reason (#3335)
Pubgrub got a new feature where all unavailability is a custom, instead
of the reasonless `UnavailableDependencies` and our custom `String` type
previously (https://github.com/pubgrub-rs/pubgrub/pull/208). This PR
introduces a `UnavailableReason` that tracks either an entire version
being unusable, or a specific version. The error messages now also track
this difference properly.

The pubgrub commit is our main rebased onto the merged
https://github.com/pubgrub-rs/pubgrub/pull/208, i'll push
`konsti/main-rebase-generic-reason` to `main` after checking for rebase
problems.
2024-05-08 08:40:15 +00:00
Charlie Marsh bd7860de17
Remove some `allow(unused)` (#3448) 2024-05-07 22:19:07 -04:00
Charlie Marsh b0d7a26431
Bump version to v0.1.41 (#3446) 2024-05-08 01:05:47 +00:00
Charlie Marsh 49937a386d
Remove unconstrained version error from requirements (#3443)
## Summary

It's not clear to me that this should exist at all, but it's causing
errors in projects that don't use `tool.uv.sources`, so we should
definitely remove it for now.
2024-05-07 20:04:44 -04:00
DaniPopes c59cb1381a
Use `into_par_iter` instead of `par_bridge` (#3435)
## Summary

Use the native rayon range iterator instead of bridging the standard
library's.
2024-05-07 19:38:35 +00:00
Charlie Marsh d665410d59
Move PyO3 derive down (#3434)
## Summary

For some reason the current order is breaking the IntelliJ LSP.
2024-05-07 18:16:28 +00:00
Charlie Marsh e8b423de77
Use top-level `--isolated` for `uv run` (#3431)
## Summary

We already have a global `--isolated`, which means "ignore any on-disk
configuration". I think we should reuse this for the "ignore the
workspace" setting in `uv run`, rather than `--no-workspace`.

I've also merged the existing `--isolated` and `--no-workspace`
behaviors in `uv run` into a single flag. We may not need separate flags
for this, since the current intent seems to be "ignore the workspace
environment"? Though we could always re-add later.

Closes https://github.com/astral-sh/uv/issues/3421.
2024-05-07 13:30:02 -04:00
Charlie Marsh 7fe9f0a3dd
Bump version to v0.1.40 (#3433) 2024-05-07 17:29:29 +00:00
Charlie Marsh f8a7813add
Rename `--force` to `--allow-existing` (#3416)
## Summary

We've found `--force` to be a confusing name here. (Not breaking as this
hasn't shipped in a release.)
2024-05-07 17:11:31 +00:00
konsti f8901e9989
Always activate non-pep508-extensions (#3428)
Avoid compilation errors when running partial tests due to that feature
being missing.
2024-05-07 16:13:09 +00:00
Ahmed Ilyas 388dba4815
add compat arg --user error message to pip install (#3424)
Resolves [#3419](https://github.com/astral-sh/uv/issues/3419)

## Summary

Add compatargs to pip install command and hint the user to create a venv
for --user arg.

## Test Plan

Tested it locally.

```bash
cargo run pip install --user flask
   Compiling uv v0.1.39 (/home/ahmedilyas/uv/crates/uv)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 8.96s
     Running `target/debug/uv pip install --user flask`
error: pip install's `--user` is unsupported (use a virtual environment instead).
```
2024-05-07 14:59:53 +00:00
konsti 55f6e4e66b
Make `Requirement` generic over url type (#3253)
This change allows switching out the url type for requirements. The
original idea was to allow different types for different requirement
origins, so that core metadata reads can ban non-pep 508 requirements
while we only allow them for requirements.txt. This didn't work out
because we expect `&Requirement`s from all sources to match.

I also tried to split `pep508_rs` into a PEP 508 compliant crate and
into our extensions, but they are to tightly coupled.

I think this change is an improvement still as it reduces the hardcoded
dependence on `VerbatimUrl`.
2024-05-07 16:45:49 +02:00
Zanie Blue 8e86cd0c73
Add hint to use a venv to `pip sync --user` (#3418) 2024-05-07 08:50:23 -05:00
konsti 24f38d7c22
Preserve given for `tool.uv.sources` paths (#3412)
We now correctly emit relative paths in `uv pip compile` with
`tool.uv.sources` path inputs.

`tool.uv.sources` is mainly intended to be used with the uv lock file
over requirements.txt, but it's good to have basic `uv pip` support
working.

Fixes #3366
2024-05-07 09:00:02 +00:00
Shantanu 18516b4e41
List and uninstall legacy editables (#3415) 2024-05-07 03:51:50 +00:00
Ibraheem Ahmed 94cf604574
Remove unnecessary uses of `DashMap` and `Arc` (#3413)
## Summary

All of the resolver code is run on the main thread, so a lot of the
`Send` bounds and uses of `DashMap` and `Arc` are unnecessary. We could
also switch to using single-threaded versions of `Mutex` and `Notify` in
some places, but there isn't really a crate that provides those I would
be comfortable with using.

The `Arc` in `OnceMap` can't easily be removed because of the uv-auth
code which uses the
[reqwest-middleware](https://docs.rs/reqwest-middleware/latest/reqwest_middleware/trait.Middleware.html)
crate, that seems to adds unnecessary `Send` bounds because of
`async-trait`. We could duplicate the code and create a `OnceMapLocal`
variant, but I don't feel that's worth it.
2024-05-06 22:30:43 -04:00
konsti 2c84af15b8
Rename `distribution_types::VersionOrUrl` to `VersionOrUrlRef` (#3254)
This is more consistent with the other `*Ref` types and reduces
confusion with the real `VersionOrUrl` type.
2024-05-06 14:15:56 -04:00
Charlie Marsh ed27dde8a2
Revise comment on virtualenv discovery from cwd (#3406)
See:
37d229b2c2..cd53a28181 (r1590746360)
2024-05-06 14:07:11 +00:00
Charlie Marsh 26045e5f59
Respect and enable uninstalls of existing `.egg-info` packages (#3380)
## Summary

Users often find themselves dropped into environments that contain
`.egg-info` packages. While we won't support installing these, it's not
hard to support identifying them (e.g., in `pip freeze`) and
_uninstalling_ them.

Closes https://github.com/astral-sh/uv/issues/2841.
Closes #2928.
Closes #3341.

## Test Plan

Ran `cargo run pip freeze --python
/opt/homebrew/Caskroom/miniforge/base/envs/TEST/bin/python`, with an
environment that includes `pip` as an `.egg-info`
(`/opt/homebrew/Caskroom/miniforge/base/envs/TEST/lib/python3.12/site-packages/pip-24.0-py3.12.egg-info`):

```
cffi @ file:///Users/runner/miniforge3/conda-bld/cffi_1696001825047/work
pip==24.0
pycparser @ file:///home/conda/feedstock_root/build_artifacts/pycparser_1711811537435/work
setuptools==69.5.1
wheel==0.43.0
```

Then ran `cargo run pip uninstall`, verified that `pip` was uninstalled,
and no longer listed in `pip freeze`.
2024-05-06 09:47:28 -04:00
konsti 098944fc7d
Improve non-git error message (#3403)
The boxing changes are due to clippy
2024-05-06 13:28:05 +02:00
konsti d0c3146ef6
Restore verbatim in error message (#3402)
Fixup for
https://github.com/astral-sh/uv/pull/3263#discussion_r1589718035
2024-05-06 11:17:06 +00:00
konsti b2f6b92e3b
Move pep508-rs `Cursor` into its own module (#3401) 2024-05-06 10:13:27 +00:00
Shantanu 95f31f2266
Better error for unsupported Python version (#3398)
Fixes #3371

It seems like uv doesn't proactively enforce 3.8+ and in most cases just
issues a warning. This PR keeps that property, only adding the new check
when it is known to fail. I checked the imports in this file and the
other ones seem fine.
2024-05-06 11:12:36 +02:00
konsti 9de49c8a60
Make pubgrub an allowed ident (#3399)
Followup to #3361, fix some backtick-quoting.
2024-05-06 09:10:37 +00:00
renovate[bot] c1370cab1b
Update pre-commit dependencies (#3391) 2024-05-06 02:18:51 +00:00
Godefroid Chapelle ef92c38486
Detect current venv when `uv` is invoked from within a virtualenv (#3379)
Fixes #3378.
2024-05-05 22:53:25 +00:00
Charlie Marsh 6d73db2b1e
Use `Cow` for source call (#3377) 2024-05-05 02:21:24 +00:00
Charlie Marsh 37635fda56
Update activation scripts from virtualenv (#3376)
## Summary

Refreshes some of the activation scripts, and fixes some bugs in
`activate_this.py` that were likely the rest of some erroneous
copy-pasting.

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

## Test Plan

```
❯ python
Python 3.12.0 (main, Feb 28 2024, 09:44:16) [Clang 15.0.0 (clang-1500.1.0.2.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import httpx
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'httpx'
>>> activator = '.venv/bin/activate_this.py'
>>> with open(activator) as f:
...     exec(f.read(), {'__file__': activator})
...
>>> import httpx
```
2024-05-04 23:30:00 +00:00
Charlie Marsh 2a212eb6a9
Add branch and tag variants to Git reference (#3374)
## Summary

Closes https://github.com/astral-sh/uv/issues/3368.
2024-05-04 21:13:11 +00:00
Charlie Marsh 69e99b3502
Use canonical URLs in satisfaction check (#3373)
## Summary

Closes https://github.com/astral-sh/uv/issues/3367.
2024-05-04 12:44:25 +00:00
Charlie Marsh 8adf5b11ab
Fix Git URL construction in `tool.uv.sources` (#3365)
## Summary

We were including the `git+` prefix twice:

```
DEBUG At least one requirement is not satisfied: boltons @ git+git+https://github.com/mahmoud/boltons@57fbaa9b673ed85b32458b31baeeae230520e4a0@57fbaa9b673ed85b32458b31baeeae230520e4a0
```

## Test Plan

Extended the test to include a Git URL; verified that we don't trigger a
reinstall.
2024-05-04 03:02:14 +00:00
konsti 44858bc28d
Use preview mode for tool.uv.sources (#3277)
Only allow using `tool.uv.sources` with preview mode, the design isn't
finalized yet.

Not sure what to label this, do we want a preview section and label for
the release notes?
2024-05-04 02:47:47 +00:00
Charlie Marsh 363e808724
Tweak some of the `tool.uv.sources` error messages for consistency (#3364) 2024-05-04 02:38:47 +00:00
Charlie Marsh 100935f4f1
Respect `editable = true` setting in sources map (#3363)
## Summary

We need to partition the editable and non-editable requirements. As-is,
`editable = true` requirements were still being installed as
non-editable.
2024-05-04 02:17:55 +00:00
Charlie Marsh a63018591e
Unset target when creating virtual environments (#3362)
## Summary

We were writing the build dependencies into the `--target` directory,
which both made builds fail and led to them leaking into the user's
directory.

Closes https://github.com/astral-sh/uv/issues/3349.
2024-05-03 23:21:23 +00:00
konsti 4f87edbe66
Add basic `tool.uv.sources` support (#3263)
## Introduction

PEP 621 is limited. Specifically, it lacks
* Relative path support
* Editable support
* Workspace support
* Index pinning or any sort of index specification

The semantics of urls are a custom extension, PEP 440 does not specify
how to use git references or subdirectories, instead pip has a custom
stringly format. We need to somehow support these while still stying
compatible with PEP 621.

## `tool.uv.source`

Drawing inspiration from cargo, poetry and rye, we add `tool.uv.sources`
or (for now stub only) `tool.uv.workspace`:

```toml
[project]
name = "albatross"
version = "0.1.0"
dependencies = [
  "tqdm >=4.66.2,<5",
  "torch ==2.2.2",
  "transformers[torch] >=4.39.3,<5",
  "importlib_metadata >=7.1.0,<8; python_version < '3.10'",
  "mollymawk ==0.1.0"
]

[tool.uv.sources]
tqdm = { git = "https://github.com/tqdm/tqdm", rev = "cc372d09dcd5a5eabdc6ed4cf365bdb0be004d44" }
importlib_metadata = { url = "https://github.com/python/importlib_metadata/archive/refs/tags/v7.1.0.zip" }
torch = { index = "torch-cu118" }
mollymawk = { workspace = true }

[tool.uv.workspace]
include = [
  "packages/mollymawk"
]

[tool.uv.indexes]
torch-cu118 = "https://download.pytorch.org/whl/cu118"
```

See `docs/specifying_dependencies.md` for a detailed explanation of the
format. The basic gist is that `project.dependencies` is what ends up on
pypi, while `tool.uv.sources` are your non-published additions. We do
support the full range or PEP 508, we just hide it in the docs and
prefer the exploded table for easier readability and less confusing with
actual url parts.

This format should eventually be able to subsume requirements.txt's
current use cases. While we will continue to support the legacy `uv pip`
interface, this is a piece of the uv's own top level interface. Together
with `uv run` and a lockfile format, you should only need to write
`pyproject.toml` and do `uv run`, which generates/uses/updates your
lockfile behind the scenes, no more pip-style requirements involved. It
also lays the groundwork for implementing index pinning.

## Changes

This PR implements:
* Reading and lowering `project.dependencies`,
`project.optional-dependencies` and `tool.uv.sources` into a new
requirements format, including:
  * Git dependencies
  * Url dependencies
  * Path dependencies, including relative and editable
* `pip install` integration
* Error reporting for invalid `tool.uv.sources`
* Json schema integration (works in pycharm, see below)
* Draft user-level docs (see `docs/specifying_dependencies.md`)

It does not implement:
* No `pip compile` testing, deprioritizing towards our own lockfile
* Index pinning (stub definitions only)
* Development dependencies
* Workspace support (stub definitions only)
* Overrides in pyproject.toml
* Patching/replacing dependencies

One technically breaking change is that we now require user provided
pyproject.toml to be valid wrt to PEP 621. Included files still fall
back to PEP 517. That means `pip install -r requirements.txt` requires
it to be valid while `pip install -r requirements.txt` with `-e .` as
content falls back to PEP 517 as before.

## Implementation

The `pep508` requirement is replaced by a new `UvRequirement` (name up
for bikeshedding, not particularly attached to the uv prefix). The still
existing `pep508_rs::Requirement` type is a url format copied from pip's
requirements.txt and doesn't appropriately capture all features we
want/need to support. The bulk of the diff is changing the requirement
type throughout the codebase.

We still use `VerbatimUrl` in many places, where we would expect a
parsed/decomposed url type, specifically:
* Reading core metadata except top level pyproject.toml files, we fail a
step later instead if the url isn't supported.
* Allowed `Urls`.
* `PackageId` with a custom `CanonicalUrl` comparison, instead of
canonicalizing urls eagerly.
* `PubGrubPackage`: We eventually convert the `VerbatimUrl` back to a
`Dist` (`Dist::from_url`), instead of remembering the url.
* Source dist types: We use verbatim url even though we know and require
that these are supported urls we can and have parsed.

I tried to make improve the situation be replacing `VerbatimUrl`, but
these changes would require massive invasive changes (see e.g.
https://github.com/astral-sh/uv/pull/3253). A main problem is the ref
`VersionOrUrl` and applying overrides, which assume the same
requirement/url type everywhere. In its current form, this PR increases
this tech debt.

I've tried to split off PRs and commits, but the main refactoring is
still a single monolith commit to make it compile and the tests pass.

## Demo

Adding
d1ae3b85d5/pyproject.json
as json schema (v7) to pycharm for `pyproject.toml`, you can try the IDE
support already:


![pycharm](https://github.com/astral-sh/uv/assets/6826232/599082c7-6be5-41c1-a3cd-516092382f8d)


[dove.webm](https://github.com/astral-sh/uv/assets/6826232/c293c272-c80b-459d-8c95-8c46a8d198a1)
2024-05-03 21:10:50 +00:00
samypr100 2ffb252498
Update Rust to v1.78 (#3361)
## Summary

Updates rust to 1.78 in `rust-toolchain.toml`

See: https://blog.rust-lang.org/2024/05/02/Rust-1.78.0.html

### Potential blockers

* homebre still on 1.77 -
https://github.com/Homebrew/homebrew-core/pull/170649
* conda-forge still on 1.77 - https://anaconda.org/conda-forge/rust
2024-05-03 20:07:13 +00:00
Andrew Gallant 1089abda3f
require serde and rkyv everywhere; remove optional serde and rkyv features (#3345)
In *some* places in our crates, `serde` (and `rkyv`) are optional
dependencies. I believe this was done out of reasons of "good sense,"
that is, it follows a Rust ecosystem pattern where serde integration
tends to be an opt-in crate feature. (And similarly for `rkyv`.)

However, ultimately, `uv` itself requires `serde` and `rkyv` to
function. Since our crates are strictly internal, there are limited
consumers for our crates without `serde` (and `rkyv`) enabled. I think
one possibility is that optional `serde` (and `rkyv`) integration means
that someone can do this:

    cargo test -p pep440_rs

And this will run tests _without_ `serde` or `rkyv` enabled. That in
turn could lead to faster iteration time by reducing compile times. But,
I'm not sure this is worth supporting. The iterative compilation times
of
individual crates are probably fast enough in debug mode, even with
`serde` and `rkyv` enabled. Namely, `serde` and `rkyv` themselves
shouldn't need to be re-compiled in most cases. On `main`:

```
from-scratch: `cargo test -p pep440_rs --lib` 0.685
incremental: `cargo test -p pep440_rs --lib` 0.278s
from-scratch: `cargo test -p pep440_rs --features serde,rkyv --lib` 3.948s
incremental: `cargo test -p pep440_rs --features serde,rkyv --lib` 0.321s
```

So while a from-scratch build does take significantly longer, an
incremental build is about the same.

The benefit of doing this change is two-fold:

1. It brings out crates into alignment with "reality." In particular,
   some crates were _implicitly_ relying on `serde` being enabled
   without explicitly declaring it. This technically means that our
   `Cargo.toml`s were wrong in some cases, but it is hard to observe it
   because of feature unification in a Cargo workspace.
2. We no longer need to deal with the cognitive burden of writing
   `#[cfg_attr(feature = "serde", ...)]` everywhere.
2024-05-03 10:21:03 -04:00
Andrew Gallant 7772e6249f
add basic "install from lock file" operation (#3340)
This PR principally adds a routine for converting a `Lock` to a
`Resolution`, where a `Resolution` is a map of package names pinned to
a specific version.

I'm not sure that a `Resolution` is ultimately what we want here (we
might need more stuff), but this was the quickest route I could find to
plug a `Lock` into our existing `uv pip install` infrastructure.

This commit also does a little refactoring of the `Lock` types. The
main thing is to permit extra state on some of the types (like a
`by_id` map on `Lock` for quick lookups of distributions) that aren't
included in the serialization format of a `Lock`. We achieve this
by defining separate `Wire` types that are automatically converted
to-and-from via `serde`.

Note that like with the lock file format types themselves, we leave a
few `todo!()` expressions around. The main idea is to get something
minimally working without spending too much effort here. (A fair bit
of refactoring will be required to generate a lock file, and it's
not clear how much this code will wind up needing to change anyway.)
In particular, we only handle the case of installing wheels from a
registry.

A demonstration of the full flow:

```
$ requirements.in
anyio
$ cargo run -p uv -- pip compile -p3.10 requirements.in --unstable-uv-lock-file
$ uv venv
$ cargo run -p uv -- pip install --unstable-uv-lock-file anyio -r requirements.in
Installed 5 packages in 7ms
 + anyio==4.3.0
 + exceptiongroup==1.2.1
 + idna==3.7
 + sniffio==1.3.1
 + typing-extensions==4.11.0
```

In order to install from a lock file, we start from the root and do a
breadth first traversal over its dependencies. We aren't yet filtering
on marker expressions (since they aren't in the lock file yet), but we
should be able to add that in the future. In so doing, the traversal
should select only the subset of distributions relevant for the current
platform.
2024-05-03 08:18:36 -04:00
Zanie Blue 49675558eb
Split virtual environment detection into a dedicated module (#3331)
Split out of https://github.com/astral-sh/uv/pull/3266
2024-05-02 06:58:48 -05:00
Zanie Blue c28a2806b3
Separate interpreter selectors into `implementation` and `platform` modules (#3332)
Split out of #3266

The "selector" concept doesn't seem well enough defined as-is. For
example, `PythonVersion` belongs there but isn't present. Going for
smaller modules instead.
2024-05-02 11:55:01 +00:00
Zanie Blue 5048ccef3a
Update toolchain discovery to avoid runtime panic (#3330)
Split out of https://github.com/astral-sh/uv/pull/3266

If `UV_BOOTSTRAP_DIR` and `CARGO_MANIFEST_DIR` are both unset, we
currently panic. This isn't good once we start to use managed toolchains
in production. We'll need to change this more later once the toolchain
directory is more user-facing.
2024-05-02 06:44:16 -05:00
Zanie Blue 528bed5bed
Move `py` launcher handling into separate module (#3329)
Split out of #3266 

Mostly an organizational change, with some error handling
simplification.
2024-05-02 06:44:07 -05:00
konsti 2e27abd34a
Remove `Into::into` (#3337)
Motivated by
https://github.com/astral-sh/uv/pull/3263#discussion_r1585896159

I don't think we can lint againt this since we do want to allow
`.into()`, just not the bare `Into::into` call.
2024-05-02 10:26:42 +00:00
konsti 538a85b827
Add missing optional rkyv feature bound (#3336)
`PackageName` needs to derive the rkyv types.
2024-05-02 10:01:10 +00:00
Charlie Marsh c6137702a5
Accept `--no-upgrade`, `--no-refresh`, etc. on the CLI (#3328)
## Summary

We added `--no-X` variants for all other flags, but omitted these. Seems
more consistent to support them.

Closes https://github.com/astral-sh/uv/issues/1900.
2024-05-01 11:13:33 -07:00
Charlie Marsh 614c07329b
Allow `--force` to overwrite existing virtualenv (#2548)
## Summary

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

## Test Plan

- `mkdir .venv`
- `touch .venv/foo`
- `cargo run venv` (ensure failure)
- `cargo run venv --force` (ensure success)
- `cargo run venv --force` (ensure success again)
2024-05-01 16:34:52 +00:00
Zanie Blue 630d3fde5c
Merge `uv-toolchain` and `uv-interpreter` (#3265)
Moves all of `uv-toolchain` into `uv-interpreter`. We may split these
out in the future, but the refactoring I want to do for interpreter
discovery is easier if I don't have to deal with entanglement. Includes
some restructuring of `uv-interpreter`.

Part of #2386
2024-04-30 17:49:46 +00:00
Ibraheem Ahmed 1d2c57a259
Run resolve/install benchmarks in ci (#3281)
## Summary

Runs resolver benchmarks in CI with CodSpeed.
2024-04-30 13:39:42 -04:00
Zanie Blue 100dbe475c
Quote version parse errors consistently (#3325) 2024-04-30 12:20:14 -05:00