Commit Graph

2532 Commits

Author SHA1 Message Date
Charlie Marsh 4f340580c7
Show user-facing warning when falling back to copy installs (#4880)
## Summary

This has come up a few times including in a recent email to me.
2024-07-08 13:35:58 +00:00
Charlie Marsh 947cfa13a8
Add some decoration to tool CLI (#4865)
Mostly small things. I added entrypoint counts and bolded the executable
names.

Closes https://github.com/astral-sh/uv/issues/4815.
2024-07-08 09:21:05 -04:00
Andrew Gallant fb19372a00 uv/tests: fix tool_install_home test
This test was, I believe, relying on the XDG_DATA_HOME environment
variable not being set. When it is set, as is the case in my
environment, `uv tool run` will respect it and install `black` for this
particular test into my actual XDG_DATA_HOME directory. We fix this by
setting `XDG_DATA_HOME` explicitly.
2024-07-08 06:12:53 -07:00
Charlie Marsh ffcc05240e
Add user-facing output to indicate PEP 723 script (#4881) 2024-07-08 02:05:13 +00:00
Charlie Marsh ae242c3b8f
Ensure Pythons are aligned in `uv python list` (#4884)
## Summary

The existing tab input sometimes leads to misalignment on my machine, I
think it has to do with breakpoints?

![Screenshot 2024-07-07 at 9 22
43 PM](https://github.com/astral-sh/uv/assets/1309177/c95c5d26-3acb-48a6-8cce-d76f219f5afe)

This PR computes the width explicitly, and then pads each line. I also
added some colors to the RHS. I think it makes it easier to scan, but
don't feel strongly.

![Screenshot 2024-07-07 at 9 36
56 PM](https://github.com/astral-sh/uv/assets/1309177/1c89c83b-9562-4597-a892-021573c48f8d)
2024-07-07 21:52:30 -04:00
Charlie Marsh 98a720ec08
Skip installing `--with` requirements if present in base environment (#4879)
## Summary

Closes #4547.
2024-07-08 01:23:59 +00:00
konsti a76d04b159
`Box::pin(run())` and 2MB test stack (#4851)
By using `Box::pin(run())` we can reduce the artificial stack size for
running tests on windows in debug mode from 8MB to 2MB. I've checked and
1MB/no custom stack size still fail tests, e.g.
`add_workspace_editable`.
2024-07-07 20:50:36 -04:00
konsti 1a31938626
Update windows binaries, again (#4864)
https://github.com/astral-sh/uv/pull/4850#issuecomment-2212557050
2024-07-07 18:58:22 -04:00
Charlie Marsh 389582a37e
Avoid creating cache directories in tool directory (#4868)
Closes https://github.com/astral-sh/uv/issues/4867.
2024-07-07 21:19:07 +00:00
Charlie Marsh a302d704c5
Fix always-plural message in uv python install (#4866) 2024-07-07 20:29:19 +00:00
Jo f4c4b69cc7
Add progress bar when downloading python (#4840)
## Summary

Resolves #4825 

## Test Plan

```sh
$ cargo run -- python install --force --preview
$ cargo run -- venv -p 3.12 --python-preference only-managed
$ cargo run -- tool install --preview -p 3.12 --python-preference only-managed --force black
````

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2024-07-07 20:01:35 +00:00
konsti 9e50864508
Ignore `compile_invalid_pyc_invalidation_mode` on all platforms (#4863)
This test is failing most times for me when running nextest locally,
failing the overall test run, so i'm deactivating it for now. I'm still
not sure what the root cause here is. It seems to have something to do
with python stdin not being ready immediately after we spawn the process
and us being too fast.
2024-07-07 19:46:41 +00:00
Charlie Marsh f5e84bbbab
Bump version to v0.2.22 (#4862) 2024-07-07 19:23:38 +00:00
konsti d787e69f7c
Rename `Workspace.root` to `Workspace.install_path` (#4859)
Renaming in preparation of #4833, which adds a `Workspace.lock_path`. No
functional changes.
2024-07-07 18:35:41 +00:00
konsti 91e4d880a9
Remove dead code from tests (#4856)
Looks like an oversight
2024-07-07 11:48:34 -05:00
Jo 2c214e7585
Use `install_only` python archive (#4843)
## Summary

Resolves #4834

## Test Plan

```sh
# 3.12.3 is a `install_only` archive
$ cargo run -- python install --preview --force 3.12.3

# 3.9.4 has only `full` archive
$ cargo run -- python install --preview --force 3.9.4
```
2024-07-06 21:43:55 -05:00
konsti 7117359ca9
Update trampolines (#4850)
Follow-up to https://github.com/astral-sh/uv/pull/4722
2024-07-06 21:06:48 +00:00
samypr100 eee90a340c
feat: re-enable std in uv-trampoline (#4722)
## Summary

Partially closes #1917

This PR picks up on some of the great work from #1864 and opted to keep
`panic_immediate_abort` (for size reasons). I split the PR in different
isolated commits in case we want to separate/cherry-pick them out.

1. The first commit ports mostly all std changes from that PR into this
PR. Binary sizes stayed the same ~16kb.
2. The second commit migrates our existing usage of windows-sys to
windows for a safer ffi calls with Results!. It also changes all large
unsafe blocks to be isolated to the actual unsafe calls, and switches
some areas to use std such as getenv port ( which seemed buggy! ) from
launcher.c. In addition, this also adds more error checking in order to
match some missing assertions from distlib's launcher.c. Note, due to
the additional .text data, the binary sizes increased to ~20.5kb, but we
can cut back on some of the added error msgs as needed.
3. The third commit switches to using xwin for building on all 3
supported trampoline targets for sanity, and adds a CI bloat check for
core::fmt and panic as a precaution. Sadly, this will invalidate the
xwin cache on the first run.

## Test Plan

Most changes were tested on a couple of local GUI apps and console apps,
also tested some of the error states manually by using SetLastError at
different points in the code and/or passing in invalid handles.

I'm not sure how far we can get with migrating some of the other calls
without increasing binary size substantially. An initial attempt at
using std::path didn't seem so bad size wise when I tried it (~1k). On
other cases, such as std::process::exit added ~10k to the total binary
size.

---------

Co-authored-by: konstin <konstin@mailbox.org>
2024-07-06 20:38:45 +00:00
Ahmed Ilyas 6c8ce1d013
`uv cache prune` removes all cached environments (#4845)
## Summary

Resolves #4802

## Test Plan
- `cargo test`
```sh
❯ cargo run -- cache prune -v
Pruning cache at: /Users/ahmedilyas/Library/Caches/uv
No unused entries found
❯ cargo run -- tool run cowsay
warning: `uv tool run` is experimental and may change without warning.
Resolved 1 package in 182ms
Installed 1 package in 20ms
 + cowsay==6.1
usage: Cowsay [-h] [-c CHARACTER] -t TEXT [-v]
Cowsay: error: the following arguments are required: -t/--text
❯ cargo run -- cache prune -v
Pruning cache at: /Users/ahmedilyas/Library/Caches/uv
    0.793440s DEBUG uv_cache Removing dangling cache entry: /Users/ahmedilyas/Library/Caches/uv/environments-v1/095cd7c4c298a0d8
Removed 41 files (143.5KiB)
```
2024-07-06 19:37:15 +00:00
Charlie Marsh 798ec373c0
Create empty environment for `uv run --isolated` (#4849)
## Summary

If you pass `--isolated` but no `--with`, at present, we don't create
any environment (so `--python` isn't respected and `python` will fail
entirely if it wasn't already in your path). Now, we create a base
environment in `--isolated` even if `with` wasn't provided.

Closes https://github.com/astral-sh/uv/issues/4846.
Closes https://github.com/astral-sh/uv/issues/4776.
2024-07-06 19:22:19 +00:00
Jo 1f454f3a67
Revert `uninstall` deduplication changes from #4841 (#4842)
`matching_installations` is BTreeSet already, no need to deduplicate it.

https://github.com/astral-sh/uv/pull/4841#discussion_r1667241722
2024-07-06 14:16:52 -05:00
Jo bcb2568f47
Deduplicate when install or uninstall python (#4841)
When specifying the same argument multiple times, the same version will
be downloaded multiple times:

```sh

$ cargo run -- python install --preview --force 3.12.3 cpython-3.12 3.12.3 3.12
Looking for installation Python 3.12.3 (any-3.12.3-any-any-any)
Looking for installation cpython-3.12-any-any-any (cpython-3.12-any-any-any)
Looking for installation Python 3.12.3 (any-3.12.3-any-any-any)
Looking for installation Python 3.12 (any-3.12-any-any-any)
Found 4/4 versions requiring installation
Downloading cpython-3.12.3-windows-x86_64-none
Downloading cpython-3.12.3-windows-x86_64-none
Downloading cpython-3.12.3-windows-x86_64-none
Downloading cpython-3.12.3-windows-x86_64-none
```

This PR deduplicates the `ManagedPythonDownload` before `install` or
`uninstall`:

```sh
$ cargo run -q -- python install --preview --force 3.12.3 cpython-3.12 3.12.3 3.12
Looking for installation Python 3.12 (any-3.12-any-any-any)
Looking for installation Python 3.12.3 (any-3.12.3-any-any-any)
Looking for installation cpython-3.12-any-any-any (cpython-3.12-any-any-any)
Downloading cpython-3.12.3-windows-x86_64-none
Installed Python 3.12.3 to C:\Users\nigel\AppData\Roaming\uv\data\python\cpython-3.12.3-windows-x86_64-none
Installed 1 version in 6s

$ cargo run -q -- python uninstall --preview  3.12.3 cpython-3.12 3.12.3 3.12
Looking for Python installations matching Python 3.12 (any-3.12-any-any-any)
Found installation `cpython-3.12.3-windows-x86_64-none` that matches Python 3.12
Looking for Python installations matching Python 3.12.3 (any-3.12.3-any-any-any)
Looking for Python installations matching cpython-3.12-any-any-any (cpython-3.12-any-any-any)
Uninstalled `cpython-3.12.3-windows-x86_64-none`
Removed 1 Python installation
```
2024-07-05 22:05:17 -05:00
Charlie Marsh 1bd73a7346
Bold durations in CLI messages (#4818)
I guess the `.bold()` on the preceding text causes the `.dimmed()` to...
stop?

But you can compare before and after:

![Screenshot 2024-07-04 at 2 06
41 PM](https://github.com/astral-sh/uv/assets/1309177/b8298cce-5c7f-4a65-8279-93f1c777344c)

Closes #4817.
2024-07-05 16:58:33 -05:00
Charlie Marsh 32ea636585
Preserve verbatim URLs for `--find-links` (#4838)
Also gets rid of a lot of duplicated logic for `--find-links`.

Closes https://github.com/astral-sh/uv/issues/4797
2024-07-05 16:57:40 -05:00
Zanie Blue c0ca0b02b8
Fill Python requests with platform information during automatic fetches (#4810)
Closes https://github.com/astral-sh/uv/issues/4800

We do this during `install` — it's an important step to ensure the
request has the platform information in it.
2024-07-05 21:13:57 +00:00
Charlie Marsh 77b1bb77b5
Fix some ephemeral-to-cached comments (#4837) 2024-07-05 21:11:19 +00:00
Charlie Marsh f450b45780
Add `UV_OVERRIDE` environment variable for `--override` (#4836)
Closes https://github.com/astral-sh/uv/issues/4827
2024-07-05 16:03:17 -05:00
Charlie Marsh 3fa09a3972
Require at least one target for toolchain uninstalls (#4820)
Closes https://github.com/astral-sh/uv/issues/4816.
2024-07-04 18:31:40 -04:00
Charlie Marsh a13ab43a0d
Tweak installation language in toolchain install (#4811)
## Summary

Like https://github.com/astral-sh/uv/pull/4808 but with a few more
changes. I suspect this will require some bikeshedding but I find the
use of "installation" and "installed" in the same sentence to be kind of
a lot.
2024-07-04 17:05:31 -04:00
Charlie Marsh b588054dfb
Always use release-only comparisons for `requires-python` (#4794)
## Summary

There are a few ideas at play here:

1. pip always strips versions to the release when evaluating against a
`Requires-Python`, so we now do the same. That means, e.g., using
`3.13.0b0` will be accepted by a project with `Requires-Python: >=
3.13`, which does _not_ adhere to PEP 440 semantics but is somewhat
intuitive.
2. Because we know we'll only be evaluating against release-only
versions, we can use different semantics in PubGrub that let us collapse
ranges. For example, `python_version >= '3.10' or python_version <
'3.10'` can be collapsed to the truthy marker.

Closes https://github.com/astral-sh/uv/issues/4714.
Closes https://github.com/astral-sh/uv/issues/4272.
Closes https://github.com/astral-sh/uv/issues/4719.
2024-07-04 20:06:52 +00:00
konsti 11cb0059c1
Remove incompatible wheels from `uv.lock` (#4799)
Remove wheels from the lockfile that don't match the required python
version. For example, we remove
`charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl` when we have
`requires-python = ">=3.12"`.

Our snapshots barely show changes since we avoid the large binaries for
which matters. Here are 3 real world `uv.lock` before/after comparisons
to show the large difference:
*
[warehouse](https://gist.github.com/konstin/9a1ed6a32b410e250fcf4c6ea8c536a5)
(5677 -> 4214)
*
[transformers](https://gist.github.com/konstin/5636281b5226f64aa44ce3244d5230cd)
(6484 -> 5816)
*
[github-wikidata-bot](https://gist.github.com/konstin/ebbd7b9474523aaa61d9a8945bc02071)
(793 -> 454)

We only remove wheels we are certain don't match the python version and
still keep those with unknown tags. We could remove even more wheels by
also considering other markers, e.g. removing linux wheels for a
windows-only dep, but we would trade complex, easy-to-get-wrong logic
for diminishing returns.
2024-07-04 14:03:54 -04:00
Jo dac3161f90
Check hash of downloaded python toolchain (#4806)
## Summary

Check the sha256 checksum when downloading a managed python toolchain.

## Test Plan

```sh
$ cargo run -- python install 3.12

warning: `uv python install` is experimental and may change without warning.
Looking for installation Python 3.12.3 (any-3.12.3-any-any-any)
Downloading cpython-3.12.3-windows-x86_64-none
Installed Python 3.12.3 to C:\Users\jo\AppData\Roaming\uv\data\python\cpython-3.12.3-windows-x86_64-none
Installed 1 installation in 6s

$ cargo run -- python uninstall 3.12

$ # manually change the hash in `crates/uv-python/src/downloads.inc`

$ cargo run -- python install 3.12

warning: `uv python install` is experimental and may change without warning.
Looking for installation Python 3.12 (any-3.12-any-any-any)
Downloading cpython-3.12.3-windows-x86_64-none
error: Hash mismatch for `cpython-3.12.3-windows-x86_64-none`

Expected:
xx

Computed:
776568c92c5f3b47dbf5f17c1c58578f70d75a32654419a158aa8bdc6f95b09a
```
2024-07-04 17:49:12 +00:00
Charlie Marsh 445d45b82c
Always use base interpreter for cached environments (#4805)
Closes #4801.
2024-07-04 17:38:53 +00:00
Charlie Marsh 6a27135a65
Use cached environments in PEP 723 execution (#4789)
## Summary

This seems like another good candidate for environment caching. If you
run a script repeatedly, we can just use the existing cached
environment.
2024-07-04 17:23:13 +00:00
konsti 892106fef0
Box clap args some more for `uv init` (#4796)
Fixes stack overflows in tests for
https://github.com/astral-sh/uv/pull/4791
2024-07-04 13:22:24 -04:00
Danny 35afcfd053
Enable Registry Client Builder to be created from Base Client Builder (#4729)
<!--
Thank you for contributing to uv! To help us out with reviewing, please
consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->

## Summary

<!-- What's the purpose of the change? What does it do, and why? -->
Addresses https://github.com/astral-sh/uv/issues/4330, to reduce
duplication in the client creation logic.
## Test Plan

<!-- How was it tested? -->
https://github.com/astral-sh/uv/pull/4729#issuecomment-2204681655
2024-07-04 15:53:05 +00:00
Jo 0a336dacab
Remove installed python for force installation (#4807)
## Summary

Currently `uv python install` does not respect `--force` reinstallation,
the downloading process is just skipped if the installation existed.

```
$ uv python install 3.12

Looking for installation Python 3.12 (any-3.12-any-any-any)
Downloading cpython-3.12.3-windows-x86_64-none
Installed Python 3.12.3 to C:\Users\jo\AppData\Roaming\uv\data\python\cpython-3.12.3-windows-x86_64-none
Installed 1 installation in 6s

$ uv python install --force 3.12

Looking for installation Python 3.12 (any-3.12-any-any-any)
Found installed installation `cpython-3.12.3-windows-x86_64-none` that satisfies Python 3.12
Downloading cpython-3.12.3-windows-x86_64-none
Installed 1 installation in 0s
```

## Test Plan


```
$ uv python install 3.12

Looking for installation Python 3.12 (any-3.12-any-any-any)
Downloading cpython-3.12.3-windows-x86_64-none
Installed Python 3.12.3 to C:\Users\jo\AppData\Roaming\uv\data\python\cpython-3.12.3-windows-x86_64-none
Installed 1 installation in 6s

$ uv python install --force 3.12

Looking for installation Python 3.12 (any-3.12-any-any-any)
Found installed installation `cpython-3.12.3-windows-x86_64-none` that satisfies Python 3.12
Removing installed installation `cpython-3.12.3-windows-x86_64-none`
Downloading cpython-3.12.3-windows-x86_64-none
Installed Python 3.12.3 to C:\Users\jo\AppData\Roaming\uv\data\python\cpython-3.12.3-windows-x86_64-none
Installed 1 installation in 7s
```
2024-07-04 11:13:14 -04:00
Charlie Marsh cf004fd644
Rename `EphemeralEnvironment` to `CachedEnvironment` (#4804) 2024-07-04 13:57:12 +00:00
Charlie Marsh c6f72d333a
Resolve requirements prior to nuking tool environments (#4788)
## Summary

Closes #4747.
2024-07-04 09:45:26 -04:00
konsti d178d97a40
Document the `RequiresPython` fields (#4798) 2024-07-04 08:27:02 -04:00
Ibraheem Ahmed 576ba9c522
Avoid hangs before exiting CLI (#4793)
## Summary

The resolver sometimes starts HTTP requests that end up not being
necessary. When dropping the Tokio runtime before exiting we currently
wait for those to complete. This can cause noticeable hangs in the CLI,
particularly when the runtime is blocked on slow DNS resolution.

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

## Test Plan

This change resolves any reproducible hangs for me locally.
2024-07-03 20:05:44 -04:00
Charlie Marsh de40f798b9
Cache tool environments in `uv tool run` (#4784)
## Summary

The basic strategy:

- When the user does `uv tool run`, we resolve the `from` and `with`
requirements (always).
- After resolving, we generate a hash of the requirements. For now, I'm
just converting to a lockfile and hashing _that_, but that's an
implementation detail.
- Once we have a hash, we _also_ hash the interpreter.
- We then store environments in
`${CACHE_DIR}/${INTERPRETER_HASH}/${RESOLUTION_HASH}`.

Some consequences:

- We cache based on the interpreter, so if you request a different
Python, we'll create a new environment (even if they're compatible).
This has the nice side-effect of ensuring that we don't use environments
for interpreters that were later deleted.
- We cache the `from` and `with` together. In practice, we may want to
cache them separately, then layer them? But this is also an
implementation detail that we could change later.
- Because we use the lockfile as the cache key, we will invalidate the
cache when the format changes. That seems ok, but we could improve it in
the future by generating a stable hash from a lockfile that's
independent of the schema.

Closes https://github.com/astral-sh/uv/issues/4752.
2024-07-03 19:25:39 -04:00
Charlie Marsh 6a4c4ace2b
Always use exact semantics in `update_environment` (#4790)
## Summary

We don't need to expose this -- these are always environments that we
want to be perfectly synced.
2024-07-03 21:23:21 +00:00
Charlie Marsh 814b3c45bc
Fix misleading description contains docstring (#4783)
## Summary

This doesn't include pre-releases by default. Maybe it did at one point!
2024-07-03 14:28:40 -04:00
Caíque Porfirio c17761904e
feat: add tool version to list command (#4674)
<!--
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 #4653

## Summary
Adds the tool version to the list command right beside the tool name

```
$ uv tool list
black v24.2.0
```

Following the proposed format discussed in #4653


## Test Plan
`cargo test tool_list`

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

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2024-07-03 18:24:37 +00:00
Charlie Marsh d24b075b2d
Add `--exclude-newer` to installer arguments (#4785)
## Summary

We already support this in `pip sync` and have it stubbed to `None` in
`sync.
2024-07-03 18:05:05 +00:00
konsti 37f15367bb
Box clap commands to avoid windows debug clap stack overflow (#4768)
The changes in https://github.com/astral-sh/uv/pull/4708 caused an
overflow in debug mode only of the 1MB default stack size in windows
during clap. This means that even trivial wrong argument tests would
fail without increasing the stack size. As remedy, we box the clap
types.
2024-07-03 19:06:15 +02:00
Zanie Blue 1c6c8db1a2
Add dedicated help menu for `uvx` (#4770)
Closes #4749
2024-07-03 16:38:54 +00:00
Zanie Blue c0875fd8fe
Improvements to the Python metadata fetch script (#4780)
This fell out of my investigation of
https://github.com/astral-sh/uv/issues/4774 but the bug was fixed by the
reporter in #4775

- Adds support for `GH_TOKEN` authentication again — basically needed to
avoid rate limits when hacking on this.
- Clarifies some handling and logging of flavors
2024-07-03 11:36:59 -05:00
Zanie Blue 81442f0b4c
Update "about" in help menu (#4782)
Following #4773 

```
❯ cargo run -q -- -h
An extremely fast Python package manager.

Usage: uv [OPTIONS] <COMMAND>
```
2024-07-03 11:36:38 -05:00
Charlie Marsh f980e3f4fc
Use already-installed tools in `uv tool run` (#4750)
## Summary

This doesn't cache the tool environment; rather, it just uses the `tool
install` environment if it satisfies the request.

Closes https://github.com/astral-sh/uv/issues/4742.
2024-07-03 16:35:11 +00:00
Zanie Blue a604f15028
Drop the crate description from the `uv` help menu (#4773)
Previously this displayed:

```
❯ cargo run -q -- --help
The command line interface for the uv binary.

Usage: uv [OPTIONS] <COMMAND>
```

This is.. weird. Here I remove it entirely. I could see adding
`about_long` text being helpful in the future.
2024-07-03 11:11:36 -05:00
Di-Is dc4ff84443
Use optimized versions of managed Python on Linux (#4775)
Fix #4774.

## Summary

Change the python interpreter for linux installed with `uv python` to an
optimized one.

## Test Plan

I ran the following command on Linux (glibc) to confirm that an
optimized (not debug built) Python is installed.

```bash
# install python
uv python install 3.12.3

# check build type
uv run python -c "import sysconfig;print(sysconfig.get_config_var('Py_DEBUG'))"
0
```
2024-07-03 10:58:04 -05:00
Charlie Marsh d858fb8901
Make in-flight part of shared state struct (#4778)
## Summary

Now that we don't need to re-initialize it, this seems simpler.
2024-07-03 15:51:51 +00:00
Charlie Marsh b6575fe487
Avoid resetting dispatch and in-flight state with reinstalls (#4771)
## Summary

This used to be necessary because we purged the cache in the
`InstallPlan` if the user passed `--reinstall`. _However_, we later
changed the cache to be append-only.

## Test Plan

I ran through the test plan in https://github.com/astral-sh/uv/pull/933,
which includes an integration test and running `uv pip install
--reinstall` with:

```text
setuptools
devpi @ e334eb4dc9bb023329e4b610e4515b/devpi-2.2.0.tar.gz
```
2024-07-03 10:31:51 -04:00
konsti dcdf26eead
Make `path_with_trailing_space_gives_proper_error` language independent (#4767)
The test currently fails on windows machines with non-english locale.
2024-07-03 12:46:30 +00:00
Zanie Blue dd7da6af5f
Change "toolchain" to "python" (#4735)
Whew this is a lot.

The user-facing changes are:

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

The internal changes are:

- `uv-toolchain` crate to `uv-python`
- `Toolchain` no longer referenced in type names
- Dropped unused `SystemPython` type (previously replaced)
- Clarified the type names for "managed Python installations"
- (more little things)
2024-07-03 07:44:29 -05:00
pppp56 174414c5da
Add entrypoints to tool list (#4661)
<!--
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 #4654 
## Summary

The purpose of this is to show the entrypoints of each tool when running
`uv tool list` as below:

```
$ uv tool list
black
    black
    blackd

```

I used the proposed formatting as it was written in #4653 by @blueraft.
I had to use spaces instead of tabs in order to make the test
successful. Indeed in the test we are using a raw string and I did not
manage to make the test pass when escaping the tab in the list.rs file
so I used spaces everywhere.

I had a deeper look into #4653 as well but it is more difficult as we
need to get the version of the tool in the Tool object, I will continue
on this next one later.

Please tell me if anything else is needed I tried to follow the
contribution guidelines but I might have forgotten something.
Have a great day!


## Test Plan

`cargo clippy`

then by using the local version of uv as described in the Readme.md. 


```
my-computer :~/mypath/uv$ cargo run -- tool list
   Compiling uv-cli v0.0.1 (/mypath/uv/crates/uv-cli)
   Compiling uv v0.2.18 (/mypath/uv/crates/uv)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 18.69s
     Running `target/debug/uv tool list`
warning: `uv tool list` is experimental and may change without warning.
black
  black
  blackd
isort
  isort
  isort-identify-imports

```

and 

`cargo test tool_list`

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2024-07-02 23:54:19 -05:00
Zanie Blue ebfe6d8fcc
Bump version to 0.2.21 (#4757) 2024-07-03 04:27:00 +00:00
David Poznik 7bb9b96dc3
Differentiate `freeze` and `list` help text (#4751)
`uv pip freeze` and `uv pip list` had identical help text. This PR
differentiates them.
2024-07-02 23:44:57 +00:00
Charlie Marsh 75731452d8
Replace tool environments on updated Python request (#4746)
## Summary

Closes https://github.com/astral-sh/uv/issues/4741.
2024-07-02 23:07:55 +00:00
Zanie Blue e88e1373e6
Bump version to 0.2.20 (#4745) 2024-07-02 22:30:43 +00:00
Zanie Blue c5bf64abeb
Bump version to 0.2.19 (#4738) 2024-07-02 21:15:58 +00:00
Charlie Marsh 676d550410
Remove dangling environments in `tool uninstall` (#4740)
## Summary

It seems useful that `tool uninstall` guarantees the tool is gone (e.g.,
if the receipt and environment get out-of-sync somehow).
2024-07-02 21:03:39 +00:00
Charlie Marsh 32dc9bef59
Respect tool upgrades in `uv tool install` (#4736)
## Summary

For now the semantics are such that if the requested requirements from
the command line don't match the receipt (or if any `--reinstall` or
`--upgrade` is requested), we proceed with an install, passing the
`--reinstall` and `--upgrade` to the underlying Python environment.

This may lead to some unintuitive behaviors, but it's simplest for now.
For example:

- `uv tool install black<24` followed by `uv tool install black
--upgrade` will install the latest version of `black`, removing the
`<24` constraint.
- `uv tool install black --with black-plugin` followed by `uv tool
install black` will remove `black-plugin`.

Closes https://github.com/astral-sh/uv/issues/4659.
2024-07-02 16:46:31 -04:00
Charlie Marsh 21187e1f36
Accept package names in the tool API (#4737)
## Summary

It seems helpful that these _not_ accept arbitrary strings.
2024-07-02 15:30:40 -04:00
Zanie Blue c8987269ff
Lock the toolchains directory during toolchain operations (#4733) 2024-07-02 13:31:30 -05:00
Ibraheem Ahmed a380e8e4df
Add conversion from lockfile `Distribution` to `Metadata` (#4706)
## Summary

Splitting this out from https://github.com/astral-sh/uv/pull/4495
because it's also useful to reuse the `uv pip tree` code for `uv tree`.
2024-07-02 18:03:20 +00:00
konsti 4b19319485
Show when we retried requests (#4725)
In #3514 and #2755, users had intermittent network errors, but it was
not always clear whether we had already retried these requests or not.
Building upon https://github.com/TrueLayer/reqwest-middleware/pull/159,
this PR adds the number of retries to the error message, so we can see
at first glance where we're missing retries and where we might need to
change retry settings.

Example error trace:

```
Could not connect, are you offline?
  Caused by: Request failed after 3 retries
  Caused by: error sending request for url (https://pypi.org/simple/uv/)
  Caused by: client error (Connect)
  Caused by: dns error: failed to lookup address information: Name or service not known
  Caused by: failed to lookup address information: Name or service not known
```

This code is ugly since i'm missing a better pattern for attaching
context to reqwest middleware errors in
https://github.com/TrueLayer/reqwest-middleware/pull/159.
2024-07-02 19:04:11 +02:00
Charlie Marsh d05bb45c74
Omit pythonX.Y segment in stdlib on managed Windows (#4727)
## Summary

Windows omits this segment, IIRC.

Closes https://github.com/astral-sh/uv/issues/4724.
2024-07-02 09:21:15 -04:00
Zanie Blue 2c0cb6e021
Allow `uv pip sync` to clear an environment with opt-in (#4517)
Closes https://github.com/astral-sh/uv/issues/4516

Open to some deliberation about the opt-in strategy here.
2024-07-02 13:14:27 +00:00
Charlie Marsh d9f389a58d
Narrow `requires-python` requirement in resolver forks (#4707)
## Summary

Given:

```text
numpy >=1.26 ; python_version >= '3.9'
numpy <1.26 ; python_version < '3.9'
```

When resolving for Python 3.8, we need to narrow the `requires-python`
requirement in the top branch of the fork, because `numpy >=1.26` all
require Python 3.9 or later -- but we know (in that branch) that we only
need to _solve_ for Python 3.9 or later.

Closes https://github.com/astral-sh/uv/issues/4669.
2024-07-02 12:23:38 +00:00
Charlie Marsh 89b3324ae1
Move `Requires-Python` incompatibilities out of version map (#4705)
## Summary

This is required to solve https://github.com/astral-sh/uv/issues/4669,
because the `Requires-Python` version can now vary across a resolution.
For example, within certain forks, we might have a more narrow range,
which would allow us to use distributions that would not be allowed for
the global resolution.

This should be fine because `requires-python` is part of the package
metadata, so it should be consistent between files within a package
version. As such, there shouldn't be any risk that we incorrectly
prioritize distributions by omitting this information.

(To be more specific, the risk is something like: we prioritize some
wheel over a source distribution within a package-version, so we don't
track the source distribution at all. Then, later, when we choose a
candidate, we see that the wheel doesn't meet the `Requires-Python`
requirement, even though the source distribution _would've_ met it. If
files within a distribution could have varied support, this would be a
real risk.)
2024-07-02 08:15:39 -04:00
Zanie Blue 8dabc29d80
Add `uv toolchain uninstall` (#4646) 2024-07-02 02:37:53 +00:00
Zanie Blue ad5151cda8
Fetch managed toolchains if necessary in `uv tool install` and `uv tool run` (#4717)
Hey we should download toolchains here if we need to, right!?
2024-07-01 21:27:43 -05:00
Zanie Blue c0a06a2c1b
Drop `prefer` prefix from `toolchain-preference` values (#4602)
I think `--toolchain-preference system` is sufficiently clear and
`--toolchain-preference prefer-system` is excessively verbose. This was
discussed in the original pull request at
https://github.com/astral-sh/uv/pull/4424 but because we had a case for
preferring "installed managed" toolchains I was hesitant to change it.
Now that I've dropped that in #4601, I think we can drop the prefix.
2024-07-02 02:07:30 +00:00
Zanie Blue 6799cc883a
Allow configuring the toolchain fetch strategy (#4601)
Adds a `toolchain-fetch` option alongside `toolchain-preference` with
`automatic` (default) and `manual` values allowing automatic toolchain
fetches to be disabled (replaces
https://github.com/astral-sh/uv/pull/4425). When `manual`, toolchains
must be installed with `uv toolchain install`.

Note this was previously implemented with `if-necessary`, `always`,
`never` variants but the interaction between this and
`toolchain-preference` was too confusing. By reducing to a binary
option, things should be clearer. The `if-necessary` behavior moved to
`toolchain-preference=installed`. See
https://github.com/astral-sh/uv/pull/4601#discussion_r1657839633 and
https://github.com/astral-sh/uv/pull/4601#discussion_r1658658755
2024-07-02 01:54:24 +00:00
Zanie Blue ec2723a9f5
Add `uvx` alias for `uv tool run` (#4632)
Closes https://github.com/astral-sh/uv/issues/4476

Originally, this used the changes in #4642 to invoke `main()` from a
`uvx` binary. This had the benefit of `uvx` being entirely standalone at
the cost of doubling our artifact size. We think that's the incorrect
trade-off.

Instead, we assume `uvx` is always next to `uv` and create a tiny binary
(<1MB) that invokes `uv` in a child process. This seems preferable to a
`cargo-dist` alias because we have more control over it. This binary
should "just work" for all of our cargo-dist distributions and
installers, but we'll need to add a new entry point for our PyPI
distribution. I'll probably tackle support there separately?

```
❯ ls -lah target/release/uv target/release/uvx
-rwxr-xr-x  1 zb  staff    31M Jun 28 23:23 target/release/uv
-rwxr-xr-x  1 zb  staff   452K Jun 28 23:22 target/release/uvx
```

This includes some small overhead:

```
❯ hyperfine --shell=none --warmup=100 './target/release/uv tool run --help' './target/release/uvx --help' --min-runs 2000
Benchmark 1: ./target/release/uv tool run --help
  Time (mean ± σ):       2.2 ms ±   0.1 ms    [User: 1.3 ms, System: 0.5 ms]
  Range (min … max):     2.0 ms …   4.0 ms    2000 runs
 
  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.
 
Benchmark 2: ./target/release/uvx --help
  Time (mean ± σ):       2.9 ms ±   0.1 ms    [User: 1.7 ms, System: 0.9 ms]
  Range (min … max):     2.8 ms …   4.2 ms    2000 runs
 
  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs. It might help to use the '--warmup' or '--prepare' options.
 
Summary
  ./target/release/uv tool run --help ran
    1.35 ± 0.09 times faster than ./target/release/uvx --help
```

I presume there may be some other downsides to a child process? The
wrapper is a little awkward. We could consider `execv` but this is
complicated across platforms. An example implementation of that over in
[monotrail](433af5aed9/crates/monotrail/src/monotrail.rs (L764-L799)).
2024-07-01 20:42:02 -05:00
Charlie Marsh 8e935e2c17
Support unnamed requirements in `uv tool install` (#4716)
## Summary

This PR adds support for (e.g.) `uv tool install
git+https://github.com/psf/black`.

Closes https://github.com/astral-sh/uv/issues/4664.
2024-07-01 21:37:14 -04:00
Charlie Marsh 368276d7d1
Shared Git and in-memory index across operations (#4715)
## Summary

I ended up needing this for https://github.com/astral-sh/uv/issues/4664
but I think it's a good change more broadly. We should be able to share
this cached information across operations within a given invocation.
2024-07-01 20:27:01 -04:00
Charlie Marsh 13077406f8
Add lockfile snapshots for branching URL tests (#4713)
## Summary

These are changing in one of my branches but I can't tell _what's_
changing. Some tests include the lock, but others don't. This PR adds it
for all successful resolves in the suite.
2024-07-01 22:24:50 +00:00
Chan Kang 61014d48b0
Implement `--package` for `pip tree` (#4655)
## Summary

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

## Test Plan

The existing tests pass + added a couple of tests to ensure `--package` behaves as expected.
2024-07-01 21:12:59 +00:00
Charlie Marsh a4417eba4a
Enable projects to opt-out of workspace management (#4565)
## Summary

You can now add `managed = false` under `[tool.uv]` in a
`pyproject.toml` to explicitly opt out of the project and workspace
APIs.

If a project sets `managed = false`, we will (1) _not_ discover it as a
workspace root, and (2) _not_ discover it as a workspace member (similar
to using `exclude` in the workspace parent).

Closes https://github.com/astral-sh/uv/issues/4551.
2024-07-01 16:17:43 -04:00
Ibraheem Ahmed be2a67cd9b
Replace `map_or(false, ..)` uses with `is_some_and` and `is_ok_and` (#4703)
## Summary

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

Follow up to https://github.com/astral-sh/uv/pull/4700.
2024-07-01 15:21:38 -04:00
Ibraheem Ahmed ea031461c5
Simplify `OnceMap::wait_blocking` (#4704)
## Summary

De-duplicate by calling directly into the async version.
2024-07-01 15:17:37 -04:00
Charlie Marsh f3d1e52e65
Use `requires-python` semantics for `--universal` (#4701)
## Summary

This doesn't actually change any behaviors, but it does make it a bit
easier to solve #4669, because we don't have to support "version
narrowing" for the non-`RequiresPython` variants in here. Right now, the
semantics are kind of muddied, because the `target` variant is
_sometimes_ interpreted as an exact version and sometimes as a lower
bound.
2024-07-01 15:16:40 -04:00
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](https://github.com/astral-sh/uv/assets/1309177/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 = "a89e8120fa0bbafcb2c2387c0317be/flask-3.0.2.tar.gz", hash = "sha256:822c03f4b799204250a7ee84b1eddc40665395333973dfb9deebfe425fefcb7d", size = 675248 }
wheels = [{ url = "aa98bfe0ebf27ce224fb4f766acb23/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 = "a89e8120fa0bbafcb2c2387c0317be/flask-3.0.2.tar.gz", hash = "sha256:822c03f4b799204250a7ee84b1eddc40665395333973dfb9deebfe425fefcb7d", size = 675248 }
dependencies = [
    { name = "blinker" },
    { name = "click" },
    { name = "itsdangerous" },
    { name = "jinja2" },
    { name = "werkzeug" },
]
wheels = [{ url = "aa98bfe0ebf27ce224fb4f766acb23/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
Zanie Blue 7c3ad62544
Allow the package spec to be passed positionally in `uv tool install` (#4564)
Moves `--from` to a hidden argument — we allow it still but we validate
that it is compatible with whatever is passed to `uv tool install
<package>`. The positional package can now be a full specification,
allowing things like `uv tool install black==24.2.0`.
2024-06-27 07:35:00 -05:00
Zanie Blue cb580d1a5d
Add support for specifying `name@version` in `uv tool run` (#4572)
Instead of requiring `uv tool run --from package==version command` we
support `uv tool run command@version` shorthand.
2024-06-27 05:50:15 -05:00
Zanie Blue 857b3cc777
Add test context utility for standardized filtering of counts (#4568)
There are cases where these counts simply don't matter and we're
manually tweaking them to deal with Windows.
2024-06-27 05:48:19 -05:00
konsti 8a046313b1
Onbreak CI on main (#4577)
Merge order broke CI
2024-06-27 09:41:32 +00:00
Chan Kang c74ef75059
implement `--depth`, `--prune` for `pip tree` (#4440) 2024-06-26 19:34:31 -05:00
Zanie Blue 2eb1e6693c
Bump version to 0.2.17 (#4573) 2024-06-26 23:16:44 +00:00
Charlie Marsh bbbe1f3968
Avoid enforcing extra-only constraints (#4570)
## Summary

In the dependency refactor (https://github.com/astral-sh/uv/pull/4430),
the logic for requirements and constraints was combined. Specifically,
we were applying constraints _before_ filtering on markers and extras,
and then applying that same filtering to the constraints. As a result,
constraints that should only be activated when an extra is enabled were
being enabled unconditionally.

Closes https://github.com/astral-sh/uv/issues/4569.
2024-06-26 22:52:46 +00:00
Ibraheem Ahmed a8c28c4612
Add `--extra` to `uv add` and enable fine grained updates (#4566)
## Summary

- Adds a `--extra` flag to `uv add` that allows activating extras
without the PEP508 syntax.
- `uv add` now errors if the update is ambiguous (e.g. the dependency is
present twice with different markers)
- `uv add` is smarter about updates. For example, `uv add flask==3.0.0`
followed by `uv add flask --extra dotenv` preserves the previous version
specifier.

Resolves https://github.com/astral-sh/uv/issues/4419.
2024-06-26 22:36:07 +00:00
Charlie Marsh 95b4aacc25
Bump version to v0.2.16 (#4561) 2024-06-26 17:00:09 -04:00
Zanie Blue fc681ec738
Move from a shared `tools.toml` to separated tool receipts (#4560)
Refactors the installed tool metadata per commentary in #4492 

We now store a `uv-receipt.toml` per tool install instead of a single
`tools.toml`
2024-06-26 16:48:18 -04:00
Zanie Blue 909b69dfa2
Respect constraints passed in `uv tool install --from` (#4563)
I accidentally trimmed this to just the `requirement.name`
2024-06-26 20:32:13 +00:00
Zanie Blue b44c47fdab
Add support for `--reinstall` and `--reinstall-package` in `uv tool install` (#4504)
Adds support for `--reinstall` and `--reinstall-package` to `uv tool
install`. These are already available via the installer settings, we
just respect them now.

`--reinstall` implies a recreation of the environment and reinstallation
of the entry points.
`--reinstall-package` will only update a subset of the environment. If
the target package is the one with the entry points, we'll reinstall the
entry points. Otherwise, the entry points are not changed.
2024-06-26 20:23:34 +00:00
Zanie Blue 747ab0d9f7
Add `uv tool install --force` (#4501)
Adds detection of existing entry points, avoiding clobbering entry
points that were installed by another tool. If we see any existing entry
point collisions, we'll stop instead of overwriting them. The `--force`
flag can be used to opt-in to overwriting the files; we can't use `-f`
because it's taken by `--find-links` which is silly. The `--force` flag
also implies replacing a tool previously installed by uv (the
environment is rebuilt).

Similarly, #4504 adds support for reinstalls that _will not_ clobber
entry points managed by other tools.
2024-06-26 15:03:01 -05:00
Zanie Blue dc408146ac
Add test cases for `uv tool install` (#4509)
Adds test cases for functionality in #4492.

Includes #4520 which was needed to pass CI.
2024-06-26 14:51:32 -05:00
Ibraheem Ahmed fe13ea39f0
Rename `uv add --raw` to `--raw-sources` (#4538)
## Summary

This feels a bit clearer and less ambiguous.
2024-06-26 14:50:04 -04:00
Charlie Marsh d4fd868531
Make `uv.sources` without `--preview` non-fatal (#4558)
## Summary

Like other preview usages, this should just warn.
2024-06-26 18:07:00 +00:00
Charlie Marsh 45c271d15d
Automatically detect workspace packages in `uv add` (#4557)
## Summary

If the package _isn't_ marked as `workspace = true`, locking will fail
given:

```rust
let workspace_package_declared =
    // We require that when you use a package that's part of the workspace, ...
    !workspace.packages().contains_key(&requirement.name)
    // ... it must be declared as a workspace dependency (`workspace = true`), ...
    || matches!(
        source,
        Some(Source::Workspace {
            // By using toml, we technically support `workspace = false`.
            workspace: true,
            ..
        })
    )
    // ... except for recursive self-inclusion (extras that activate other extras), e.g.
    // `framework[machine_learning]` depends on `framework[cuda]`.
    || &requirement.name == project_name;
if !workspace_package_declared {
    return Err(LoweringError::UndeclaredWorkspacePackage);
}
```

Closes https://github.com/astral-sh/uv/issues/4552.
2024-06-26 14:03:23 -04:00
Charlie Marsh a328c7b995
Use interpreter rather than environment in uv run (#4559) 2024-06-26 13:57:08 -04:00
Charlie Marsh 963a7b2ab5
Add `--package` argument to `uv add` and `uv remove` (#4556)
## Summary

Closes https://github.com/astral-sh/uv/issues/4550.
2024-06-26 17:46:07 +00:00
Charlie Marsh 0fe5eacdba
Fallback to interpreter discovery in `uv run` (#4549)
## Summary

This PR modifies `uv run` to fallback to discovering an interpreter
(e.g., a local `.venv`) if the command is run outside of a workspace.

`uv run --isolated` continues to completely skip workspace _and_
interpreter discovering, only installing whatever's provided with
`--with`.

The next step here is adding some ergonomic controls for enabling this
behavior even if your project is technically in a workspace (i.e., you
have a `pyproject.toml` but aren't using the Project APIs and don't want
locking etc.). I could imagine a setting in `pyproject.toml` that's also
exposed on the command-line. Something like: `managed = false` or
`project = false`.

See: https://github.com/astral-sh/uv/issues/3836.
2024-06-26 12:25:18 -04:00
Zanie Blue c9657b0015
Add `uv tool install` (#4492)
This is the minimal "working" implementation. In summary, we:

- Resolve the requested requirements
- Create an environment at `$UV_STATE_DIR/tools/$name`
- Inspect the `dist-info` for the main requirement to determine its
entry points scripts
- Link the entry points from a user-executable directory
(`$XDG_BIN_HOME`) to the environment bin
- Create an entry at `$UV_STATE_DIR/tools/tools.toml` tracking the
user's request

The idea with `tools.toml` is that it allows us to perform upgrades and
syncs, retaining the original user request (similar to declarations in a
`pyproject.toml`). I imagine using a similar schema in the
`pyproject.toml` in the future if/when we add project-levle tools. I'm
also considering exposing `tools.toml` in the standard uv configuration
directory instead of the state directory, but it seems nice to tuck it
away for now while we iterate on it. Installing a tool won't perform a
sync of other tool environments, we'll probably have an explicit `uv
tool sync` command for that?

I've split out todos into follow-up pull requests:

- #4509 (failing on Windows)
- #4501 
- #4504 

Closes #4485
2024-06-26 10:24:29 -05:00
konsti b677a06aba
Break `choose_version` into three methods (#4543)
`ResolverState::choose_version` had become huge, with an odd match due
to the url handling from #4435. This refactoring breaks it into
`choose_version`, `choose_version_registry` and `choose_version_url`. No
functional changes.
2024-06-26 15:15:28 +02:00
konsti 2ef34bd65b
Remove `InMemoryIndexRef` (#4544)
`InMemoryIndex` has recently been turned into an `Arc`, so we can now
freely copy it instead using `Cow` tricks.
2024-06-26 09:11:14 -04:00
Charlie Marsh 9701ead5be
Flatten errors in registry fetch (#4546)
## Summary

Right now, the outer error is "fatal" and the inner error is
"recoverable" (in some cases), but ultimately it's all the same error
type?
2024-06-26 13:05:46 +00:00
Andrew Gallant 63dcc6fa57 uv-resolver: make `hash` on `SourceDistMetadata` required
Now that we only materialize a `SourceDist` when there is some
non-redundant information in it from `source`, we can require that a
hash is present.
2024-06-26 05:55:52 -07:00
Andrew Gallant 7c71aec68c uv-resolver: include 'sdist' entry for direct URL dependencies
In the case of a direct URL sdist, it includes a hash, and this hash is
not (and probably should not) be part of the `source`. The URL is part
of the source because it permits uniquely identifying this particular
package as distinct from any other package with the same name. But, we
should still include the hash.

So in this commit, we rejigger what we did previously to make it so the
`SourceDist` value isn't even constructed at all when it isn't needed.
This also in turn lets us make the hash field required (which we will do
in a subsequent commit).

This does mean the URL is stored twice for direct URL dependencies in
the lock file. This seems non-ideal. We could make the URL for the sdist
optional, but this seems like a bridge too far? Another choice is to add
a new key to `distribution` that is just `direct-url-hash`, but that
also seems mucky.

Maybe the duplication here is okay given the relative rarity of direct
URL dependencies.
2024-06-26 05:55:52 -07:00
Andrew Gallant 9d4681cf19 uv/tests: update snapshots for sdist omission
This updates all of the test snapshots where `sdist` was
strictly redundant and could be removed.

Note that there is one test failure whose snapshot I didn't
update: one where there is a direct URL dependency. In this
case, the sdist entry isn't strictly redundant, as it includes
a hash that isn't present in the source. We'll deal with that
in a subsequent commit.
2024-06-26 05:55:52 -07:00
Andrew Gallant 86c2a9b0b2 uv-resolver: only serialize sdist for registry sourced distributions
This fixes an issue in the lock file where, in cases where we had a
non-registry sdist, the information in the sdist was strictly redundant
with the information in the source. This was born out in the code
already where the `sdist` field was only ever used to build a source
distribution type when the source was a registry. In all other cases,
the source distribution data can be materialized from the `source`
field.
2024-06-26 05:55:52 -07:00
Andrew Gallant 4899612619 uv-resolver: refactor Distribution::to_dist
This makes it clear that an actual `sdist` is only required when a
distribution is from a registry. In all other cases, a source
distribution is manufactured directly from the `source`.
2024-06-26 05:55:52 -07:00
Andrew Gallant 840f61fc2b uv-resolver: re-arrange some code
Previously, we had Lock and LockWire impl blocks inter-mixed. This bugs
me a bit, so I've just shuffled things around so that we have Lock, impl
Lock, LockWire and then impl LockWire.

No changes are otherwise made to the code here.
2024-06-26 05:55:52 -07:00
Charlie Marsh a5b5856521
Gracefully handle non-existent packages in local indexes (#4545)
## Summary

Ensures that local indexes can be used as `--extra-index-url` by
gracefully handling "404" errors.

Closes https://github.com/astral-sh/uv/issues/4540.
2024-06-26 12:54:38 +00:00
konsti d7f195fdc9
Add `PubGrubPackage::name_no_root` (#4542)
Small code style improvement.
2024-06-26 12:29:26 +00:00
Andrew Gallant 89bef7bf09 uv/tests: update lock file snapshots
This update follows from the removal of of `source` and `version` from
`distribution.dependency` entries in the lock file when the package name
unambiguously refers to a single distribution.
2024-06-26 05:18:23 -07:00
Andrew Gallant 4accbfd915 uv-resolver: support unambiguous omission of 'source' and 'version'
When there is only one distribution for a particular package name, any
dependencies (the edges in the resolution graph) that reference that
package name are completely unambiguous. Therefore, we can actually omit
their version and source information and instead derive it from the
distribution entry.

We add some tests to check the success and error cases. That is, when
`source` or `version` are omitted and there are more than one
corresponding distribution for the package name (i.e., it's ambiguous),
then lock deserialization should fail.
2024-06-26 05:18:23 -07:00
Andrew Gallant 4cb1595136 uv-resolver: refactor lock data type deserialization
This commit prepares to make the `source` and `version` fields optional
in a `distribution.dependency` based on whether they have an unambiguous
value. e.g., When there is exactly one distribution with a matching
package name.

This refactor effectively defines "wire" types for most of the lock data
types (repeating the `WheelWire` and `LockWire` pattern) with one key
difference: we don't use serde's `TryFrom` integration. In this
refactor, we could have, and it would have worked. But in a subsequent
commit, we're going to be adding state to the `unwire()` calls that is
impossible to thread through a `TryFrom` implementation. This state will
tell us how to populate the `source` and `version` values on a
`Dependency` when they're missing.

The duplication of types here is unfortunate, but compiler should catch
any deviations. And the wire types are unexported, so they have a
limited blast radius on complexity.
2024-06-26 05:18:23 -07:00
konsti d9dbb8a4af
Support conflicting URL in separate forks (#4435)
Downstack PR: #4481

## Introduction

We support forking the dependency resolution to support conflicting
registry requirements for different platforms, say on package range is
required for an older python version while a newer is required for newer
python versions, or dependencies that are different per platform. We
need to extend this support to direct URL requirements.

```toml
dependencies = [
  "iniconfig @ 62565a6e1ceac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl ; python_version >= '3.12'",
  "iniconfig @ b3c12c6d70988d7baea9578f3c48f3/iniconfig-1.1.1-py2.py3-none-any.whl ; python_version < '3.12'"
]
```

This did not work because `Urls` was built on the assumption that there
is a single allowed URL per package. We collect all allowed URL ahead of
resolution by following direct URL dependencies (including path
dependencies) transitively, i.e. a registry distribution can't require a
URL.

## The same package can have Registry and URL requirements

Consider the following two cases:

requirements.in:
```text
werkzeug==2.0.0
werkzeug @ 960bb4017c4aed12b5ed8b78e0153e/Werkzeug-2.0.0-py3-none-any.whl
```
pyproject.toml:
```toml
dependencies = [
  "iniconfig == 1.1.1 ; python_version < '3.12'",
  "iniconfig @ git+https://github.com/pytest-dev/iniconfig@93f5930e668c0d1ddf4597e38dd0dea4e2665e7a ; python_version >= '3.12'",
]
```

In the first case, we want the URL to override the registry dependency,
in the second case we want to fork and have one branch use the registry
and the other the URL. We have to know about this in
`PubGrubRequirement::from_registry_requirement`, but we only fork after
the current method.

Consider the following case too:

a:
```
c==1.0.0
b @ https://b.zip
```
b:
```
c @ https://c_new.zip ; python_version >= '3.12'",
c @ https://c_old.zip ; python_version < '3.12'",
```

When we convert the requirements of `a`, we can't know the url of `c`
yet. The solution is to remove the `Url` from `PubGrubPackage`: The
`Url` is redundant with `PackageName`, there can be only one url per
package name per fork. We now do the following: We track the urls from
requirements in `PubGrubDependency`. After forking, we call
`add_package_version_dependencies` where we apply override URLs, check
if the URL is allowed and check if the url is unique in this fork. When
we request a distribution, we ask the fork urls for the real URL. Since
we prioritize url dependencies over registry dependencies and skip
packages with `Urls` entries in pre-visiting, we know that when fetching
a package, we know if it has a url or not.

## URL conflicts

pyproject.toml (invalid):
```toml
dependencies = [
  "iniconfig @ e96292c7f723f1fa332fe4ed6dfbec/iniconfig-1.1.0.tar.gz",
  "iniconfig @ b3c12c6d70988d7baea9578f3c48f3/iniconfig-1.1.1-py2.py3-none-any.whl ; python_version < '3.12'",
  "iniconfig @ 62565a6e1ceac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl ; python_version >= '3.12'",
]
```

On the fork state, we keep `ForkUrls` that check for conflicts after
forking, rejecting the third case because we added two packages of the
same name with different URLs.

We need to flatten out the requirements before transformation into
pubgrub requirements to get the full list of other requirements which
may contain a URL, which was changed in a previous PR: #4430.

## Complex Example

a:
```toml
dependencies = [
  # Force a split
  "anyio==4.3.0 ; python_version >= '3.12'",
  "anyio==4.2.0 ; python_version < '3.12'",
  # Include URLs transitively
  "b"
]
```
b:
```toml
dependencies = [
  # Only one is used in each split.
  "b1 ; python_version < '3.12'",
  "b2 ; python_version >= '3.12'",
  "b3 ; python_version >= '3.12'",
]
```
b1:
```toml
dependencies = [
  "iniconfig @ b3c12c6d70988d7baea9578f3c48f3/iniconfig-1.1.1-py2.py3-none-any.whl",
]
```
b2:
```toml
dependencies = [
  "iniconfig @ 62565a6e1ceac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl",
]
```
b3:
```toml
dependencies = [
  "iniconfig @ e96292c7f723f1fa332fe4ed6dfbec/iniconfig-1.1.0.tar.gz",
]
```

In this example, all packages are url requirements (directory
requirements) and the root package is `a`. We first split on `a`, `b`
being in each split. In the first fork, we reach `b1`, the fork URLs are
empty, we insert the iniconfig 1.1.1 URL, and then we skip over `b2` and
`b3` since the mark is disjoint with the fork markers. In the second
fork, we skip over `b1`, visit `b2`, insert the iniconfig 2.0.0 URL into
the again empty fork URLs, then visit `b3` and try to insert the
iniconfig 1.1.0 URL. At this point we find a conflict for the iniconfig
URL and error.

## Closing

The git tests are slow, but they make the best example for different URL
types i could find.

Part of #3927. This PR does not handle `Locals` or pre-releases yet.
2024-06-26 13:58:23 +02:00
Charlie Marsh ca92b55605
Make `.egg-info` filename parsing spec compliant (#4533)
## Summary

It turns out that `.egg-info` files and directories can _both_ have up
to four segments in the filename:
https://setuptools.pypa.io/en/latest/deprecated/python_eggs.html#filename-embedded-metadata.
This PR upgrades the parsing and now uses the same parsing for files and
directories.

Closes https://github.com/astral-sh/uv/issues/4532.
2024-06-25 23:49:43 +00:00
Charlie Marsh 41f051db3b
Remove exclude newer methods on test context (#4535)
## Summary

Closes https://github.com/astral-sh/uv/issues/4531.
2024-06-25 23:45:35 +00:00
konsti c28a2c7583
Small `lock.rs` improvements (#4239)
Small improvements i made reading through `lock.rs`.
2024-06-25 22:19:00 +00:00
konsti ff2f927579
Replace `PubGrubDependencies` by `PubGrubDependency` (#4481)
In the last PR (#4430), we flatten the requirements. In the next PR
(#4435), we want to pass `Url` around next to `PubGrubPackage` and
`Range<Version>` to keep track of which `Requirement`s added a url
across forking. This PR is a refactoring split out from #4435 that rolls
the dependency conversion into a single iterator and introduces a new
`PubGrubDependency` struct as abstraction over `(PubGrubPackage,
Range<Version>)` (or `(PubGrubPackage, Range<Version>,
VerbatimParsedUrl)` in the next PR), and it removes the now unnecessary
`PubGrubDependencies` abstraction.
2024-06-25 22:11:52 +00:00
konsti e6103dcab1
Deduplicate test command creation (#4512)
This PR refactors the command creation in the test suite to remove the
duplication.

**1)** We add the same set of test stubbing args to almost any uv
invocation in the tests:

```rust
command
    .arg("--cache-dir")
    .arg(self.cache_dir.path())
    .env("VIRTUAL_ENV", self.venv.as_os_str())
    .env("UV_NO_WRAP", "1")
    .env("HOME", self.home_dir.as_os_str())
    .env("UV_TOOLCHAIN_DIR", "")
    .env("UV_TEST_PYTHON_PATH", &self.python_path())
    .current_dir(self.temp_dir.path());

if cfg!(all(windows, debug_assertions)) {
    // TODO(konstin): Reduce stack usage in debug mode enough that the tests pass with the
    // default windows stack of 1MB
    command.env("UV_STACK_SIZE", (8 * 1024 * 1024).to_string());
}
```

Centralizing these into a `TestContext::add_shared_args` method removes
them from everywhere.

**2)** Prefix all `TextContext` methods of the pip interface with
`pip_`. This is now necessary due to `uv sync` vs. `uv pip sync`.

**3)** Move command creation in the various test files into dedicated
functions or methods to avoid repeating the arguments. Except for error
message tests, there should be at most one `Command::new(get_bin())`
call per test file. `EXCLUDE_NEWER` is exclusively used in
`TestContext`.

---

I'm considering adding a `TestCommand` on top of these changes (in
another PR) that holds a reference to the `TextContext`, has
`add_shared_args` as a method and uses `Fn(Self) -> Self` instead of
`Fn(&mut Self) -> Self` for methods to improved chaining.
2024-06-25 22:06:54 +00:00
Charlie Marsh e1708689a9
Add a universal resolution mode to `pip compile` (#4505)
## Summary

This needs more tests and a few more changes, but checkpointing it for
now.
2024-06-25 21:28:50 +00:00
konsti f2f48d339e
Flatten requirements eagerly in `get_dependencies` (#4430)
Downstack PR: #4515 Upstack PR: #4481

Consider these two cases:

A:
```
werkzeug==2.0.0
werkzeug @ 960bb4017c4aed12b5ed8b78e0153e/Werkzeug-2.0.0-py3-none-any.whl
```

B:
```toml
dependencies = [
  "iniconfig == 1.1.1 ; python_version < '3.12'",
  "iniconfig @ git+https://github.com/pytest-dev/iniconfig@93f5930e668c0d1ddf4597e38dd0dea4e2665e7a ; python_version >= '3.12'",
]
```

In the first case, `werkzeug==2.0.0` should be overridden by the url. In
the second case `iniconfig == 1.1.1` is in a different fork and must
remain a registry distribution.

That means the conversion from `Requirement` to `PubGrubPackage` is
dependent on the other requirements of the package. We can either look
into the other packages immediately, or we can move the forking before
the conversion to `PubGrubDependencies` instead of after. Either version
requires a flat list of `Requirement`s to use. This refactoring gives us
this list.

I'll add support for both of the above cases in the forking urls branch
before merging this PR. I also have to move constraints over to this.
2024-06-25 21:13:47 +00:00
Zanie Blue e242cdf713
Update `project::update_environment` to respect reinstall options (#4502)
While working on https://github.com/astral-sh/uv/pull/4492 I noticed
that `--reinstall-package` was not actually respected by
`update_environment`, it exited early due to satisfied requirements.

Before

```

❯ cargo run -q -- tool install black -v --reinstall-package tomli
...
DEBUG All requirements satisfied: black | click>=8.0.0 | mypy-extensions>=0.4.3 | packaging>=22.0 | pathspec>=0.9.0 | platformdirs>=2 | tomli>=1.1.0 ; python_version < '3.11' | typing-extensions>=4.0.1 ; python_version < '3.11'
```

After

```
❯ cargo run -q -- tool install black -v --reinstall-package tomli
...
Uninstalled 1 package in 0.99ms
Installed 1 package in 4ms
 - tomli==2.0.1
 + tomli==2.0.1
```
2024-06-25 17:12:51 -04:00
Charlie Marsh 08bf6fb87c
Deduplicate source edges in annotations (#4530)
## Summary

Not relevant today, but it will be once we support universal resolution,
in which a package can be repeated.
2024-06-25 21:10:09 +00:00
konsti ad42206e50
Unify dependency iteration in `ResolverState::get_dependencies` (#4515)
Upstack PR: #4430

Split out from #4430 according to
https://github.com/astral-sh/uv/pull/4430#discussion_r1650192338.
2024-06-25 23:04:49 +02:00
Charlie Marsh 5732209be3
Add support for `--no-strip-markers` in `pip compile` output (#4503)
## Summary

This is an intermediary change in enabling universal resolution for
`requirements.txt` files. To start, we need to be able to preserve
markers in the `requirements.txt` output _and_ propagate those markers,
such that if you have a dependency that's only included with a given
marker, the transitive dependencies respect that marker too.

Closes #1429.
2024-06-25 20:55:58 +00:00
konsti af1f1369e5
Remove useless `#[allow(clippy::too_many_arguments)]` (#4529)
I went through all `#[allow(clippy::too_many_arguments)]` and removed
the useless ones.
2024-06-25 19:09:59 +00:00
Charlie Marsh a81742c06b
Read persistent configuration from non-workspace `pyproject.toml` (#4526)
## Summary

If the user puts their configuration in a `pyproject.toml` that _isn't_
a valid workspace root (e.g., it's a Poetry file), we won't discover it,
because we only look in `uv.toml` files in that case. I think this is
somewhat debatable... We could choose to _require_ `uv.toml` there, but
as a user I'd probably expect it to work?

Closes https://github.com/astral-sh/uv/issues/4521.
2024-06-25 18:53:14 +00:00
Zanie Blue 5641f3a5d9
Add guard to `replace_symlink` on Windows (#4519)
`junction::create` apparently will happily succeed but not create a link
to files? Since our symlink function does not indicate that it cannot
handle files, this was quite surprising.


Tested over in #4509 which previously failed on an assertion that
`black.exe` existed.
```
error: Failed to install entrypoint
    Caused by: Cannot create a junction for [TEMP_DIR]/tools/black/Scripts/black.exe: is not a directory
```

We should file an issue upstream too, I think?
2024-06-25 13:47:40 -05:00
Charlie Marsh a07e70d93a
Avoid panic for invalid, non-base index URLs (#4527)
## Summary

See: https://github.com/astral-sh/uv/issues/4510
2024-06-25 18:32:58 +00:00
Charlie Marsh 904957bf80
Allow local index references in `requirements.txt` files (#4525)
## Summary

We currently accept `--index-url /path/to/index` on the command line,
but confusingly, not in `requirements.txt`. This PR just brings the two
in sync.

## Test Plan

New snapshot tests.
2024-06-25 18:06:37 +00:00
Charlie Marsh e39f5f72fe
Allow non-file:// paths to serve as `--index-url` values (#4524)
## Summary

pip allows these with the following logic:

```python
if os.path.exists(location):  # Is a local path.
    url = path_to_url(location)
    path = location
elif location.startswith("file:"):  # A file: URL.
    url = location
    path = url_to_path(location)
elif is_url(location):
    url = location
```

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

## Test Plan

`cargo run pip install --index-url ../packse/index/simple-html/
example-a-961b4c22 --reinstall --no-cache --no-deps`
2024-06-25 17:57:12 +00:00
Andrew Gallant 3379e4c8c2
uv/tests: tweak toolchain_find test (#4523)
I was getting this test failure locally on my Archlinux system:

```
-old snapshot
+new results
    0     0 │ success: true
    1     1 │ exit_code: 0
    2     2 │ ----- stdout -----
    3       │-[PYTHON-3.12]
          3 │+/usr/bin/python3
    4     4 │
    5     5 │ ----- stderr -----
```

Where I have `/usr/bin/python3` and `/usr/bin/python3.12`.

Thanks @zanieb for the help with figuring out the fix here!
2024-06-25 13:23:36 -04:00
Zanie Blue 7fe7d8b34e
Fix symlink doc (#4514)
This bit me.
2024-06-25 08:27:03 -05:00
Zanie Blue e25cbee4d2
Isolate the tests from the real home directory (#4508)
Nice to have for #4492 and seems like a good idea in general to avoid
mutating a developer's machine.
2024-06-25 07:47:55 -05:00
Eric Mark Martin 967f136564
More precise locking with --prefix option (#4506)
## Summary

In #4085, support was implemented for the `--prefix` option. When using
this option, however, a lock is either acquired on the virtualenv or
globally, preventing multiple installs to different `--prefix`s from the
same interpreter.

In this change, acquire the lock on just the prefix in question.

## Test Plan

Ran a `uv pip install` with `--prefix` and `RUST_LOG=trace` and observed
that the lock was acquired in the prefix.
2024-06-25 06:47:52 -04:00
Charlie Marsh ddacede7db
Move requirements.txt distribution into separate file (#4500)
## Summary

No functional changes, but this has outgrown being in the module root.
2024-06-25 00:32:44 +00:00
Charlie Marsh 7946509931
Change Operations API to always accept `PythonRequirement` (#4498)
## Summary

I think this is more intuitive than taking an `Option` and computing the
requirement if it's `None`.
2024-06-24 23:37:08 +00:00
Zanie Blue 25cde888ae
Rename `SitePackages::from_environment` for clarity (#4497) 2024-06-24 23:32:45 +00:00
Charlie Marsh 604be9ed71
Use `Preferences` struct in Manifest API (#4496)
## Summary

This is just a bit more consistent with `Overrides` and `Constraints`.
2024-06-24 23:28:55 +00:00
Charlie Marsh 10ec9c9d0b
Use operations API in `pip compile` (#4493)
## Summary

Closes https://github.com/astral-sh/uv/issues/4235.
2024-06-24 22:20:03 +00:00
Charlie Marsh 9905521957
Use shared client in Git fetch implementation (#4487)
## Summary

It turns out that the Git fetch implementation is initializing its own
client, which can be really expensive on macOS (due to loading native
certificates) _and_ bypasses any of our middleware. This PR modifies the
Git implementation to accept a shared client.
2024-06-24 17:09:29 -04:00
Charlie Marsh 7221514136
Make overrides a workspace method (#4491)
## Summary

No functional changes; just encapsulating the logic within the workspace
module.
2024-06-24 17:09:23 -04:00
Charlie Marsh 7d3fb4330f
Skip submodule update for fresh clones (#4482)
## Summary

We unconditionally update the submodules in our Git code, but AFAICT it
shouldn't be necessary if we already have a complete, up-to-date fetch
available.
2024-06-24 17:09:14 -04:00
Charlie Marsh 849478fa91
Add unowned settings variants (#4490)
## Summary

This PR adds unowned settings variants so that we can convert from
`ResolverInstallerSettings` to `ResolverSettings` without allocating.
2024-06-24 20:18:16 +00:00
Charlie Marsh 8afad69b03
Implement settings conversion traits (#4489)
## Summary

This does require cloning the settings, but I think it's fine. A better
solution would be to have owned and unowned settings structs, so that we
could convert `ResolverInstallerSettingsRef` to `InstallerSettingsRef`
without cloning, but that requires maintaining owned and unowned
variants.

Closes https://github.com/astral-sh/uv/issues/4455.
2024-06-24 16:08:11 -04:00
Charlie Marsh ff72bb9bcc
Read content length from response rather than request (#4488)
## Summary

I might be mistaken, but I think we need to read the header from the
response, not the request. The request would only contain headers that
we set.

I verified (with extra logging) that the request header is `None` while
PyPI returns a valid length in the response header.
2024-06-24 15:58:21 -04:00
Charlie Marsh f6aec0a96c
Remove non-existent extras from lockfile (#4479)
## Summary

Ultimately decided to view this as part of `LockWire` normalization:
removing references to extras that don't exist. I think it would be nice
if the resolver avoided omitting these, but I don't know if it's fully
possible.

Closes https://github.com/astral-sh/uv/issues/4405.
2024-06-24 14:56:56 -04:00
konsti 1984ada57c
Break `PubGrubReportFormatter::hints` into methods (#4478)
I have to add yet another indentation level to the prerelease-available
check in `PubGrubReportFormatter::hints` for #4435, so i've broken the
code into methods and decreased indentation in this split out
refactoring-only change.
2024-06-24 19:14:09 +02:00
Chan Kang c127632419
implement `--no-dedupe` for `uv pip tree` (#4449)
<!--
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/4439 partially.

Implements for `uv pip tree`:
- `--no-dedupe` flag, similar to `cargo tree --no-dedupe` .
- denote dependency cycles with `(#)` and add a footnote if there's a
cycle (using `(*)` would require keeping track of the cycle state, so
opted to do this instead).
<!-- What's the purpose of the change? What does it do, and why? -->

## Test Plan
The existing tests pass + added a couple of tests to validate
`--no-dedupe` behavior.
<!-- How was it tested? -->
2024-06-24 11:54:55 -05:00
Sandu 03cfdc2275
uv lock to use overrides from tool.uv (#4108) (#4369)
## Summary

This will make `uv lock` read `override-dependencies` from the
`[tool.uv]` section of `pyproject.toml`.
Resolves #4108

This [other](https://github.com/astral-sh/uv/pull/4446) implementation
touches more code but seems more consistent.

## Test Plan

Unit test
2024-06-24 12:44:54 -04:00
Zanie Blue bfc342da94
Bump version to 0.2.15 (#4475)
Releasing 0.2.15 with a few additions over 0.2.14. Motivated by the
incorrect tagging of 0.2.14 (#4474).

Generated the changelog with a small patch to Rooster allowing me to
force the previous commit to be correct.

```diff
diff --git a/src/rooster/_cli.py b/src/rooster/_cli.py
index 2a4f61b..4ec1299 100644
--- a/src/rooster/_cli.py
+++ b/src/rooster/_cli.py
@@ -38,6 +38,7 @@ def release(
     without_sections: list[str] = typer.Option(
         [], help="Sections to exclude from the changelog"
     ),
+    previous_commit: str = None,
 ):
     """
     Create a new release.
@@ -58,7 +59,11 @@ def release(
         typer.echo("It looks like there are no version tags for this project.")
 
     # Get the commits since the last release
-    changes = list(get_commits_between(config, repo, last_version))
+    changes = list(
+        get_commits_between(
+            config, repo, last_version, force_first_commit=previous_commit
+        )
+    )
     since = "since last release" if last_version else "in the project"
     typer.echo(f"Found {len(changes)} commits {since}.")
 
diff --git a/src/rooster/_git.py b/src/rooster/_git.py
index 597bb88..66bc54e 100644
--- a/src/rooster/_git.py
+++ b/src/rooster/_git.py
@@ -29,12 +29,13 @@ def get_commits_between(
     target: Path,
     first_version: Version | None = None,
     second_version: Version | None = None,
+    force_first_commit: str | None = None,
 ) -> Generator[git.Commit, None, None]:
     """
     Yield all commits between two tags
     """
     repo = git.repository.Repository(target.absolute())
-    first_commit = (
+    first_commit = force_first_commit or (
         repo.lookup_reference(
             TAG_PREFIX + config.version_tag_prefix + str(first_version)
         )
```
2024-06-24 10:04:09 -05:00
konsti 40f852687b
Add context to unregistered task name to error context (#4471)
I caused this error during development and having the name of the task
on it is helpful for debugging.

Split out from #4435
2024-06-24 14:42:55 +00:00
Zanie Blue 64e07b68a8
Reapply "Bump version to 0.2.14" (#4472)
Restores #4431

This reverts commit 9ff6a5ed74 (#4436)
2024-06-24 09:14:16 -05:00
Charlie Marsh f07308823e
Add `--emit-build-options` flag to `uv pip compile` interface (#4463)
## Summary

Closes https://github.com/astral-sh/uv/issues/4420.
2024-06-24 12:25:01 +00:00
Charlie Marsh cba270f750
Respect index strategy in source distribution builds (#4468)
## Summary

The `--index-strategy` is linked to the index locations, which we
propagate to source distribution builds; so it makes sense to pass the
`--index-strategy` too.

While I was here, I made `exclude_newer` a required argument so that we
don't forget to set it via the `with_options` builder.

Closes https://github.com/astral-sh/uv/issues/4465.
2024-06-24 12:03:38 +00:00
Charlie Marsh 1eee427c94
Add standalone CLI crate (#4456)
## Summary

This PR moves all the CLI code into its own crate, separate from the
`uv` crate. The `uv` crate is iterated on frequently, and the CLI code
comprises a significant portion of it but rarely changes. Removing the
CLI code reduces the `uv` crate size from 1.4MiB to 1.0MiB.
2024-06-24 06:16:22 -04:00
renovate[bot] 3251690327
Update Rust crate rustc-hash to v2 (#4461) 2024-06-24 01:13:05 +00:00
Charlie Marsh 757ea61bea
Fix casing of `--no-compile` alias (#4453)
## Summary

Closes https://github.com/astral-sh/uv/issues/4452.
2024-06-23 17:25:50 +00:00
Zanie Blue d4f2a8a52f
Adjust the docs for the pip CLI commands (#4445) 2024-06-23 12:03:49 -04:00
Zanie Blue 03e2e6b99a
Fix construction of Python path in test context (#4443)
When executables were not named `python3` e.g. `python3.11` we would
construct a Python path that would only work for _some_ requests in
tests since we don't search for those names unless a specific version is
requested. To solve, we construct a test context with constant Python
executable names. For example, if a test context was created with `3.11`
and `3.12` we could end up with the search path
`/usr/local/python-3.11/bin:/usr/local/python-3.12/bin` where the
executables are named `python3.11` and `python3` respectively. A test
invocation of uv requesting any Python toolchain version would then
locate the `3.12` executable since the `3.11` executable doesn't have
the generic name, but we want `3.11` to come first.

On Windows, we just leave things as-is because executables are always
called `python.exe`.

Closes https://github.com/astral-sh/uv/issues/4376
2024-06-23 10:05:48 -05:00
samypr100 2288ff7bf4
feat: pythonw support on gui scripts (#4409)
## Summary

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

This changes the bootstrap launcher script to use `pythonw.exe` instead
of `python.exe` on `gui_scripts` via a helper fn both in the shebang and
the python exe path encoded before `UVUV` magic, that way
uv-trampoline's `find_python_exe` can use the right pythonw executable.

## Test Plan

New unit tests for the helper was added.
Tested on example from #2956 on Windows to make sure it works as
expected.

## Questions

I noticed the docs in `fn windows_script_launcher` says ```The launcher
will look for `python[w].exe` adjacent to it in the same directory to
start the embedded script.``` but I didn't find such functionality when
I looked in uv-trampoline.
I only saw `clear_app_starting_state` getting called when `is_gui` is
set.

Was the intention to do this in uv-trampoline at some point instead?

---------

Co-authored-by: konstin <konstin@mailbox.org>
2024-06-23 09:48:47 +00:00
Zanie Blue 3a63e1410d
Adjust deduplicated message in `pip tree` (#4448) 2024-06-22 14:53:01 +00:00
Zanie Blue c7149e96ca
Collapse duplicate toolchain search in test setup (#4442) 2024-06-22 09:43:03 -05:00
Zanie Blue 8f2d8b3f4f
Fix ordering of prefer-system toolchain preference (#4441)
Whoopsies!
2024-06-22 09:42:51 -05:00
Chan Kang dd45fce2d4
implement `uv pip tree` (#3859)
## Summary

resolves https://github.com/astral-sh/uv/issues/3272

added it as a new subcommand rather than a flag on an existing
command since that seems more consistent with `cargo tree` + cleaner
code organization, but can make changes if it's preferred the other way.
2024-06-21 15:48:30 -04:00
Zanie Blue 9ff6a5ed74
Revert "Bump version to 0.2.14 (#4431)" (#4436)
This reverts commit e0ad649c74.

We shouldn't be linking to this version in the readme.

See https://github.com/astral-sh/uv/issues/4432
2024-06-21 16:24:32 +00:00
Zanie Blue e0ad649c74
Bump version to 0.2.14 (#4431) 2024-06-20 13:58:10 -05:00
Zanie Blue 93c6e0df56
Expose `toolchain-preference` as a CLI and configuration file option (#4424)
Exposes the option added in #4416. Adds `--toolchain-preference` and
`tool.uv.toolchain-preference` to configure if system or managed
toolchains are preferred. Users can opt-out of managed toolchains or
system toolchains entirely as well.
2024-06-20 13:42:09 -05:00
Ibraheem Ahmed e797d3eb5c
Pin benchmark requirements (#4429)
## Summary

This should make benchmarks more consistent.
2024-06-20 14:13:38 -04:00
Zanie Blue e783a79955
Add `PythonEnvironment::find` API (#4423)
Restores the `PythonEnvironment::find` API which was removed a while
back in favor of `Toolchain::find`. As mentioned in #4416, I'm
attempting to separate the case where you want an active environment
from the case where you want an installed toolchain in order to create
environments.

I wanted to drop `EnvironmentPreference` from `Toolchain::find` and just
have us consistently consider (or not consider) virtual environments
when discovering toolchains for creating environments. Unfortunately
this caused a few things to break so I reverted that change and will
explore it separately. Because I was exploring that change, there are
some minor changes to the `Toolchain` API here.
2024-06-20 17:54:17 +00:00
Zanie Blue 13e532ccda
Add internal options for managing toolchain discovery preferences (#4416)
Adds support for the toolchain discovery preferences outlined in
https://github.com/astral-sh/uv/issues/4198 but we don't expose this to
users yet, I'll do that next to make it easier to review.

I've made some refactors in the toolchain discovery implementation to
enable this behavior and move us towards clearer abstractions. There's
still remaining work here, but I'd prefer tackle things in follow-ups
instead of expanding this pull request. I plan on opening a couple
before merging this.

I'd like to shift the public toolchain API to focus on discovering
either an **environment** or a **toolchain**. The first would be used by
commands that operate on an environment, while the latter would be used
by commands that just need an interpreter to create environments. I
haven't changed this here, but some of the refactors are in preparation
for supporting this idea.

In brief:

- We now allow different ordering of installed toolchain discovery based
on a `ToolchainPreference` type. This is the type we will expose to
users.
- `SystemPython` was changed into an `EnvironmentPreference` which is
used to determine if we should prefer virtual or system Python
environments.
- We drop the whole `ToolchainSources` selection concept, it was
confusing and the error messages from it were awkward. Most of the
functionality is now captured by the preference enums, but you can't do
things like "only find a toolchain from the parent interpreter" as
easily anymore.
2024-06-20 08:57:05 -05:00
konsti b865341517
Use correct lock path for workspace dependencies (#4421)
Previously, distributions created through `Source::Workspace` would have
the absolute path as lock path. This didn't cause any problems, since in
`Urls` we would later overwrite those urls with the correct one created
from being workspace members by path.

Changing the order surfaced this. This change emits the correct lock
path. I've manually checked the difference with `dbg!`, this is not
observable on main, but on the diverging urls branch it fixes lockfile
creation.
2024-06-20 13:28:47 +00:00
Andrew Gallant fc7c318dd0 uv/tests: add sibling fork filter dependency test
This is from: https://github.com/astral-sh/packse/pull/197
2024-06-20 07:21:45 -04:00
Andrew Gallant 9595a511cd uv-resolver: filter out sibling dependencies in a fork
When a fork is created from a list of dependencies, we were previously
adding all other sibling dependencies to every fork created. But this
isn't actually quite right, since the fork created is always created by
some marker expression. And while it is definitively disjoint from any
directly conflicting dependency specification, it is also possibly
disjoint with other dependencies. For example, as reported in #4414:

```toml
dependencies = [
  "anyio==4.4.0 ; python_version >= '3.12'",
  "anyio==4.3.0 ; python_version < '3.12'",
  "b1 ; python_version >= '3.12'",
  "b2 ; python_version < '3.12'",
]
```

The first two `anyio` requirements are conflicting with non-overlapping
marker expressions, and so a fork is created. Prior to this commit,
*both* `b1` and `b2` would be added to each fork. But of course, `b2` is
impossible in the `anyio==4.4.0` fork because of disjoint marker
expressions.

So in this commit, we specifically filter out any sibling dependencies
that could find their way into a fork that have disjoint markers with
that fork. We are careful to do this both when a new fork is created
from an existing set of dependencies, and when adding new dependencies
to a fork.

Fixes #4414
2024-06-20 07:21:45 -04:00
Zanie Blue 34c7bc5cc8
Refactor Python executable chain into lazy variables (#4318)
In preparation for changing the order dynamically in #4416
2024-06-19 15:27:02 -05:00
Ibraheem Ahmed 7b72b55af8
Opt-out `tool.uv.sources` support for `uv add` (#4406)
## Summary

After this change, `uv add` will try to use `tool.uv.sources` for all
source requirements. If a source cannot be resolved, i.e. an ambiguous
Git reference is provided, it will error. Git references can be
specified with the `--tag`, `--branch`, or `--rev` arguments. Editables
are also supported with `--editable`.

Users can opt-out of `tool.uv.sources` support with the `--raw` flag,
which will force uv to use `project.dependencies`.

Part of https://github.com/astral-sh/uv/issues/3959.
2024-06-19 14:20:16 -04:00
konsti 3c5b13695e
Move adding dependencies for versions into dedicated method (#4410)
To support diverging urls, we have to check urls when adding
dependencies (after forking). To prepare for this, i've moved adding
dependencies for the current version to
`SolveState::add_package_version_dependencies` and removed the
duplication when checking for self-dependencies.

This changed is joined with a change in pubgrub
(https://github.com/astral-sh/pubgrub/pull/27) that simplifies the same
code path.
2024-06-19 20:19:12 +02:00
Zanie Blue a68146d978
Support toolchain requests with platform-tag style Python implementations and version (#4407)
Closes https://github.com/astral-sh/uv/issues/4399

---------

Co-authored-by: Andrew Gallant <andrew@astral.sh>
2024-06-19 17:04:24 +00:00
Zanie Blue e5f061e1f1
Add test case for wheel with the same name at a different absolute path (#4398)
As discussed at
https://github.com/astral-sh/uv/pull/4396#issuecomment-2176741999

This may not be the desired behavior, but let's track it.
2024-06-19 15:08:01 +00:00
Zanie Blue 1f2dd5b942
Remove stale comment (#4413) 2024-06-19 15:01:33 +00:00
Zanie Blue 39da3917e5
Improve handling of command arguments in `uv run` and `uv tool run` (#4404)
Closes https://github.com/astral-sh/uv/issues/4390

We no longer require `--` to disambiguate child command options that
overlap with uv options.
2024-06-19 14:55:21 +00:00
Zanie Blue 9a3b8511f1
Treat mismatched directory and file urls as unsatisfied requirements (#4393)
Closes https://github.com/astral-sh/uv/issues/4391
2024-06-19 14:50:13 +00:00
Zanie Blue 0db5ce0e98
Filter uv version display in standard filters (#4403)
No reason for these to be special-cased and I need them for #4404 tests
2024-06-19 09:46:40 -05:00
Zanie Blue 2b74d13f40
Fix test case for `toolchain find` with no intepreters (#4408) 2024-06-19 09:40:10 -05:00
Zanie Blue 549d7dfe37
Add test case for wheel installation with different path (#4396)
Regression test for #4391 / https://github.com/astral-sh/uv/pull/4393
2024-06-19 09:39:55 -05:00
Zanie Blue f219f88553
Rename `Downloader` for clarity (#4395)
Follow-up to https://github.com/astral-sh/uv/pull/4394 with internal
refactor
2024-06-18 16:00:10 -05:00
Zanie Blue b22ee82f0d
Use "Prepared" instead of "Downloaded" in logs (#4394)
We download, build, and unzip packages in this stage. The current name
is very misleading.

Closes https://github.com/astral-sh/uv/issues/4011
2024-06-18 13:38:18 -05:00
konsti e486eb86b7
Log when we fork (#4386)
We currently don't log if or when we split the resolution graphs into
forks. I ran into this when trying to debug missing forking.
2024-06-18 11:47:06 -05:00
Zanie Blue fa6ed34105
Bump version to 0.2.13 (#4388) 2024-06-18 11:46:32 -05:00
Ibraheem Ahmed eefc8c6d3c
Add `--workspace` option to `uv add` (#4362)
## Summary

Implements `uv add foo --workspace`, which adds `foo` as a workspace
dependency with the corresponding `tool.uv.sources` entry.

Part of https://github.com/astral-sh/uv/issues/3959.
2024-06-18 16:26:07 +00:00
Zanie Blue b3e3d899e5
Use `&impl AsRef<Path>` instead of type parameter (#4383) 2024-06-18 15:54:07 +00:00