Commit graph

2395 commits

Author SHA1 Message Date
Ibraheem Ahmed
348efa26ba
Clean up uv pip tree code (#4700)
## Summary

Minor improvements/nits.
2024-07-01 17:56:16 +00:00
Ibraheem Ahmed
58499439d3
Fix implementation of GitDatabase::contains (#4698)
## Summary

`GitDatabase::contains` previously only parsed the commit to see if it
was a valid hash and didn't verify if the commit existed in the object
database. This led to the database never being updated.

Resolves https://github.com/astral-sh/uv/issues/4378.

## Test Plan

Added a test that fails without this change.
2024-07-01 13:01:29 -04:00
Chan Kang
5715def24b
Implement --invert for pip tree (#4621)
## Summary

Part of https://github.com/astral-sh/uv/issues/4439.

## Test Plan

Existing tests pass + added a couple of new tests with `--invert`.
2024-07-01 12:58:28 -04:00
konsti
0ee4a2cc6e
Remove SolveState to ForkState (#4683)
It's hard to talk about solve state and resolver state, so i'm renaming
them to fork state and resolver state, indicating the hierarchy between
more directly.
2024-07-01 12:33:50 -04:00
Charlie Marsh
305868cdcc
Show dedicated message for tools with no entrypoints (#4694)
## Summary

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

## Test Plan

```
❯ cargo run tool install ruff
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.14s
     Running `target/debug/uv tool install ruff`
warning: `uv tool install` is experimental and may change without warning.
Resolved 1 package in 136ms
Installed 1 package in 3ms
 + ruff==0.5.0
No entrypoints to install for tool `ruff`
```
2024-07-01 12:22:45 -04:00
Charlie Marsh
324e9fe5cf
Respect data scripts in uv tool install (#4693)
## Summary

Packages that provide scripts that _aren't_ Python entrypoints need to
respected in `uv tool install`. For example, Ruff ships a script in
`ruff-0.5.0.data/scripts`.

Unfortunately, the `.data` directory doesn't exist in the virtual
environment at all (it's removed, per the spec, after install). So this
PR changes the entry point detection to look at the `RECORD` file, which
is the only evidence that the scripts were installed.

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

## Test Plan

`cargo run uv tool install ruff` (snapshot tests to-come)
2024-07-01 12:22:37 -04:00
Ahmed Ilyas
081f092781
Add tool dir and toolchain dir commands (#4695)
## Summary

Resolves #4483 
Resolves #4484 

## Test Plan

`cargo test`

```sh
❯ cargo run -- toolchain dir
warning: `uv toolchain dir` is experimental and may change without warning.
/Users/ahmedilyas/Library/Application Support/uv/toolchains

❯ cargo run -- tool dir
warning: `uv tool dir` is experimental and may change without warning.
/Users/ahmedilyas/Library/Application Support/uv/tools
```
2024-07-01 14:51:59 +00:00
Charlie Marsh
65cd676da7
Reinstall entrypoints with --force (#4697)
## Summary

I think this may have just been a typo.

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

## Test Plan

Run `cargo run tool install flask --force --reinstall` repeatedly.
2024-07-01 14:25:11 +00:00
Charlie Marsh
977a5c8835
Use a single mutable preferences for forks (#4690)
## Summary

Avoids a quadratic loop.

See: https://github.com/astral-sh/uv/pull/4662.
2024-07-01 12:47:28 +00:00
Charlie Marsh
1557ad1b3c
DRY up some project interpreter validation and discovery (#4658)
## Summary

I noticed that `init_environment` and `find_interpreter` were both
calling `find_environment`, which seemed like a code smell to me.
Instead, `find_interpreter` now returns either a compatible environment
or an interpreter (if no compatible environment was found).

Additionally, `interpreter_meets_requirements` now no longer validates
`requires-python` if `--python` or `.python-version` is set. Instead, we
warn, which matches the behavior we get when creating a new environment
at the bottom of `find_interpreter`.

In total, I think this makes the data flow in project interpreter
discovery less repetitive and easier to reason about.
2024-07-01 12:31:42 +00:00
Charlie Marsh
2d57309b0f
Set fork solution as preference when resolving (#4662)
## Summary

This should both make it faster to solve forks (since we have a guess
for a valid resolution, and will bias towards packages we've already
fetched) and improve consistency between forks.

Closes https://github.com/astral-sh/uv/issues/4617.
2024-07-01 08:25:40 -04:00
Charlie Marsh
bfadadefaf
Add PEP 723 support to uv run (#4656)
Closes #3096 

## Summary

Enables `uv run foo.py` to execute PEP 723-compatible scripts.

For example, given:

```python
# /// script
# requires-python = ">=3.11"
# dependencies = [
#   "requests<3",
#   "rich",
# ]
# ///

import requests
from rich.pretty import pprint

resp = requests.get("https://peps.python.org/api/peps.json")
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])
```

![Screenshot 2024-06-29 at 7 23
52 PM](c60f2415-4874-4b15-b9f5-dd8c8c35382e)
2024-07-01 08:20:24 -04:00
konsti
bbd2deb64f
Fix tool dist-info directory normalization (#4686)
`.dist-info` directories use a different normalization.

Fixes #4685
2024-07-01 10:43:56 +00:00
konsti
049833e037
Log when we start solving a fork (#4684)
Adds a debug log message with the markers.
2024-07-01 08:46:54 +00:00
Charlie Marsh
8ea47ab45f
Add --disable-pip-version-check to compatibility arguments (#4672)
## Summary

Closes https://github.com/astral-sh/uv/issues/4590.
2024-06-30 23:43:23 +00:00
Charlie Marsh
d5501274d8
Omit (*) in uv pip tree for empty packages (#4673)
## Summary

Closes https://github.com/astral-sh/uv/issues/4665.
2024-06-30 23:42:06 +00:00
Charlie Marsh
ac87fd4006
Disable Clippy's too-many-arguments rule (#4663)
## Summary

We allow this constantly, I think it's just too pedantic for us.
2024-06-30 19:30:38 +00:00
Charlie Marsh
b4c53fd15f
Add a command abstraction to uv run (#4657)
## Summary

Small refactor broken out from #4656.
2024-06-30 10:40:37 -04:00
Chan Kang
7cc4565b5b
fix the issue with pruning the last package in pip tree (#4652)
<!--
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
resolves https://github.com/astral-sh/uv/issues/4651
(pruning needs to happen at the parent level so that the number of
children being used to figure out the output is correct)

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

## Test Plan
added a test that would've caught this bug 🌵 
<!-- How was it tested? -->
2024-06-29 17:45:34 -05:00
Charlie Marsh
13b0beb56f
Bump version to v0.2.18 (#4650) 2024-06-29 14:30:01 -04:00
Zanie Blue
7da3423af9
Add uv tool uninstall (#4641)
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2024-06-29 17:50:20 +00:00
Charlie Marsh
8d9b4a5e1c
Sort indexes during graph edge removal (#4649)
## Summary

`remove_edge` will invalidate the last index in the graph, so we need to
ensure that each index we look at is "earlier" than the last.

Co-authored-by: bluss <bluss@users.noreply.github.com>
2024-06-29 13:31:54 -04:00
Charlie Marsh
ea6185e082
Merge markers when applying constraints (#4648)
## Summary

When a constraint is applied to a requirement with a marker, the marker
needs to be propagated to the constraint.

If both the constraint and the requirement have a marker, they need to
be merged together (via `and`).

Closes https://github.com/astral-sh/uv/issues/4575.
2024-06-29 16:51:04 +00:00
Charlie Marsh
0bb99952f6
Sync all packages in a virtual workspace (#4636)
## Summary

This PR dodges some of the bigger issues raised by
https://github.com/astral-sh/uv/pull/4554 and
https://github.com/astral-sh/uv/pull/4555 by _not_ changing any of the
bigger semantics around syncing and instead merely changing virtual
workspace roots to sync all packages in the workspace (rather than
erroring due to being unable to find a project).

Closes #4541.
2024-06-29 12:43:59 -04:00
Zanie Blue
af9c2e60aa
Ignore py not found errors during interpreter discovery (#4620)
Closes https://github.com/astral-sh/uv/issues/4522
2024-06-28 23:39:26 -05:00
Zanie Blue
3a627f3799
Track tool entry points in receipts (#4634)
We need this to power uninstallations! 

The latter two commits were reviewed in:

- #4637 
- #4638 

Note this is a breaking change for existing tool installations, but it's
in preview and very new. In the future, we'll need a clear upgrade path
for tool receipt changes.
2024-06-28 22:45:40 -05:00
Chan Kang
72438ef5bb
Use asterisk for dependency cycles in uv pip tree (#4626)
## Summary

Use an asterisk to indicate dependency cycles, along with de-duplicated packages.

Purely an aesthetic change.
2024-06-28 22:35:37 +00:00
Zanie Blue
a444e59668
Add uv tool list (#4630)
What it says on the tin.

We skip tools with malformed receipts now and warn instead of failing
all tool operations.
2024-06-28 22:00:18 +00:00
Charlie Marsh
164160da34
Avoid infinite loop for cyclic installs (#4633)
## Summary

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

## Test Plan

Run `uv sync` with:

```toml
[project]
name = "foo"
version = "0.1.0"
requires-python = ">=3.9"
dependencies = ["poetry"]
```
2024-06-28 20:15:28 +00:00
Andrew Gallant
22ce8fdf4b uv-resolver: add some tests for other source types
This adds some coverage for source types that aren't used as much in
other tests. For example, a direct URL source with a sub-directory.
2024-06-28 12:02:33 -07:00
Andrew Gallant
870660d8bd uv/tests: update snapshots 2024-06-28 12:02:33 -07:00
Andrew Gallant
47ea5effc7 uv-resolver: make source structured via an inline table 2024-06-28 12:02:33 -07:00
Andrew Gallant
cbc83ecd8f uv-resolver: add DistributionId::to_toml
This centralizes writing out the DistributionId as TOML. This is again
just a refactor. No behavioral changes were made. In a subsequent
commit, we will tweak how `source` is written.
2024-06-28 12:02:33 -07:00
Andrew Gallant
fcbc65c956 uv-resolver: add Distribution::to_toml
This splits out the TOML serialization logic for Distribution to its own
method. This is just moving code. No changes have been made.
2024-06-28 12:02:33 -07:00
Zanie Blue
f15cd5c11d
Rename tool_run to run_tool for consistency (#4628) 2024-06-28 12:10:55 -05:00
konsti
796171e1e6
Normalize fork markers (#4623)
Looks much better than #4618:

```
DEBUG Pre-fork split universal took 0.644s
DEBUG Split python_version >= '3.12' and platform_machine == 'aarch64' and platform_system == 'Darwin' and platform_system == 'Linux' took 0.659s
DEBUG Split python_version == '3.9' and platform_machine == 'arm64' and platform_system == 'Darwin' took 0.291s
```
2024-06-28 17:55:48 +02:00
Zanie Blue
3a62ba3809
Improve toolchain and environment missing error messages (#4596)
The journey here can be seen in:

- #4587 
- #4589 
- #4594 

I collapsed all the commits here because only the last one in the stack
got us to a "correct" error message.

There are a few architectural changes:

- We have a dedicated `MissingEnvironment` and `EnvironmentNotFound`
type for `PythonEnvironment::find` allowing different error messages
when searching for environments
- `ToolchainNotFound` becomes a struct with the `ToolchainRequest` which
greatly simplifies missing toolchain error formatting
- `ToolchainNotFound` tracks the `EnvironmentPreference` so it can
accurately report the locations checked

The messages look like this now, instead of the bland (and often
incorrect): "No Python interpreter found in system toolchains".

```
❯ cargo run -q -- pip sync requirements.txt
error: No virtual environment found
❯ UV_TEST_PYTHON_PATH="" cargo run -q -- pip sync requirements.txt --system
error: No system environment found
❯ UV_TEST_PYTHON_PATH="" cargo run -q -- pip sync requirements.txt --python 3.12
error: No virtual environment found for Python 3.12
❯ UV_TEST_PYTHON_PATH="" cargo run -q -- pip sync requirements.txt --python 3.12 --system
error: No system environment found for Python 3.12
❯ UV_TEST_PYTHON_PATH="" cargo run -q -- toolchain find 3.12 --preview
error: No toolchain found for Python 3.12 in system path
❯ UV_TEST_PYTHON_PATH="" cargo run -q -- pip compile requirements.in
error: No toolchain found in virtual environments or system path
```

I'd like to follow this with hints, suggesting creating an environment
or using system in some cases.
2024-06-28 15:16:59 +00:00
konsti
e79fa774b8
Split out SolveState::add_unavailable_version (#4619)
Reduces the size of the overly complex `solve_tracked` a little. No
functional changes.
2024-06-28 14:47:54 +00:00
konsti
2b63dfd717
Log fork timings (#4618)
This includes a functional change, we now skip the forked state pop/push
if we didn't fork.

From transformers:

```
DEBUG Pre-fork split universal took 0.036s
DEBUG Split python_version >= '3.10' and python_version >= '3.10' and platform_system == 'Darwin' and python_version >= '3.11' and python_version >= '3.12' and python_version >= '3.6' and platform_system == 'Linux' and platform_machine == 'aarch64' took 0.048s
DEBUG Split python_version <= '3.9' and platform_system == 'Darwin' and platform_machine == 'arm64' and python_version >= '3.7' and python_version >= '3.8' and python_version >= '3.9' took 0.038s
```

The messages could use simplification from
https://github.com/astral-sh/uv/issues/4536

We can consider nested spans in the future but this works nicely for
now.
2024-06-28 14:45:30 +00:00
Zanie Blue
363f3f7862
Replace all uses of fs_err::tokio::rename with uv_fs::rename_with_retry (#4606)
Same as #4605 but includes persistence of extracted archives and
toolchain downloads.
2024-06-28 14:33:23 +00:00
Zanie Blue
f3c7de3c7d
Retry on spurious failures when caching built wheels (#4605)
https://github.com/astral-sh/uv/pull/2419 appears to have only applied
this retry to wheels that were already downloaded (though I would have
to look more carefully to be certain). In
https://github.com/astral-sh/uv/issues/1491, we've gotten continued
reports of spurious failures on Windows and tracing reveals that we are
not applying our retry logic during the rename. I believe we're in this
code path — switching to our backoff retry should resolve the failures.
2024-06-28 09:23:09 -05:00
Charlie Marsh
14564f97c2
Add some rustdoc to pip tree (#4615) 2024-06-28 13:39:40 +00:00
Chan Kang
b3b4b47394
fix the incorrect handling of markers in pip tree (#4611)
## Summary
resolves https://github.com/astral-sh/uv/issues/4609

previously, the implementation of `required_with_no_extra` was
incorrect, particularly when there are packages that do not require any
extras but have other types of markers.

## Test Plan
the existing tests also did cover this (my bad... missed it) but added a
smaller test since this bug would've been more obvious with this new
test.
2024-06-28 09:28:39 -04:00
Ibraheem Ahmed
bbd59ff455
Allow uv add to specify optional dependency groups (#4607)
## Summary

Implements `uv add --optional <group>`, which adds a dependency to
`project.optional-dependency.<group>`.

Resolves https://github.com/astral-sh/uv/issues/4585.
2024-06-28 01:24:21 +00:00
Charlie Marsh
9b38450998
Handle cycles when propagating markers (#4595)
## Summary

It turns out that `Topo` only works on graphs without cycles. If a graph
has a cycle, it seems to bail early. So we were losing markers for trees
that contain cycles (like Poetry, which depends on
`poetry-plugin-export`, which depends on Poetry).

Now, we remove cycles beforehand and re-add those edges afterwards.

It's a bit hard for me to reason about the implications of this. The way
that marker propagation works is that we do visit the nodes in-order and
propagate the markers from any incoming to any outgoing edges. We only
do this at a single depth (rather than recursively) because we visit the
nodes in-order anyway. But if you have a cycle... then in theory you
might need to propagate the markers recursively? Or maybe not?

As an example:

`A -> B -> C -> D -> B`

If `A -> B` has `sys_platform == 'darwin'`, and then `D -> B` has
`python_version >= '3.7`... then we don't need to propagate
`python_version >= '3.7'` back to `B` or any of its dependencies,
because the condition would be `(sys_platform == 'darwin' or
python_version >= '3.7) or sys_platform == 'darwin'`, which is
equivalent to `sys_platform == 'darwin'`.

Closes #4584.
2024-06-27 17:30:09 -04:00
konsti
80e45d3174
Indent wheels like dependencies in the lockfile (#4582)
This PR contains two style changes to the lockfile:
* Always indent lists of objects, even with they are only a single
element.
* Use 4 spaces instead of tabs for indenting, to mirror what we do in
the ruff formatter.
2024-06-27 22:26:47 +02:00
Charlie Marsh
4c1181b9e1
Make --universal and --python-platform mutually exclusive (#4598)
## Summary

Open to just making this a warning but no strong opinion.

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

## Test Plan

Failure:

```
❯ echo "pandas==2.2.2" | cargo run pip compile --universal -p 3.11 --no-header - --python-platform linux
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.15s
     Running `target/debug/uv pip compile --universal -p 3.11 --no-header - --python-platform linux`
error: the argument '--universal' cannot be used with '--python-platform <PYTHON_PLATFORM>'

Usage: uv pip compile --universal --python-version <PYTHON_VERSION> --no-header <SRC_FILE>...

For more information, try '--help'.
```
2024-06-27 18:51:44 +00:00
Charlie Marsh
9ac1a29c7a
Treat Python version as a lower bound in --universal (#4597)
## Summary

Closes https://github.com/astral-sh/uv/issues/4591.
2024-06-27 14:41:45 -04:00
konsti
86e6f76836
Use inline table for dependencies in lockfile (#4581)
Use indented inline tables for `distribution.dependencies`,
`distribution.optional-dependencies` and
`distribution.dev-dependencies`.

The new style is more concise (see examples below) and it makes the
association between a distribution and its dependencies clearer
(previously, they were both individual `[[...]]` blocks separated by
newlines). The style is optimized for small, meaningful diffs by placing
each dependency on a single line with a final trailing comma. Whenever a
dependency is added, removed or changed, there should be a one line diff
in `distribution.dependencies`. The final trailing comma ensures that
adding a dependency doesn't change the line ahead.

Part of #3611

## Examples

### Simple workspace package

Before:
```toml
[[distribution]]
name = "bird-feeder"
version = "1.0.0"
source = "editable+packages/bird-feeder"

[[distribution.dependencies]]
name = "anyio"

[[distribution.dependencies]]
name = "seeds"
```

After:
```toml
[[distribution]]
name = "bird-feeder"
version = "1.0.0"
source = "editable+packages/bird-feeder"
dependencies = [
    { name = "anyio" },
    { name = "seeds" },
]
```

### Flask

Before:
```toml
[[distribution]]
name = "flask"
version = "3.0.2"
source = "registry+https://pypi.org/simple"
sdist = { url = "a89e8120fa/flask-3.0.2.tar.gz", hash = "sha256:822c03f4b799204250a7ee84b1eddc40665395333973dfb9deebfe425fefcb7d", size = 675248 }
wheels = [{ url = "aa98bfe0eb/flask-3.0.2-py3-none-any.whl", hash = "sha256:3232e0e9c850d781933cf0207523d1ece087eb8d87b23777ae38456e2fbe7c6e", size = 101300 }]

[[distribution.dependencies]]
name = "blinker"

[[distribution.dependencies]]
name = "click"

[[distribution.dependencies]]
name = "itsdangerous"

[[distribution.dependencies]]
name = "jinja2"

[[distribution.dependencies]]
name = "werkzeug"

[distribution.optional-dependencies]

[[distribution.optional-dependencies.dotenv]]
name = "python-dotenv"
```

After:
```toml
[[distribution]]
name = "flask"
version = "3.0.2"
source = "registry+https://pypi.org/simple"
sdist = { url = "a89e8120fa/flask-3.0.2.tar.gz", hash = "sha256:822c03f4b799204250a7ee84b1eddc40665395333973dfb9deebfe425fefcb7d", size = 675248 }
dependencies = [
    { name = "blinker" },
    { name = "click" },
    { name = "itsdangerous" },
    { name = "jinja2" },
    { name = "werkzeug" },
]
wheels = [{ url = "aa98bfe0eb/flask-3.0.2-py3-none-any.whl", hash = "sha256:3232e0e9c850d781933cf0207523d1ece087eb8d87b23777ae38456e2fbe7c6e", size = 101300 }]

[distribution.optional-dependencies]
dotenv = [
    { name = "python-dotenv" },
]
```

### Forking

Before:
```toml
[[distribution]]
name = "project"
version = "0.1.0"
source = "editable+."

[[distribution.dependencies]]
name = "package-a"
version = "4.3.0"
source = "registry+https://astral-sh.github.io/packse/0.3.29/simple-html/"
marker = "sys_platform == 'darwin'"

[[distribution.dependencies]]
name = "package-a"
version = "4.4.0"
source = "registry+https://astral-sh.github.io/packse/0.3.29/simple-html/"
marker = "sys_platform == 'linux'"

[[distribution.dependencies]]
name = "package-b"
marker = "sys_platform == 'linux'"

[[distribution.dependencies]]
name = "package-c"
marker = "sys_platform == 'darwin'"
```

After:
```toml
[[distribution]]
name = "project"
version = "0.1.0"
source = "editable+."
dependencies = [
    { name = "package-a", version = "4.3.0", source = "registry+https://astral-sh.github.io/packse/0.3.29/simple-html/", marker = "sys_platform == 'darwin'" },
    { name = "package-a", version = "4.4.0", source = "registry+https://astral-sh.github.io/packse/0.3.29/simple-html/", marker = "sys_platform == 'linux'" },
    { name = "package-b", marker = "sys_platform == 'linux'" },
    { name = "package-c", marker = "sys_platform == 'darwin'" },
]
```
2024-06-27 20:06:45 +02:00
Gilles Peiffer
bf46792839
Explicitly mention use of seed packages during uv venv --seed (#4588)
<!--
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?
-->

Closes #1329.

## Summary

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

Mentions use of seed packages during `uv venv --seed`, and clarifies the
divergence in behavior when using Python 3.12+.

## Test Plan

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

`cargo nextest run --test venv`

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2024-06-27 14:36:15 +00:00