Commit Graph

3925 Commits

Author SHA1 Message Date
Charlie Marsh 7551097a17
Add env var to `--link-mode=copy` warning (#6103)
## Summary

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

## Test Plan

![Screenshot 2024-08-14 at 9 35
45 PM](https://github.com/user-attachments/assets/f2cf6382-dfc3-4c0f-abc2-776fbdfad01d)
2024-08-15 03:14:53 +00:00
Zanie Blue 76e324857b
Improve resolver error messages for single-project workspaces (#6095)
Extends https://github.com/astral-sh/uv/pull/6092 to improve resolver
error messages for workspaces that have a single member.

As before, this requires a two-step approach of

1. Traversing the derivation tree and collapsing some members. In this
case, we drop the empty root node in favor of the project.
2. Using special-case formatting for packages. In this case, the
workspace package is referred to with "your project" instead of its
name.
2024-08-15 03:08:56 +00:00
Zanie Blue 2e3e6a01aa
Improve resolver error messages referencing workspace members (#6092)
An extension of #6090 that replaces #6066.

In brief, 

1. Workspace member names are passed to the resolver for no solution
errors
2. There is a new derivation tree pre-processing step that trims
`NoVersion` incompatibilities for workspace members from the derivation
tree. This avoids showing redundant clauses like `Because only
bird==0.1.0 is available and bird==0.1.0 depends on anyio==4.3.0, we can
conclude that all versions of bird depend on anyio==4.3.0.`. As a minor
note, we use a custom incompatibility kind to mark these
incompatibilities at resolution-time instead of afterwards.
3. Root dependencies on workspace members say `your workspace requires
bird` rather than `you require bird`
4. Workspace member package display omits the version, e.g., `bird`
instead of `bird==0.1.0`
5. Instead of reporting a workspace member as unusable we note that its
requirements cannot be solved, e.g., `bird's requirements are
unsatisfiable` instead of `bird cannot be used`.
6. Instead of saying `your requirements are unsatisfiable` we say `your
workspace's requirements are unsatisfiable` when in a workspace, since
we're not in a "provide direct requirements" paradigm.

As an annoying but minor implementation detail, `PackageRange` now
requires access to the `PubGrubReportFormatter` so it can determine if
it is formatting a workspace member or not. We could probably improve
the abstractions in the future.

As a follow-up, we should additional special casing for "single project"
workspaces to avoid mention of the workspace concept in simple projects.
However, it looks like this will require additional tree manipulations
so I'm going to keep it separate.
2024-08-15 02:41:31 +00:00
Charlie Marsh 5c4e111a1b
Add a compatibility test for `[package.metadata]` (#6098) 2024-08-15 00:29:53 +00:00
Charlie Marsh 7b67b5a328
Strip SHA when constructing package source (#6097)
## Summary

Similar to #5805, but applies the normalization earlier so that
`--locked` passes for URLs that contain fragments.
2024-08-14 20:12:32 -04:00
Charlie Marsh e3f345ce09
Validate lockfile (rather than re-resolve) in `uv lock` (#6091)
## Summary

Historically, in order to "resolve from a lockfile", we've taken the
lockfile, used it to pre-populate the in-memory metadata index, then run
a resolution. If the resolution didn't match our existing resolution, we
re-resolved from scratch.

This was an appealing approach because (in theory) it didn't require any
dedicated logic beyond pre-populating the index. However, it's proven to
be _really_ hard to get right, because it's a stricter requirement than
we need. We just need the current lockfile to _satisfy_ the requirements
provided by the user. We don't actually need a second resolution to
produce the exact same result. And it's not uncommon that this second
resolution differs, because we seed it with preferences, which
fundamentally changes its course. We've worked hard to minimize those
"instabilities", but they're still present.

The approach here is intended to be much simpler. Instead of resolving
from the lockfile, we just check if the current resolution satisfies the
state of the workspace. Specifically, we check if the lockfile (1)
contains all the relevant members, and (2) matches the metadata for all
dependencies, recursively. (We skip registry dependencies, assuming that
they're immutable.)

This may actually be too conservative, since we can have resolutions
that satisfy the requirements, even if the requirements have changed
slightly. But we want to bias towards correctness for now.

My hope is that this scheme will be more performant, simpler, and more
robust.

Closes https://github.com/astral-sh/uv/issues/6063.
2024-08-14 20:00:15 -04:00
Zanie Blue 359f39ca0f
Avoid displaying "failed to download" on build failures for local source distributions (#6075)
Especially with workspace members (e.g., [this new test
case](https://github.com/astral-sh/uv/pull/6073/files#diff-273076013b4f5a8139defd5dcd24f5d1eb91c0266dceb4448fdeddceb79f7738R1377-R1379)),
I find it very confusing that we say we failed to download these
distributions.
2024-08-14 17:27:55 -05:00
Zanie Blue dc67023677
Fix loading of cached metadata for git distributions with subdirectories (#6094)
Applies the same fix as https://github.com/astral-sh/uv/issues/5944 to
cache loads

Closes https://github.com/astral-sh/uv/issues/6093
2024-08-14 21:19:30 +00:00
Zanie Blue 981b7ca5ec
Add test cases for unsat dependencies in workspace members (#6073)
Adding some test cases to help inform the work in #6066
2024-08-14 10:50:59 -05:00
github-actions[bot] d6c858b0d3
Update Pythons to include Python 3.12.5 (#6087) 2024-08-14 15:18:01 +00:00
Charlie Marsh 9de3c945f6
Remove `same-graph` merging in resolver (#6077)
## Summary

This was added in https://github.com/astral-sh/uv/pull/5405 but is now
the cause of an instability in `github_wikidata_bot`. Specifically, on
the initial run, we fork in `pydantic==2.8.2`, via:

```
Requires-Dist: typing-extensions>=4.12.2; python_version >= '3.13'
Requires-Dist: typing-extensions>=4.6.1; python_version < '3.13'
```

In the end, we resolve a single version of `typing-extensions`
(`4.12.2`)... But we don't recognize the two resolutions as the "same
graph", because we propagate the fork markers, and so the "edges" have
different markers on them...

In the second run through, when we have the forks in advance, we don't
split on Pydantic... We just try to solve from the root with the current
forks. This is fundamentally different and I fear it will be the cause
of many instabilities. But removing this graph check fixes the proximate
issue.

I don't really understand why this was added since there was no test
coverage in the PR.
2024-08-14 14:06:18 +00:00
Charlie Marsh 4a902a7ca1
Propagate fork markers to extras (#6065)
## Summary

When constructing the `Resolution`, we only propagated the fork markers
to the package node, but not the extras node. This led to cases in which
an extra could be included unconditionally or otherwise diverge from the
base package version.

Closes https://github.com/astral-sh/uv/issues/6062.
2024-08-14 09:55:39 -04:00
Charlie Marsh 8c8f723005
Store `environment-markers` in solve order (#6078)
## Summary

Right now, we store the environment markers in a `BTreeSet` -- so
they're sorted, but the sort doesn't really tell us anything. I think we
should instead store them in the order in which we solved. I thought
this might fix an instability (it didn't), but I think it's still good
to ensure we solve in the same order.

I also changed from `Option<Vec>` to just `Vec`, since there was no
distinction between `None` and empty.
2024-08-14 09:20:12 -04:00
Charlie Marsh 8fac63d4ce
Redact Git credentials from `pyproject.toml` (#6074)
## Summary

We retain them if you use `--raw-sources`, but otherwise they're
removed. We still respect them in the subsequent `uv.lock` via an
in-process store.

Closes #6056.
2024-08-14 01:30:02 +00:00
Charlie Marsh 92263108cc
Redact Git credentials in lockfile (#6070)
## Summary

Closes https://github.com/astral-sh/uv/issues/6055.
2024-08-13 19:48:59 -04:00
Charlie Marsh 1bbb05dca7
Invalidate `uv.lock` if registry sources are removed (#6026)
## Summary

Now, if you resolve against a registry, then swap it out for another, we
won't reuse the lockfile. (If you don't provide any registry
configuration, then we won't enforce this, so that `uv lock --index-url
foo` and `uv lock` is stable.)

Closes https://github.com/astral-sh/uv/issues/5920.
2024-08-13 23:42:04 +00:00
Andrew Gallant 34ac8cb53f uv/tests: add an unresolvable test case involving overlapping markers
This example came up in discussion and it was initially unclear whether
we should try to support it. Specifically, by automatically assuming
that the `datasets < 2.19` dependency had a marker corresponding to the
negation of the conjunction of the other sibling markers for that same
package. But this was deemed, I think, a little too magical.

This in turn implies that whenever there are sibling dependencies with
overlapping marker expressions, their version constraints also need to
be overlapping. Otherwise, for any marker environment that matches both
marker expressions, it would be impossible to select a single version.
2024-08-13 10:14:48 -07:00
Zanie Blue 8d66718077
Bump version to 0.2.36 (#6060) 2024-08-13 12:05:11 -05:00
eth3lbert ef948619ee
Hide python options in `uv tool list` help (#6003)
## Summary

Closes #5982 .

## Test Plan

```
cargo run tool list --help
```

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2024-08-13 11:21:44 -05:00
Andrew Gallant b3e3fd1aeb uv/tests: update ecosystem snapshot for 'transformers' 2024-08-13 08:35:46 -07:00
Andrew Gallant 90bcd9f48c uv/tests: only consider dependency specification for fork matching marker
The test in this case has this comment:

```
/// If a dependency requests a prerelease version with an overlapping marker expression,
/// we should prefer the prerelease version in both forks.
```

With this setup:

```
    let pyproject_toml = context.temp_dir.child("pyproject.toml");
    pyproject_toml.write_str(indoc! {r#"
        [project]
        name = "example"
        version = "0.0.0"
        dependencies = [
            "cffi >= 1.17.0rc1 ; os_name == 'Linux'"
        ]
        requires-python = ">=3.11"
    "#})?;

    let requirements_in = context.temp_dir.child("requirements.in");
    requirements_in.write_str(indoc! {"
        cffi
        .
    "})?;
```

The change in this commit _seems_ more correct that what we had,
although it does seem to contradict the comment. Namely, in the `os_name
!= "Linux"` fork, we don't prefer the pre-release version since the
`cffi >= 1.17.0rc1` bound doesn't apply.

It's not quite clear what to do in this instance.
2024-08-13 08:35:46 -07:00
Andrew Gallant 65be566846 uv/tests: update test that expects to find a resolution
Fixes #4640
2024-08-13 08:35:46 -07:00
Andrew Gallant 4d57e5deb8 uv/tests: "mundane" updates to snapshots
I believe these are all changes that aren't necessarily
expected, but also seem harmless. Like the order in which
fork markers are written to the lock file. (Although one
wonders if we should fix that once and for all by defining
a complete sort function for forks.)
2024-08-13 08:35:46 -07:00
Andrew Gallant 04b7cf894a uv-resolver: rewrite forking to be based on overlapping markers
Closes #4732
2024-08-13 08:35:46 -07:00
Andrew Gallant 8dbf43c85d
uv/tests: add new 'ecosystem' integration tests (#5970)
At a high level, this PR adds a smattering of new tests that
effectively snapshot the output of `uv lock` for a selection of
"ecosystem" projects. That is, real Python projects for which we expect
`uv` to work well with.

The main idea with these tests is to get a better idea of how changes
in `uv` impact the lock files of real world projects. For example,
we're hoping that these tests will help give us data for how #5733
differs from #5887.

This has already revealed some bugs. Namely, re-running `uv lock` for a
second time will produce a different lock file for some projects. So to
prioritize getting the tests added, for those projects, we don't do the
deterministic checking.
2024-08-13 09:48:00 -04:00
Charlie Marsh 9c8a549b3d
Add tests for mixed sources and versions in lock (#6051)
## Summary

Related to https://github.com/astral-sh/uv/issues/3943.
2024-08-12 23:49:36 +00:00
Charlie Marsh 02e4086a30
Add test coverage for transitive and cross-workspace extras (#6050)
## Summary

Related to https://github.com/astral-sh/uv/issues/3943.
2024-08-12 23:36:43 +00:00
Charlie Marsh 4be8301935
Use simplified paths in lockfile (#6049)
## Summary

Closes https://github.com/astral-sh/uv/issues/6048.
2024-08-12 19:34:29 -04:00
Charlie Marsh e71bb0afb8
Add test coverage for mixed editables in `tool.uv.sources` (#6047)
## Summary

Related to https://github.com/astral-sh/uv/issues/3943.
2024-08-12 23:27:11 +00:00
Charlie Marsh 73e32f4eb9
Add test coverage for direct URLs with sources (#6046)
## Summary

Ensures that we don't respect `tool.uv.sources` for (eg.) direct URL
requirements, as intended.

Related to https://github.com/astral-sh/uv/issues/3943.

Closes https://github.com/astral-sh/uv/issues/6048.
2024-08-12 23:14:08 +00:00
Charlie Marsh 0fdadf6ba2
Resolve relative `tool.uv.sources` relative to containing project (#6045)
## Summary

Related to https://github.com/astral-sh/uv/issues/3943.

Closes https://github.com/astral-sh/uv/issues/6044.
2024-08-12 17:14:13 -04:00
Charlie Marsh ae7a8d7f33
Colocate Python install cache with destination directory (#6043)
## Summary

Closes https://github.com/astral-sh/uv/issues/6036.
2024-08-12 16:15:30 -04:00
Charlie Marsh e27a1fce60
Add more tests for uv lock (#6040)
## Summary

Misc. cases we're missing vis-a-vis pip install.
2024-08-12 15:56:01 -04:00
Zanie Blue f6f1bd2f14
Improve top-level help for `uv tool` commands (#5983)
More work needs to be done for all of the options
2024-08-12 17:35:50 +00:00
Ibraheem Ahmed fb5c3bb918
Remove uses of `Option<MarkerTree>` in `ResolutionGraph` (#6035)
## Summary

Missed this one in https://github.com/astral-sh/uv/pull/5978.

Resolves https://github.com/astral-sh/uv/issues/5902.
2024-08-12 10:31:07 -04:00
Charlie Marsh b911a108b9
Filter mixed sources from `--find-links` entries in lockfile (#6025)
## Summary

Our current handling of `--find-links` merges the entries in each index.
As a result, we can end up with `AnnotatedDist` entries that reference
distributions across indexes.

I'd like to change `--find-links` such that each `--find-links` entry is
just treated as its own index (so, e.g., if `requests` exists in the
first `--find-links` entry, we don't even check the registry by
default), which would _also_ fix this problem automatically. But that's
a behavior change... So for now, in the lockfile, we filter
distributions that don't match the source index URL.

There are two cases to consider:

- There's a source distribution. Then, for the ID to reference the
`--find-links` registry, the source distribution _must_ have come from
the `--find-links` entry, so it's fine to discard any wheels from the
"wrong" registry without breaking any compatibility guarantees.
- There's no source distribution. Then the best wheel must come from the
`--find-links` registry. We might lose some platform coverage by
discarding the other wheels, but it shouldn't break any of the
"guarantees", since we have at least one wheel that fits in the version
range.

Closes https://github.com/astral-sh/uv/issues/6015.
2024-08-12 08:54:09 -04:00
Charlie Marsh e941bb6623
Treat local indexes as registry sources in lockfile (#6016)
## Summary

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

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

Adds test coverage for https://github.com/astral-sh/uv/issues/6015.
2024-08-11 22:02:39 -04:00
renovate[bot] 5d4ff4341e
Update Rust crate dunce to v1.0.5 (#6019) 2024-08-12 01:25:55 +00:00
renovate[bot] 8cd624f26e
Update Rust crate assert_cmd to v2.0.16 (#6017) 2024-08-12 01:23:46 +00:00
Alexander Gherm 798cc7bf3c
Make more informative warning message when failed to parse pyproject.toml (#6009)
## Summary

Added the actual error message to the warning when uv fails to parse
`pyproject.toml`.

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

## Test Plan

Took the case from the issue:
- have `pyproject.toml` which contains
```
[tool.uv]
foobar = false
```
- 
```
$ uv venv --preview -v
```
- Expect the message that contains the actual problem in the
`pyproject.toml` like:
```
warning: Failed to parse `pyproject.toml` during settings discovery: unknown field `foobar`; skipping...
```
2024-08-11 21:13:14 +00:00
Charlie Marsh 5c44937742
Misc. edits to script parsing (#5999) 2024-08-10 22:07:05 -04:00
Ahmed Ilyas 2d53e35e39
Support PEP 723 scripts in `uv add` and `uv remove` (#5995)
## Summary

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

## Test Plan

`cargo test`
2024-08-11 01:40:59 +00:00
Charlie Marsh 9b8c07bf18
Avoid replacing executables on no-op upgrades (#5998)
## Summary

Also introduces a "changelog" concept that enables callers to introspect
the modifications that were made to a virtual environment.
2024-08-11 00:34:06 +00:00
Charlie Marsh ec8248ff93
Use upgrade-specific output for tool upgrade (#5997)
## Summary

Closes https://github.com/astral-sh/uv/issues/5949.
2024-08-10 20:24:49 -04:00
Ibraheem Ahmed f5110f7b5e
Remove uses of `Option<MarkerTree>` (#5978)
## Summary

Follow up to https://github.com/astral-sh/uv/pull/5898. This should fix
some of the failures in https://github.com/astral-sh/uv/pull/5887 where
`uv lock --locked` is failing due to `Some(true)` and `None` markers not
comparing equal.
2024-08-10 13:23:29 -04:00
Charlie Marsh 4eced1bd0c
Add better `tool upgrade` tests (#5996)
## Summary

A lot of the existing tests were no-ops. For convenience, we now use the
trick of: install from Test PyPI (to get an outdated "latest"), then
upgrade from PyPI.
2024-08-10 16:56:58 +00:00
Charlie Marsh 2822dde8cb
Add resolver error context to `run` and `tool run` (#5991)
## Summary

Closes https://github.com/astral-sh/uv/issues/5530.
2024-08-10 03:21:56 +00:00
Charlie Marsh f10c28225c
Support `tool.uv` in PEP 723 scripts (#5990)
## Summary

This includes both _settings_ and _sources.

Closes https://github.com/astral-sh/uv/issues/5855.
2024-08-09 23:11:10 -04:00
Charlie Marsh 19ac9af167
Use consistent canonicalization for URLs (#5980)
Right now, the URL gets out-of-sync with the install path, since the
install path is canonicalized. This leads to a subtle error on Windows
(in CI) in which we don't preserve caching across resolution and
installation.
2024-08-09 21:43:36 -04:00
Charlie Marsh cd0171a2ed
Remove `editable: false` support (#5987)
## Summary

This doesn't actually work yet. We'll re-add it in the future.

Closes #5958.
2024-08-09 20:59:23 -04:00
Zanie Blue e097f948c9
Bump version to 0.2.35 (#5984) 2024-08-09 19:21:06 -05:00
Charlie Marsh a3b1a4b8da
Warn when project-specific settings are passed to non-project `uv run` commands (#5977)
## Summary

Closes https://github.com/astral-sh/uv/issues/5856.
2024-08-09 23:10:33 +00:00
konsti fcbee9ce25
Support relative path wheels (#5969)
Surprisingly, this is a lockfile schema change: We can't store relative
paths in urls, so we have to store a `filename` entry instead of the
whole url.

Fixes #4355
2024-08-09 21:57:16 +00:00
Charlie Marsh dd32087842
Remove unnecessary optional from `uv run` (#5976)
## Summary

This is always `Some` now.
2024-08-09 20:13:47 +00:00
Zanie Blue 921050d747
Improve the `uv sync` CLI documentation (#5930) 2024-08-09 14:46:32 -05:00
Zanie Blue d6c587c21c
Improve the `uv python` CLI documentation (#5961) 2024-08-09 14:46:21 -05:00
Zanie Blue e6d76dbf35
Add hint for long help to `uvx` (#5971) 2024-08-09 18:24:38 +00:00
Charlie Marsh f89403f4f6
Retain and respect settings in tool upgrades (#5937)
## Summary

We now persist the `ResolverInstallerOptions` when writing out a tool
receipt. When upgrading, we grab the saved options, and merge with the
command-line arguments and user-level filesystem settings (CLI > receipt
> filesystem).
2024-08-09 18:21:49 +00:00
Zanie Blue 4df0fe9a01
Update the interface for declaring Python download preferences (#5936)
The loose consensus is that "fetch" doesn't have much meaning and that a
boolean flag makes more sense from the command line.

1. Adds `--allow-python-downloads` (hidden, default) and
`--no-python-downloads` to the CLI to quickly enable or disable
downloads
2. Deprecates `--python-fetch` in favor of the options from (1)
3. Removes  `python-fetch` in favor of a `python-downloads` setting
5. Adds a `never` variant to the enum, allowing even explicit installs
to be disabled via the configuration file

## Test plan

I tested this with various `pyproject.toml`-level settings and `uv venv
--preview --python 3.12.2` and `uv python install 3.12.2` with and
without the new CLI flags.
2024-08-09 13:10:19 -05:00
konsti a129cf7d7e
Warn when there are missing bounds on transitive deps in lowest (#5953)
Warn when there are missing bounds on transitive dependencies with
`--resolution lowest`.

Implemented as a lazy resolution graph check. Dev deps are odd because
they are missing the edge from the root that extras have (they are
currently orphans in the resolution graph), but this is more complex to
solve properly because we can put dev dep information in a `Requirement`
so i special cased them here.

Closes #2797
Should help with #1718

---------

Co-authored-by: Ibraheem Ahmed <ibraheem@ibraheem.ca>
2024-08-09 17:55:17 +00:00
Ibraheem Ahmed ffd18cc75d
Implement marker trees using algebraic decision diagrams (#5898)
## Summary

This PR rewrites the `MarkerTree` type to use algebraic decision
diagrams (ADD). This has many benefits:
- The diagram is canonical for a given marker function. It is impossible
to create two functionally equivalent marker trees that don't refer to
the same underlying ADD. This also means that any trivially true or
unsatisfiable markers are represented by the same constants.
- The diagram can handle complex operations (conjunction/disjunction) in
polynomial time, as well as constant-time negation.
- The diagram can be converted to a simplified DNF form for user-facing
output.

The new representation gives us a lot more confidence in our marker
operations and simplification, which is proving to be very important
(see https://github.com/astral-sh/uv/pull/5733 and
https://github.com/astral-sh/uv/pull/5163).

Unfortunately, it is not easy to split this PR into multiple commits
because it is a large rewrite of the `marker` module. I'd suggest
reading through the `marker/algebra.rs`, `marker/simplify.rs`, and
`marker/tree.rs` files for the new implementation, as well as the
updated snapshots to verify how the new simplification rules work in
practice. However, a few other things were changed:
- [We now use release-only comparisons for `python_full_version`, where
we previously only did for
`python_version`](https://github.com/astral-sh/uv/blob/ibraheem/canonical-markers/crates/pep508-rs/src/marker/algebra.rs#L522).
I'm unsure how marker operations should work in the presence of
pre-release versions if we decide that this is incorrect.
- [Meaningless marker expressions are now
ignored](https://github.com/astral-sh/uv/blob/ibraheem/canonical-markers/crates/pep508-rs/src/marker/parse.rs#L502).
This means that a marker such as `'x' == 'x'` will always evaluate to
`true` (as if the expression did not exist), whereas we previously
treated this as always `false`. It's negation however, remains `false`.
- [Unsatisfiable markers are written as `python_version <
'0'`](https://github.com/astral-sh/uv/blob/ibraheem/canonical-markers/crates/pep508-rs/src/marker/tree.rs#L1329).
- The `PubGrubSpecifier` type has been moved to the new `uv-pubgrub`
crate, shared by `pep508-rs` and `uv-resolver`. `pep508-rs` also depends
on the `pubgrub` crate for the `Range` type, we probably want to move
`pubgrub::Range` into a separate crate to break this, but I don't think
that should block this PR (cc @konstin).

There is still some remaining work here that I decided to leave for now
for the sake of unblocking some of the related work on the resolver.
- We still use `Option<MarkerTree>` throughout uv, which is unnecessary
now that `MarkerTree::TRUE` is canonical.
- The `MarkerTree` type is now interned globally and can potentially
implement `Copy`. However, it's unclear if we want to add more
information to marker trees that would make it `!Copy`. For example, we
may wish to attach extra and requires-python environment information to
avoid simplifying after construction.
- We don't currently combine `python_full_version` and `python_version`
markers.
- I also have not spent too much time investigating performance and
there is probably some low-hanging fruit. Many of the test cases I did
run actually saw large performance improvements due to the markers being
simplified internally, reducing the stress on the old `normalize`
routine, especially for the extremely large markers seen in
`transformers` and other projects.

Resolves https://github.com/astral-sh/uv/issues/5660,
https://github.com/astral-sh/uv/issues/5179.
2024-08-09 13:40:02 -04:00
Zanie Blue 3228fc5f35
Improve the `uv venv` CLI documentation (#5963)
This was actually in pretty good shape already!
2024-08-09 12:15:22 -05:00
Ibraheem Ahmed ddb82a01c8
Add basic universal benchmarks to CI (#5938)
## Summary

Resolves https://github.com/astral-sh/uv/issues/4921.
2024-08-09 12:52:28 -04:00
Zanie Blue 7fdb878fd0
Display portable paths in posix venv activation commands (#5956)
Closes #5950
2024-08-09 11:28:00 -05:00
Zanie Blue 4330f9718b
Improve the `uv lock` CLI documentation (#5932) 2024-08-09 08:51:03 -05:00
Charlie Marsh cac1e7bcfc
Add `update` alias for `uv tool upgrade` (#5948)
## Summary

I always get this wrong with `brew`, it'd be nice for it to "just work"
either way.
2024-08-09 09:37:03 -04:00
konsti eed23be1bd
Discard forks when using `--upgrade` (#5905)
Fixes #5817

Needs https://github.com/astral-sh/packse/pull/213 for the test to pass.
2024-08-09 09:13:38 +00:00
konsti 1e6b021506
Update packse to 0.3.34 (#5954)
Preparation for #5905
2024-08-09 09:04:17 +00:00
Chan Kang 441d57fa29
use exclude newer env var instead of the flag (#5946)
## Summary
resolves https://github.com/astral-sh/uv/issues/5879
<!-- What's the purpose of the change? What does it do, and why? -->
2024-08-09 09:53:06 +02:00
Charlie Marsh 21408c1f35
Enforce extension validity at parse time (#5888)
## Summary

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

Closes https://github.com/astral-sh/uv/issues/5858.
2024-08-08 21:39:47 -04:00
Charlie Marsh ba7c09edd0
Respect subdirectories when locating Git workspaces (#5944)
## Summary

We were discovering the workspace from the Git repository root, so
attempting to build any subdirectories would fail.

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

## Test Plan

```
cargo run pip install \
	git+https://github.com/flyteorg/flytekit.git@master#subdirectory=plugins/flytekit-flyteinteractive
```
2024-08-08 20:13:17 -04:00
Charlie Marsh fd1d508108
Make `--upgrade` imply `--refresh` (#5943)
## Summary

I think this seems reasonable... Otherwise, we might not go back to PyPI
to revalidate the list of available versions despite the user passing
`--upgrade`.
2024-08-08 20:11:31 -04:00
Charlie Marsh 3701b60f61
Respect `--upgrade-package` in tool install (#5941)
## Summary

`--upgrade-package` is useful as you can set a constraint. `--upgrade`
will just warn for now.
2024-08-08 19:22:14 -04:00
Charlie Marsh a5ccc3288c
Add conversion to fill default settings (#5933)
## Summary

This paves the way for some future work around the installer receipt. No
behavior changes intended.
2024-08-08 21:05:38 +00:00
Charlie Marsh 88ece8b791
Search beyond workspace root when discovering configuration (#5931)
## Summary

Previously, we wouldn't respect configuration files in directories
_above_ a workspace root. But this is somewhat problematic, because any
`pyproject.toml` will define a workspace root...

Instead, I think we should _start_ the search at the workspace root, but
go above it if necessary.

Closes: #5929.

See: https://github.com/astral-sh/uv/pull/4295.
2024-08-08 17:05:02 -04:00
Ahmed Ilyas cbc3274848
Add `uv tool upgrade` command (#5197)
## Summary

Resolves #5188. Most of the changes involve creating a new function in
`tool/common.rs` to contain the common functionality previously found in
`tool/install.rs`.

## Test Plan

`cargo test`

```console
❯ ./target/debug/uv tool upgrade black
warning: `uv tool upgrade` is experimental and may change without warning.
Resolved 6 packages in 25ms
Uninstalled 1 package in 3ms
Installed 1 package in 19ms
 - black==23.1.0
 + black==24.4.2
Installed 2 executables: black, blackd
```
2024-08-08 16:48:14 -04:00
Zanie Blue bf0497e652
Add CLI flags to reference documentation (#5926)
Oopsies, options are only arguments that take values in Clap-land

Closes https://github.com/astral-sh/uv/issues/5924
2024-08-08 18:51:27 +00:00
Zanie Blue 0d21ff8b5f
Deprecate `--system` and `--no-system` in `uv venv` (#5925)
e.g.

```
❯ cargo run -- venv --no-system
    Blocking waiting for file lock on build directory
   Compiling uv v0.2.34 (/Users/zb/workspace/uv/crates/uv)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 19.85s
     Running `target/debug/uv venv --no-system`
warning: The `--no-system` flag has no effect, a system Python interpreter is always used in `uv venv`
Using Python 3.12.4 interpreter at: /opt/homebrew/opt/python@3.12/bin/python3.12
Creating virtualenv at: .venv
Activate with: source .venv/bin/activate

❯ cargo run -- venv --system
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.15s
     Running `target/debug/uv venv --system`
warning: The `--system` flag has no effect, a system Python interpreter is always used in `uv venv`
Using Python 3.12.4 interpreter at: /opt/homebrew/opt/python@3.12/bin/python3.12
Creating virtualenv at: .venv
Activate with: source .venv/bin/activate
```
2024-08-08 18:32:00 +00:00
Charlie Marsh dd1bcf8ab9
Ignore local configuration in tool commands (#5923)
## Summary

If you're running a user-level command, we shouldn't respect the local
`pyproject.toml` or `uv.toml`.
2024-08-08 14:25:12 -04:00
Zanie Blue f4576fe4a7
Improve the `uv tree` CLI documentation (#5917)
Some small follow-ups.
2024-08-08 18:21:46 +00:00
Zanie Blue d2681320d3
Improve the CLI documentation for `uv remove` (#5916)
Also, renames a `requirements` variable to `packages` for clarity and
fixes the definition of `frozen` for `uv add`.
2024-08-08 13:12:49 -05:00
Charlie Marsh dc3f498f58
Make repeated `uv add` operations simpler (#5922)
## Summary

Closes #5913.
2024-08-08 13:55:07 -04:00
Charlie Marsh 2789830ac2
Fix failing lockfile tests (#5919) 2024-08-08 16:37:05 +00:00
Charlie Marsh 32f09d86b3
Prefetch metadata in `--no-deps` mode (#5918)
## Summary

This _used_ to be true but we now require fetching metadata for all
distributions even with `--no-deps` since, e.g., we validate that any
declared extras exist.
2024-08-08 12:35:15 -04:00
Zanie Blue eb6251e0ed
Improve the CLI documentation for `uv add` (#5914) 2024-08-08 10:52:38 -05:00
Charlie Marsh cb62440aea
Show build and install summaries in `uv run` and `uv tool run` (#5899)
## Summary

Initially, we showed _all_ resolver and installer output in `uv run` and
`uv tool run`, since it was way too much for workhorse commands. Then,
we moved to showing _no_ output by default, which was way too little --
you had no idea why anything was happening, and commands appeared to
hang.

This PR adds a more nuanced middle-ground. With `--verbose`, we continue
to show everything. But by default, in `uv run` and `uv tool run`...

- During resolution, we show any "Building" and "Build" messages, if you
need to build a source distribution. But we don't show any other output.
(This _could_ be too little for expensive resolutions; we may want to
show a spinner.)
- If there are no changes to be made after resolving, we don't show any
other output.
- If we have to install, we show the progress bars for downloads (which
disappear on completion) followed by a single summary line stating the
number of packages installed.

This feels pretty good, in my limited testing. When everything is built
/ cached, you don't get _any_ additional output. When there's work to
do, you have a sense for what's happening, and we leave you with a
single summary line ("Installed X packages") at the end.

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

## Test Plan

Notice that the first `tool run` ends with an install line; the second
shows no additional output:

![Screenshot 2024-08-07 at 8 33
21 PM](https://github.com/user-attachments/assets/6b0c7824-f14f-4d0b-86d0-a334ba486ce4)

If you run `uv run` in a package for the first time, we _do_ tell you
that we're building / built it:

![Screenshot 2024-08-07 at 8 34
02 PM](https://github.com/user-attachments/assets/6a4c7b05-3aa5-410e-af5d-916eb6e745b0)

But on the second run, there's no output:

![Screenshot 2024-08-07 at 8 34
10 PM](https://github.com/user-attachments/assets/2b32f83e-0370-45fa-9e8f-407d9b93d468)

If you add a `--with`, we'll show you all the installer progress bars
(which disappear once they're done), and then a single summary line:

![Screenshot 2024-08-07 at 8 34
39 PM](https://github.com/user-attachments/assets/e975d75c-01d2-4eb6-b3ff-e4d25d5ea9e2)
2024-08-08 11:26:41 -04:00
konsti 4038c9a6af
Rename `distribution` to `packages` in lockfile (#5861)
Currently, the entry for a package+version+source table is called
`distribution`. That is incorrect, the `sdist` and `wheel` fields inside
of that table are distributions, the table itself is for a package. We
also align ourselves closer with PEP 751.

I went through `lock.rs` and renamed all occurrences of "distribution"
that actually referred to a "package".

This change invalidates all existing lockfiles.

Bikeshedding: Do we call it `package` or `packages`? See also
https://github.com/python/peps/pull/3877

`package` is nice because it looks like a header:

```toml
[[package]]
name = "anyio"
version = "4.3.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
    { name = "idna" },
    { name = "sniffio" },
]
sdist = { url = "3970183622d484d08e3285104333d3/anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6", size = 159642 }
wheels = [
    { url = "2f20c40b45242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8", size = 85584 },
]
```

`packages` is nice because the field is not a single entry, but a list.

2/3 for https://github.com/astral-sh/uv/issues/4893

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2024-08-08 11:25:06 -04:00
Zanie Blue 4fd9b115d5
Add missing "git" feature to various tests (#5910) 2024-08-08 09:49:25 -05:00
konsti ae6b59365f
Only textwrap json packse scenarios with packse 0.3.32 (#5810)
Companion change to https://github.com/astral-sh/packse/pull/205 to
correctly format lock scenario doc comments.

Updates packse to 0.3.32.
2024-08-08 15:49:50 +02:00
Charlie Marsh 03797b0724
Respect `--upgrade-package` when resolving from lockfile (#5907)
## Summary

Closes https://github.com/astral-sh/uv/issues/5900.
2024-08-08 13:07:02 +00:00
Charlie Marsh 9f32c41552
Fix reuse of Git commits in lockfile (#5908)
## Summary

See: https://github.com/astral-sh/uv/pull/5886/files#r1709430408
2024-08-08 13:01:59 +00:00
Ahmed Ilyas acbd367ead
Support `no-build-isolation-package` (#5894)
## Summary

Resolves #5831 

## Test Plan

`cargo test`
2024-08-08 01:35:56 +00:00
Charlie Marsh f7110e0a07
Enable mirror for `python-build-standalone` downloads (#5719)
## Summary

This came up again recently, so decided to do it real quick.

Closes https://github.com/astral-sh/uv/issues/5224.
2024-08-07 21:34:19 -04:00
Charlie Marsh 9081509715
Avoid requires-python warning in virtual-only workspace (#5895)
## Summary

There's no way for the user to address this, so we shouldn't show it.
2024-08-07 20:43:19 -04:00
Charlie Marsh 4b2b2d2870
Use cached environments for `--with` layers (#5897)
## Summary

I think this will make the logging changes a little easier by having
more consistency between codepaths.
2024-08-07 23:31:43 +00:00
Charlie Marsh bc1d7764e2
Combine fetch and resolve steps in Git resolver (#5886)
## Summary

Whenever we call `resolve`, we immediately call `fetch` after. And in
some cases `resolve` actually calls `fetch` internally. It seems a lot
simpler to just merge these into one method that returns a `Fetch`
(which itself contains the fully-resolved URL).

Closes https://github.com/astral-sh/uv/issues/5876.
2024-08-07 22:35:05 +00:00
Charlie Marsh c681c5a33c
Bump version to v0.2.34 (#5889) 2024-08-07 16:33:53 -04:00
Zanie Blue 766d0788b0
Fix lock test cases (#5885) 2024-08-07 13:45:16 -05:00
konsti a3569b5b96
Group resolver options in lockfile (#5853)
There are three options that determine resolver behavior:

* resolution mode
* prerelease mode
* exclude newer

They are different from the other top level options: If they mismatch,
we recreate the resolution. To distinguish them from the rest of the
lockfile, we group them under an `[options]` header.

1/3 for #4893
2024-08-07 14:11:59 -04:00
Charlie Marsh 8c6b667eeb
Add `uv add --no-sync` and `uv remove --no-sync` (#5881)
## Summary

Closes https://github.com/astral-sh/uv/issues/5867.
2024-08-07 14:09:10 -04:00
Charlie Marsh 9bb55c4ac0
Add `--locked` coverage to lock tests (#5880)
Closes https://github.com/astral-sh/uv/issues/5875.
2024-08-07 13:39:51 -04:00
Zanie Blue c95bf76dfe
Replace `uv help python` references in CLI documentation with links (#5871)
Following #5869, the documentation has some less-than-helpful
suggestions to use `uv help python` for details — we should link to the
`uv python` section instead.
2024-08-07 12:21:09 -05:00
Zanie Blue fe2849af6a
Improve CLI documentation for `uv tree` (#5870) 2024-08-07 16:59:27 +00:00
Zanie Blue 2df2092084
Improve `--python` CLI documentation (#5869)
Closes #4400
2024-08-07 16:37:10 +00:00
Zanie Blue 32d8ea1698
Improve documentation for `uv init` CLI (#5862) 2024-08-07 11:26:00 -05:00
Charlie Marsh f29bdcb9e3
Fix `add_git_implicit` test (#5872) 2024-08-07 16:23:47 +00:00
Charlie Marsh 9a80dfeed4
Assume `git+` prefix when URLs end in `.git` (#5868)
## Summary

Right now, this applies _everywhere_, so the following also works:

```
pip install "elmer-circuitbuilder @ https://github.com/ElmerCSC/elmer_circuitbuilder.git"
```

I actually think that's ok?

Closes https://github.com/astral-sh/uv/issues/5866.
2024-08-07 15:50:36 +00:00
Charlie Marsh dceba77ff7
Avoid mismatch in `--locked` with Git dependencies (#5865)
## Summary

We were dropping the query and fragment in the wrong place, so the URLs
didn't match up after resolving from an existing lockfile.

Closes https://github.com/astral-sh/uv/issues/5851.
2024-08-07 15:47:48 +00:00
Charlie Marsh e4ec6e4025
Avoid panic when re-locking with precise commit (#5863)
## Summary

Very subtle bug. The scenario is as follows:

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

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

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

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

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

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

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

Closes https://github.com/astral-sh/uv/issues/5860.
2024-08-07 10:56:15 -04:00
Charlie Marsh 3ae75a21aa
Support empty dependencies in PEP 723 scripts (#5864)
## Summary

Closes https://github.com/astral-sh/uv/issues/5859.
2024-08-07 10:56:05 -04:00
Zanie Blue 8998149ac1
Improve CLI documentation for `uv run` (#5841)
Adds more long-form help to `uv run`, which renders in `uv help run` and
the CLI reference on the website.
2024-08-07 13:26:24 +00:00
konsti 54989f1376
Replace unreachable `todo!()` with `unreachable!()` in locking (#5857)
Replace a `todo!()` that was unreachable with an `unreachable!()` and a
proper comment.
2024-08-07 13:22:56 +00:00
samypr100 2cd63f06dc
feat: more rust in trampoline (#5750)
## Summary

This is an experimental PR to replace more unsafe calls with more rust
while still trying to keep the binary size small enough. These changes
roughly increase the size of the trampolines to about 40kb~. This is a
alternate PR to https://github.com/astral-sh/uv/pull/5751.

The primary changes here include
* Switch to use rust path components for ease of path management
* Leverage `std::process::exit` for process exit and cleanup
* Use `std::io::Error::last_os_error` for IO Errors to remove
`FormatMessage` complexity
* Use `std::env::current_exe` to get the current executable instead of
`GetModuleFileNameA`

## Test Plan

Added one more existing test case to trampoline tests.
Still need to verify dunce::canonicalize is desired or not on
find_python_exe.

---------

Co-authored-by: konstin <konstin@mailbox.org>
2024-08-07 08:19:38 +00:00
Charlie Marsh d0b16f9018
Ensure `python`-to-`pythonX.Y` symlink exists in downloaded Pythons (#5849)
## Summary

After installing:

```
❯ readlink "/Users/crmarsh/Library/Application Support/uv/python/cpython-3.12.4-macos-aarch64-none/bin/python"
python3.12

❯ readlink "/Users/crmarsh/Library/Application Support/uv/python/cpython-3.9.5-macos-aarch64-none/bin/python"
python3.9
```

Closes https://github.com/astral-sh/uv/issues/5838.
2024-08-06 23:03:22 -04:00
Charlie Marsh e58c503f65
Reuse existing virtualenvs with `--no-project` (#5846)
## Summary

Closes https://github.com/astral-sh/uv/issues/5840.
2024-08-07 02:52:15 +00:00
Zanie Blue d1614c8f10
Improve CLI documentation for global options (#5834)
Slowly auditing our CLI help text
2024-08-06 20:50:29 -05:00
Charlie Marsh cccb6820db
Avoid reusing incompatible distributions across lock and sync (#5845)
## Summary

We need to avoid using incompatible versions for build dependencies that
are also part of the resolved
environment. This is a very subtle issue, but: when locking, we don't
enforce platform
compatibility. So, if we reuse the resolver state to install, and the
install itself has to
preform a resolution (e.g., for the build dependencies of a source
distribution), that
resolution may choose incompatible versions.

The key property here is that there's a shared package between the build
dependencies and the
project dependencies.

Closes https://github.com/astral-sh/uv/issues/5836.
2024-08-07 00:54:51 +00:00
Charlie Marsh 9b06b3905d
Reject `pyproject.toml` in `--config-file` (#5842)
This already rejects `pyproject.toml`... but because the schema
validation is relaxed (we allow unknown fields, and all fields are
optional), a `pyproject.toml` doesn't get properly rejected here.

This PR makes the schema stricter, but in a safe way (by adding the
other `tool.uv` fields, like `workspace`, as any).

Closes #5832.
2024-08-06 23:40:59 +00:00
Charlie Marsh fae9a70ca0
Add help heading for `--no-sources` (#5833) 2024-08-06 21:29:56 +00:00
Zanie Blue c0c26cc542
Improve display order of top-level commands (#5830)
Closes https://github.com/astral-sh/uv/issues/5702

Since Clap 4, the default order follows the declarations.

Also improves some descriptions.
2024-08-06 16:18:05 -05:00
Charlie Marsh d8d9b02512
Add `--no-build-isolation` to uv lock et al (#5829)
## Summary

Closes https://github.com/astral-sh/uv/issues/5742.
2024-08-06 21:11:48 +00:00
Charlie Marsh 9346946c7f
Allow downloading wheels for metadata with `--no-binary` (#5707)
## Summary

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

Closes https://github.com/astral-sh/uv/issues/5699.
2024-08-06 18:14:12 +00:00
Charlie Marsh 3b75d8b6d6
Support uv add `--dev` in virtual workspaces (#5821)
## Summary

Closes https://github.com/astral-sh/uv/issues/5814.
2024-08-06 14:06:03 -04:00
Ibraheem Ahmed e651e67f29
Support overlapping local and non-local requirements in forks (#5812)
## Summary

This fixes a bug introduced by
https://github.com/astral-sh/uv/pull/5232. It turns out that the
`universal_disjoint_base_or_local_requirement` test does not actually do
what it was meant to because of the incorrect python requirement. With a
valid python requirement, it fails on `main`. The problem is that we try
to exclude the original base version from the range of allowed versions
to try and prefer local versions. However, in the test, there is a
branch that depends on the non-local version, with no applicable local
in its fork. We should remove this exclusion as prioritization is
handled by the candidate resolver.
2024-08-06 12:04:35 -04:00
Charlie Marsh 089f50a845
Add `--no-sources` to avoid reading from `tool.uv.sources` (#5801)
## Summary

Closes https://github.com/astral-sh/uv/issues/5791.
2024-08-06 14:14:19 +00:00
Charlie Marsh 478d32c655
Strip URL fragments from lockfile (#5805)
## Summary

I noticed that we write entries like:

```
sdist = { url = "https://pkgs.dev.azure.com/astral-sh/_packaging/db3d73a9-2c37-40f9-8680-515ec6e132c4/pypi/download/iniconfig/2/iniconfig-2.0.0.tar.gz#sha256=2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3" }
```

(For registries that include hashes in the URLs, that is.)

This PR drops those unnecessary components from the lockfile (notice
that the hash is repeated).
2024-08-06 10:00:38 -04:00
Charlie Marsh c59c8e080a
Use `UrlString` for `Source` struct (#5804)
I don't think this will save any time in serialization, but it should
save us some deserialization, since we only need to parse URLs for the
packages we use...
2024-08-06 12:58:09 +00:00
Delgan 3a24aecb2c
Fix invalid TOML syntax in examples of "config-settings" docs (#5809)
## Summary

The snippet generated TOML errors when I copy/pasted it in my config
file, I believe there was a typo. 👍

## Test Plan

N/A
2024-08-06 08:17:54 +00:00
Charlie Marsh 552c75cf49
Redact registry credentials in lockfile (#5803)
## Summary

Okay, I tested this against...

- Our public "private" proxy
- Fury
- AWS CodeArtifact
- Azure Artifacts

It took a long time.

All of them work as expected with this approach: we omit the credentials
from the lockfile, then wire them back up when the index URL is provided
during subsequent operations.

Closes https://github.com/astral-sh/uv/issues/5119.
2024-08-05 22:54:18 -04:00
Zanie Blue dd20afdd43
Create help sections for build, install, resolve, and index (#5693)
Part of #4454 

e.g.

```
$ uv add --help
Add one or more packages to the project requirements

Usage: uv add [OPTIONS] <REQUIREMENTS>...

Arguments:
  <REQUIREMENTS>...  The packages to add, as PEP 508 requirements (e.g., `ruff==0.5.0`)

Options:
      --dev                  Add the requirements as development dependencies
      --optional <OPTIONAL>  Add the requirements to the specified optional dependency group
      --no-editable          Don't add the requirements as editables
      --raw-sources          Add source requirements to `project.dependencies`, rather than `tool.uv.sources`
      --rev <REV>            Specific commit to use when adding from Git
      --tag <TAG>            Tag to use when adding from git
      --branch <BRANCH>      Branch to use when adding from git
      --extra <EXTRA>        Extras to activate for the dependency; may be provided more than once
      --locked               Assert that the `uv.lock` will remain unchanged
      --frozen               Add the requirements without updating the `uv.lock` file
      --package <PACKAGE>    Add the dependency to a specific package in the workspace
  -p, --python <PYTHON>      The Python interpreter into which packages should be installed. [env: UV_PYTHON=]

Index options:
  -i, --index-url <INDEX_URL>                The URL of the Python package index (by default: <https://pypi.org/simple>) [env: UV_INDEX_URL=]
      --extra-index-url <EXTRA_INDEX_URL>    Extra URLs of package indexes to use, in addition to `--index-url` [env: UV_EXTRA_INDEX_URL=]
  -f, --find-links <FIND_LINKS>              Locations to search for candidate distributions, in addition to those found in the registry indexes
      --no-index                             Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those provided via `--find-links`
      --index-strategy <INDEX_STRATEGY>      The strategy to use when resolving against multiple index URLs [env: UV_INDEX_STRATEGY=] [possible values: first-index, unsafe-first-match, unsafe-best-match]
      --keyring-provider <KEYRING_PROVIDER>  Attempt to use `keyring` for authentication for index URLs [env: UV_KEYRING_PROVIDER=] [possible values: disabled, subprocess]

Resolver options:
  -U, --upgrade                            Allow package upgrades, ignoring pinned versions in any existing output file
  -P, --upgrade-package <UPGRADE_PACKAGE>  Allow upgrades for a specific package, ignoring pinned versions in any existing output file
      --resolution <RESOLUTION>            The strategy to use when selecting between the different compatible versions for a given package requirement [env: UV_RESOLUTION=] [possible values: highest, lowest, lowest-direct]
      --prerelease <PRERELEASE>            The strategy to use when considering pre-release versions [env: UV_PRERELEASE=] [possible values: disallow, allow, if-necessary, explicit, if-necessary-or-explicit]
      --exclude-newer <EXCLUDE_NEWER>      Limit candidate packages to those that were uploaded prior to the given date [env: UV_EXCLUDE_NEWER=]

Installer options:
      --reinstall                              Reinstall all packages, regardless of whether they're already installed. Implies `--refresh`
      --reinstall-package <REINSTALL_PACKAGE>  Reinstall a specific package, regardless of whether it's already installed. Implies `--refresh-package`
      --link-mode <LINK_MODE>                  The method to use when installing packages from the global cache [env: UV_LINK_MODE=] [possible values: clone, copy, hardlink, symlink]
      --compile-bytecode                       Compile Python files to bytecode after installation

Build options:
  -C, --config-setting <CONFIG_SETTING>        Settings to pass to the PEP 517 build backend, specified as `KEY=VALUE` pairs
      --no-build                               Don't build source distributions
      --no-build-package <NO_BUILD_PACKAGE>    Don't build source distributions for a specific package
      --no-binary                              Don't install pre-built wheels
      --no-binary-package <NO_BINARY_PACKAGE>  Don't install pre-built wheels for a specific package

Cache options:
  -n, --no-cache                           Avoid reading from or writing to the cache, instead using a temporary directory for the duration of the operation [env: UV_NO_CACHE=]
      --cache-dir <CACHE_DIR>              Path to the cache directory [env: UV_CACHE_DIR=]
      --refresh                            Refresh all cached data
      --refresh-package <REFRESH_PACKAGE>  Refresh cached data for a specific package

Python options:
      --python-preference <PYTHON_PREFERENCE>  Whether to prefer using Python installations that are already present on the system, or those that are downloaded and installed by uv [possible values: only-managed, managed, system, only-system]
      --python-fetch <PYTHON_FETCH>            Whether to automatically download Python when required [possible values: automatic, manual]

Global options:
  -q, --quiet                      Do not print any output
  -v, --verbose...                 Use verbose output
      --color <COLOR_CHOICE>       Control colors in output [default: auto] [possible values: auto, always, never]
      --native-tls                 Whether to load TLS certificates from the platform's native certificate store [env: UV_NATIVE_TLS=]
      --offline                    Disable network access, relying only on locally cached data and locally available files
      --no-progress                Hides all progress outputs when set
      --config-file <CONFIG_FILE>  The path to a `uv.toml` file to use for configuration [env: UV_CONFIG_FILE=]
      --no-config                  Avoid discovering configuration files (`pyproject.toml`, `uv.toml`) in the current directory, parent directories, or user configuration directories [env: UV_NO_CONFIG=]
  -h, --help                       Print help
  -V, --version                    Print version

Use `uv help add` for more details.
```
2024-08-05 21:28:35 +00:00
Charlie Marsh 82c3b12b27
Avoid using already-installed tools on `--upgrade` or `--reinstall` (#5799)
## Summary

See: https://github.com/astral-sh/uv/issues/5797. This isn't great but
is _probably_ more intuitive than using the existing tool.
2024-08-05 20:48:36 +00:00
Charlie Marsh 801797e7bf
Don't show deprecated warning in `uvx --isolated` (#5798)
## Summary

An oversight.
2024-08-05 16:32:22 -04:00
Charlie Marsh 33ec6f063d
Remove interpreter from `BuildContext` trait (#5800) 2024-08-05 16:32:10 -04:00
Charlie Marsh 92a2996e8e
Show extras and dev dependencies in `uv tree` (#5768)
## Summary

Closes https://github.com/astral-sh/uv/issues/5759.
2024-08-05 19:15:02 +00:00
Charlie Marsh 6b45baf7be
Support `--python-platform` in `uv tree` (#5764)
## Summary

This allows you to set (e.g.) `--python-platform windows` to view the
resolved dependencies on Windows.

Closes https://github.com/astral-sh/uv/issues/5760.
2024-08-05 19:02:35 +00:00
Charlie Marsh 3156fccc85
Filter `uv tree` to current platform by default (#5763)
## Summary

`uv tree` will now filter to the current platform by default. You can
pass `--universal` to show the entire tree.

Closes https://github.com/astral-sh/uv/issues/5760.
2024-08-05 18:51:18 +00:00
Charlie Marsh 823c17723b
Remove top-level bar from Python installs (#5788) 2024-08-05 02:37:39 +00:00
Charlie Marsh bb6ac67df3
Use cache for Python install temporary directories (#5787)
## Summary

It's fine for this to be in the cache, I think, since we don't
necessarily need to colocate it with the Python directory.

Closes https://github.com/astral-sh/uv/issues/5747.
2024-08-05 02:32:24 +00:00
renovate[bot] 77141464fe
Update Rust crate which to v6.0.2 (#5779) 2024-08-05 01:08:55 +00:00
Charlie Marsh 0b259c8cea
Remove lock from `TreeDisplay` (#5770) 2024-08-05 00:34:58 +00:00
Charlie Marsh 7567039b80
Avoid lingering dev and optional dependencies in `uv tree` (#5766)
## Summary

Dev and optional dependencies were appearing at the top-level.
2024-08-04 20:37:01 +00:00
Charlie Marsh a9a535da14
Use lockfile directly in `uv tree` (#5761)
## Summary

Ensures that we properly handle (1) duplicated packages and (2) packages
that aren't relevant to the current platform.

Closes https://github.com/astral-sh/uv/issues/5716.
Closes https://github.com/astral-sh/uv/issues/5253.
2024-08-04 14:33:13 -04:00
Charlie Marsh c5052bc36c
Respect malformed `.dist-info` directories in tool installs (#5756)
## Summary

Closes https://github.com/astral-sh/uv/issues/5749.
2024-08-03 19:43:03 -04:00
FishAlchemist 26b3bfbedb
Fix the default value of python-preference in docs/reference/settings.md (#5755)
## Summary
After referring to https://github.com/astral-sh/uv/pull/5637 and doing
additional testing.
The default value in a stable state seems more reasonable to be
``only-system``. ``managed`` in preview.
```
cpython-3.11.9-windows-x86_64-none     C:\Users\name\AppData\Local\Programs\Python\Python311\python.exe

cpython-3.10.14-windows-x86_64-none    C:\Users\name\AppData\Roaming\uv\data\python\cpython-3.10.14-windows-x86_64-none\install\python.exe
cpython-3.10.11-windows-x86_64-none    C:\Users\name\AppData\Local\Programs\Python\Python310\python.exe

cpython-3.9.19-windows-x86_64-none     C:\Users\name\AppData\Roaming\uv\data\python\cpython-3.9.19-windows-x86_64-none\python.exe
```
test on uv 0.2.33 (build from
257007ccaf)
### Stable version
``uv venv -p 3.10`` is ``3.10.11`` (System Python)
``uv venv -p 3.9`` is ``No interpreter found``(3.9.19 for managed
Python)
``uv venv -p 3.9 --python-preference only-system`` is ``No interpreter
found``(fail)
``uv venv -p 3.9 --python-preference only-managed`` is
``3.9.19``(success)
Do not use managed Python, only use the system Python, so it can be
determined as ``only-system``.
### Preview mode
**Note:**  ``3.10.14`` is managed python, ``3.10.11`` is system python.
``uv venv -p 3.11 --preview`` is ``3.11.9`` (System Python)
``uv venv -p 3.10 --preview`` is ``3.10.14``
``uv venv -p 3.10 --preview --python-preference only-managed`` is
``3.10.14``
``uv venv -p 3.10 --preview --python-preference managed`` is ``3.10.14``
``uv venv -p 3.10 --preview --python-preference system`` is ``3.10.11``
``venv -p 3.10 --preview --python-preference only-system`` is
``3.10.11``
Prioritize the managed Python and then select the system Python, so it
can be determined as ``managed``.

-----
fixed #5754 
## Test Plan
Run website in local.

![image](https://github.com/user-attachments/assets/02b81d44-1a99-4165-aca5-6ce46345b539)
2024-08-03 23:37:40 +00:00
Charlie Marsh 22dbb1741b
Avoid monomorphization of `untar` (#5743)
## Summary

This reduces the LLVM lines of the entire project by about 15%.

Before:

```
  Lines                  Copies               Function name
  -----                  ------               -------------
  1742332                42054                (TOTAL)
    22384 (1.3%,  1.3%)     16 (0.0%,  0.0%)  tokio_tar::entry::EntryFields<R>::unpack::{{closure}}
    19113 (1.1%,  2.4%)     69 (0.2%,  0.2%)  alloc::raw_vec::RawVec<T,A>::grow_amortized
    18352 (1.1%,  3.4%)     80 (0.2%,  0.4%)  tokio_tar::entry::EntryFields<R>::unpack::{{closure}}::{{closure}}
    16871 (1.0%,  4.4%)    613 (1.5%,  1.9%)  core::result::Result<T,E>::map_err
    14747 (0.8%,  5.2%)    594 (1.4%,  3.3%)  <core::result::Result<T,E> as core::ops::try_trait::Try>::branch
    12576 (0.7%,  6.0%)     16 (0.0%,  3.3%)  <tokio_tar::archive::Entries<R> as futures_core::stream::Stream>::poll_next
    12314 (0.7%,  6.7%)    226 (0.5%,  3.8%)  <alloc::boxed::Box<T,A> as core::ops::drop::Drop>::drop
    11895 (0.7%,  7.4%)    296 (0.7%,  4.5%)  std::panicking::try
    11718 (0.7%,  8.0%)     63 (0.1%,  4.7%)  alloc::raw_vec::RawVec<T,A>::try_allocate_in
    11152 (0.6%,  8.7%)     16 (0.0%,  4.7%)  uv_extract::stream::untar_in::{{closure}}
    10977 (0.6%,  9.3%)      1 (0.0%,  4.7%)  uv::run::{{closure}}::{{closure}}
    10859 (0.6%,  9.9%)     77 (0.2%,  4.9%)  <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter
    10508 (0.6%, 10.5%)     18 (0.0%,  5.0%)  <core::iter::adapters::flatten::FlattenCompat<I,U> as core::iter::traits::iterator::Iterator>::size_hint
    10260 (0.6%, 11.1%)    138 (0.3%,  5.3%)  core::iter::traits::iterator::Iterator::try_fold
    10196 (0.6%, 11.7%)      8 (0.0%,  5.3%)  uv_extract::stream::unzip::{{closure}}
    10178 (0.6%, 12.3%)      7 (0.0%,  5.3%)  uv_client::cached_client::CachedClient::get_cacheable::{{closure}}::{{closure}}
     9698 (0.6%, 12.8%)    293 (0.7%,  6.0%)  tokio::loom::std::unsafe_cell::UnsafeCell<T>::with_mut
```

After:

```
  Lines                  Copies               Function name
  -----                  ------               -------------
  1496463                37891                (TOTAL)
    14958 (1.0%,  1.0%)     54 (0.1%,  0.1%)  alloc::raw_vec::RawVec<T,A>::grow_amortized
    13997 (0.9%,  1.9%)    564 (1.5%,  1.6%)  <core::result::Result<T,E> as core::ops::try_trait::Try>::branch
    12776 (0.9%,  2.8%)    463 (1.2%,  2.9%)  core::result::Result<T,E>::map_err
    12381 (0.8%,  3.6%)    227 (0.6%,  3.5%)  <alloc::boxed::Box<T,A> as core::ops::drop::Drop>::drop
    11895 (0.8%,  4.4%)    296 (0.8%,  4.2%)  std::panicking::try
    10977 (0.7%,  5.1%)      1 (0.0%,  4.2%)  uv::run::{{closure}}::{{closure}}
    10859 (0.7%,  5.9%)     77 (0.2%,  4.4%)  <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter
    10508 (0.7%,  6.6%)     18 (0.0%,  4.5%)  <core::iter::adapters::flatten::FlattenCompat<I,U> as core::iter::traits::iterator::Iterator>::size_hint
    10196 (0.7%,  7.3%)      8 (0.0%,  4.5%)  uv_extract::stream::unzip::{{closure}}
    10178 (0.7%,  7.9%)      7 (0.0%,  4.5%)  uv_client::cached_client::CachedClient::get_cacheable::{{closure}}::{{closure}}
     9698 (0.6%,  8.6%)    293 (0.8%,  5.3%)  tokio::loom::std::unsafe_cell::UnsafeCell<T>::with_mut
     9078 (0.6%,  9.2%)      9 (0.0%,  5.3%)  core::slice::sort::partition_in_blocks
     8928 (0.6%,  9.8%)     48 (0.1%,  5.4%)  alloc::raw_vec::RawVec<T,A>::try_allocate_in
     8288 (0.6%, 10.3%)    296 (0.8%,  6.2%)  std::panicking::try::do_catch
     8190 (0.5%, 10.9%)    108 (0.3%,  6.5%)  core::iter::traits::iterator::Iterator::try_fold
     7540 (0.5%, 11.4%)    466 (1.2%,  7.7%)  core::ops::function::FnOnce::call_once
     6612 (0.4%, 11.8%)    296 (0.8%,  8.5%)  std::panicking::try::do_call
     6513 (0.4%, 12.3%)     56 (0.1%,  8.7%)  tokio::runtime::task::core::Cell<T,S>::new
     6438 (0.4%, 12.7%)    269 (0.7%,  9.4%)  alloc::boxed::Box<T>::new
     6360 (0.4%, 13.1%)     20 (0.1%,  9.4%)  <toml_edit:🇩🇪:value::ValueDeserializer as serde:🇩🇪:Deserializer>::deserialize_any
```
2024-08-03 23:29:17 +00:00
Charlie Marsh 257007ccaf
Omit local segments when adding uv add bounds (#5753)
## Summary

Closes https://github.com/astral-sh/uv/issues/5752.
2024-08-03 17:35:53 +00:00
Charlie Marsh 35b982446d
Respect pre-release preferences from input files (#5736)
## Summary

Right now, if you have a `requirements.txt` with a pre-release, but the
`requirements.in` does not have a pre-release marker for that dependency
we drop the pre-release. (In the selector, we end up returning
`AllowPrerelease::IfNecessary`, the default.)

I played with a few ways of solving this... The first was to remove that
guard altogether. But if we do that,
`universal_transitive_disjoint_prerelease_requirement` fails (we use
`1.17.0rc1` in both forks, when it should only apply to one of the two).

The second was to do that, but also avoid pushing pre-releases as
preferences when we solve a fork. But then
`universal_disjoint_prereleases` fails, because we return a different
pre-release in each fork.

Finally, I settled on allowing existing pre-releases in forks if they
have no markers on them, i.e., they are "global" preferences. I believe
this is true IFF the preference came from an existing lockfile.

Closes https://github.com/astral-sh/uv/issues/5729.
2024-08-02 22:01:58 -04:00
Charlie Marsh 030d477653
Respect `.python-version` in `--isolated` runs (#5741)
Closes https://github.com/astral-sh/uv/issues/5740.
2024-08-02 23:34:25 +00:00
Charlie Marsh b26794bf6f
Remove double-proxy nodes in error reporting (#5738)
## Summary

If _both_ nodes in the derivation tree are proxies, we need to remove
the _entire_ node. So, the function now returns an `Option<Tree>`
instead of taking `&mut Tree`.

Closes https://github.com/astral-sh/uv/issues/5618.
2024-08-02 21:27:07 +00:00
Charlie Marsh 097aa929b7
Skip files when detecting workspace members (#5735)
## Summary

Closes https://github.com/astral-sh/uv/issues/5724.
Closes https://github.com/astral-sh/uv/issues/5725.
2024-08-02 19:44:43 +00:00
konsti db371560bc
Use prettier to format the documentation (#5708)
To enforce the 100 character line limit in markdown files introduced in
https://github.com/astral-sh/uv/pull/5635, and to automate the
formatting of markdown files, i've added prettier and formatted our
markdown files with it.

I've excluded the changelog and the generated references documentation
from this for having too many changes, but we can also include them.

I'm not particular on which style we use. My main motivations are
(major) not having to reflow markdown files myself anymore and (minor)
consistence between all markdown files. I've chosen prettier for similar
reason as we chose black, it's a single good style that's automated and
shared in the community. I do prefer prettier's style of not breaking
inside of a link name though.

This PR is in two parts, the first adds prettier to CI and documents
using it, while the second actually formats the docs. When merge
conflicts arise, we can drop the last commit and regenerate it with `npx
prettier --prose-wrap always --write BENCHMARKS.md CONTRIBUTING.md
README.md STYLE.md docs/*.md docs/concepts/**/*.md docs/guides/**/*.md
docs/pip/**/*.md`.

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2024-08-02 08:58:31 -05:00
eth3lbert f2c4b9c752
Show default and possible options in CLI reference documentation (#5720)
## Summary

Closes #5692 .
2024-08-02 12:55:50 +00:00
Ahmed Ilyas a6416aa450
Fix CLI reference URLs to subcommands (#5722)
## Summary

Currently all of these links end up 404-ed. I've added a `#` to fix the
URLs.

<img width="653" alt="Screenshot 2024-08-02 at 12 34 22"
src="https://github.com/user-attachments/assets/9b66adcc-431c-441a-8f4f-1b579472fdce">

## Test Plan

Checked manually.
2024-08-02 07:35:33 -05:00
Ahmed Ilyas ff9f3dede1
Support build constraints (#5639)
## Summary

Partially resolves #5561. Haven't added overrides support yet but I can
add it tomorrow if the current approach for constraints is ok.

## Test Plan

`cargo test`

Manually checked trace logs after changing the constraints.
2024-08-02 02:15:58 +00:00
Zanie Blue b14945a7b1
Bump version to 0.2.33 (#5712) 2024-08-01 21:39:17 +00:00
Charlie Marsh 7efed62798
Add a dedicated error for members with mismatched Python requirements (#5695)
## Summary

Gives you a nice error message if you attempt to sync with, e.g., `-p
3.8` when that version is supported by at least one workspace member,
but your project's minimum requirement is `>=3.12`

Closes https://github.com/astral-sh/uv/issues/5662.
2024-08-01 21:37:13 +00:00
Charlie Marsh 69b8b16c75
Support dev dependencies in virtual workspace roots (#5709)
## Summary

Closes https://github.com/astral-sh/uv/issues/5650.
2024-08-01 21:04:30 +00:00
Charlie Marsh 499c368f1e
Use "pre-release" in prose and `Prerelease` in code (#5697)
## Summary

Closes https://github.com/astral-sh/uv/issues/5630.
2024-08-01 20:56:29 +00:00
Zanie Blue 6797caccdb
Update top-level command descriptions (#5706)
Addresses feedback in https://github.com/astral-sh/uv/pull/5700
2024-08-01 20:29:26 +00:00
Charlie Marsh 3a8ee0be57
Limit sync after `uv add` (#5705)
## Summary

I think it's reasonable to only sync the affected group, e.g., `uv add`
on its own should not require syncing all extras.

Closes https://github.com/astral-sh/uv/issues/4418.
2024-08-01 15:22:38 -05:00
Zanie Blue 34f657c964
Unhide the experimental top-level commands (#5700) 2024-08-01 14:06:07 -05:00
Zanie Blue 3c7526b855
Add CLI reference to `generate-all` (#5701) 2024-08-01 18:32:29 +00:00
Charlie Marsh ad384ecacf
Set lower bounds in `uv add` (#5688)
## Summary

Closes https://github.com/astral-sh/uv/issues/5178.
2024-08-01 13:06:57 -04:00
Zanie Blue 159108b728
Move `--python` and `--python-version` into the "Python options" help (#5691)
Part of #4454 

e.g. for `uv help pip compile`

```
Python options:
      --python <PYTHON>
          The Python interpreter against which to compile the requirements.
          
          By default, uv uses the virtual environment in the current working directory or any parent
          directory, falling back to searching for a Python executable in `PATH`. The `--python`
          option allows you to specify a different interpreter.
          
          Supported formats:
          - `3.10` looks for an installed Python 3.10 using `py --list-paths` on Windows, or
            `python3.10` on Linux and macOS.
          - `python3.10` or `python.exe` looks for a binary with the given name in `PATH`.
          - `/home/ferris/.local/bin/python3.10` uses the exact Python at the given path.

  -p, --python-version <PYTHON_VERSION>
          The minimum Python version that should be supported by the resolved requirements (e.g., `3.8` or `3.8.17`).
          
          If a patch version is omitted, the minimum patch version is assumed. For example, `3.8` is mapped to `3.8.0`.

      --python-preference <PYTHON_PREFERENCE>
          Whether to prefer using Python installations that are already present on the system, or those that are downloaded and installed by uv

          Possible values:
          - only-managed: Only use managed Python installations; never use system Python installations
          - managed:      Prefer managed Python installations over system Python installations
          - system:       Prefer system Python installations over managed Python installations
          - only-system:  Only use system Python installations; never use managed Python installations

      --python-fetch <PYTHON_FETCH>
          Whether to automatically download Python when required

          Possible values:
          - automatic: Automatically fetch managed Python installations when needed
          - manual:    Do not automatically fetch managed Python installations; require explicit installation
 ```
2024-08-01 11:55:11 -05:00
Charlie Marsh ff2e1fcec0
Support legacy tool receipts with PEP 508 requirements (#5679)
## Summary

In #5494, I made breaking changes to the tool receipt format. This would
break existing tools for all users. This PR makes the change
backwards-compatible by supporting deserialization for the deprecated
format.

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

## Test Plan

Beyond the automated tests, you can run `cargo run tool list` on your
existing machine.

Before:

```
warning: `uv tool list` is experimental and may change without warning
warning: Ignoring malformed tool `black` (run `uv tool uninstall black` to remove)
warning: Ignoring malformed tool `poetry` (run `uv tool uninstall poetry` to remove)
warning: Ignoring malformed tool `ruff` (run `uv tool uninstall ruff` to remove)
```

After:

```
warning: `uv tool list` is experimental and may change without warning
black v0.1.0
- black
poetry v1.8.3
- poetry
ruff v0.0.60
- ruff
```
2024-08-01 12:43:29 -04:00
Charlie Marsh b9b41d4a38
Include newly-added optional dependencies in lockfile (#5686)
## Summary

When we add a new optional group in `uv add`, we never to update the
`pyproject.toml` before locking. Otherwise, we use the stale
`pyproject.toml` and omit the optional group.

Closes https://github.com/astral-sh/uv/issues/5687.
2024-08-01 12:41:37 -04:00
Zanie Blue 0f30c69624
Move settings reference to reference section (#5689)
Joining #5685 in a dedicated reference section
2024-08-01 16:20:30 +00:00
Zanie Blue f107406727
Generate CLI reference for documentation (#5685)
Loosely based on [Cargo's
format](https://github.com/rust-lang/cargo/blob/master/src/doc/src/commands/cargo-build.md)

<img width="896" alt="Screenshot 2024-08-01 at 9 44 03 AM"
src="https://github.com/user-attachments/assets/7c016bb3-2b54-46af-8ea8-ce82e07a0e30">

Future work includes:

- Grouping options
- Enforcing some sort of specific command ordering
- Showing possible values for enums
- Adding "long_about" to commands for more context
2024-08-01 16:04:16 +00:00
eth3lbert 9788496c51
Grouping `GlobalArgs` to dedicated heading (#5665)
## Summary

Part of #4454 .

## Test Plan

test cases included.

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2024-08-01 10:01:22 -05:00
Charlie Marsh b9866b3ee8
Avoid unwrap when serializing receipts (#5678) 2024-07-31 22:57:16 -04:00
Ahmed Ilyas 5bded73c48
`uvx` warn when no executables are available (#5675)
## Summary

Resolves #5623 

## Test Plan

`cargo test`
2024-07-31 17:27:41 -05:00
Charlie Marsh ff2b810fdf
Fix non-registry serialization for receipts (#5668)
## Summary

Fixes a bug in #5494. The `RequirementSourceWire` representation was
ambiguous, and so the order of the fields meant that all variants were
mapped to `Registry` when deserializing. (So the snapshots were right,
but behaviors were wrong.)
2024-07-31 21:09:54 +00:00
Charlie Marsh 2b9a4f673e
Initialize the cache in `uv init` (#5669)
## Summary

We now query the Python interpreter here, which means we need cache
access.
2024-07-31 19:46:12 +00:00
Charlie Marsh f8e2d2f54d
Remove lingering executables after failed installs (#5666)
## Summary

This could still be made more robust, but it's not critical, since you
can always `--force`. It's good to handle this case, though, since we
have an explicit error for it.

Closes https://github.com/astral-sh/uv/issues/5490.
2024-07-31 15:27:24 -04:00
Charlie Marsh 4b8a127c54
Avoid persisting `uv add` calls that result in resolver errors (#5664)
## Summary

Closes https://github.com/astral-sh/uv/issues/5622.
2024-07-31 13:27:34 -04:00
eth3lbert 54398fa7bc
Show help specific options in `uv help` (#5516)
## Summary

Resolves #5221 

## Test Plan

Test case included.
2024-07-31 12:10:57 -05:00
Pavel Dikov d05f2b258b
fix(venv): make relocatable activation scripts support ksh (#5640)
It transpires that detecting the directory a script was sourced from is
non-trivial across `bash`, `ksh` and `zsh`.

The previous version was a one-liner and supported `bash` and `zsh` but
not `ksh`.

It is possible to keep the one-liner and add `ksh` support, but that is
mutually-exclusive with `zsh`.

Therefore, the only way to square this circle is to add an `if` block. A
silver lining here is that although longer, the script is probably
easier to follow as there is less code-golfing going on.
2024-07-31 12:18:11 -04:00
Charlie Marsh f266fb711c
Use full requirement when serializing receipt (#5494)
## Summary

The current receipt doesn't capture quite enough information. For
example, it doesn't differentiate between editable and non-editable
requirements. This PR instead uses the full `Requirement` type. I think
we should use a custom representation like we do in the lockfile, but
I'm just using the default representation to demonstrate the idea.
2024-07-31 16:16:39 +00:00
Charlie Marsh bf8934e3e4
Use intersection rather than union for `requires-python` (#5644)
## Summary

As-is, if you have a workspace with mixed `requires-python`
requirements, resolution will _never_ succeed, since we'll use the union
as the `requires-python` bound (i.e., take the lowest value), and fail
when we see the package that only supports some more narrow range.

This PR modifies the behavior to take the intersection (i.e., the
highest value), so if you have one package that supports Python 3.12 and
later, and another that supports Python 3.8 and later, we lock for
Python 3.12. If you try to sync or run with Python 3.8, we raise an
error, since the lockfile will be incompatible with that request.

Konsti has a write-up in https://github.com/astral-sh/uv/issues/5594
that outlines what could be a longer-term strategy.

Closes https://github.com/astral-sh/uv/issues/5578.
2024-07-31 16:08:53 +00:00
Charlie Marsh dfec262586
Capture portable path serialization in a struct (#5652)
## Summary

I need to reuse this in #5494, so want to abstract it out and make it
reusable.
2024-07-31 16:00:37 +00:00
konsti 2247b0f540
Check idempotence in packse lock scenarios (#5485)
Add tests for the instabilities fix.

Part of
https://github.com/astral-sh/uv/issues/5180#issuecomment-2247696198

Closes #5180
2024-07-31 15:39:16 +00:00
konsti 38c6033010
Use fork markers and fork preferences in resolution with lockfile (#5481)
By resolving for each fork from the lockfile individually and by adding
using preferences for the current fork, we solve the instability #5180.
I've tested the locally and will add the packse test scenarios upstack.

Part of
https://github.com/astral-sh/uv/issues/5180#issuecomment-2247696198
2024-07-31 15:18:58 +00:00
Charlie Marsh 176e9c4deb
Add `--package` to `uv sync` (#5656)
## Summary

Closes https://github.com/astral-sh/uv/issues/5008.
2024-07-31 15:16:48 +00:00
Andrew Gallant 5b8ed92f95 uv-client: switch heuristic freshness lifetime to hard-coded value
The comment in the code explains the bulk of this:

```rust
// We previously computed this heuristic freshness lifetime by
// looking at the difference between the last modified header and
// the response's date header. We then asserted that the cached
// response ought to be "fresh" for 10% of that interval.
//
// It turns out that this can result in very long freshness
// lifetimes[1] that lead to uv caching too aggressively.
//
// Since PyPI sets a max-age of 600 seconds and since we're
// principally just interacting with Python package indices here,
// we just assume a freshness lifetime equal to what PyPI has.
//
// Note though that a better solution here is for the index to
// support proper HTTP caching headers (ideally Cache-Control, but
// Expires also works too, as above).
```

We also remove the `heuristic_percent` field on `CacheConfig`. Since
that's actually part of the cache itself, we bump the simple cache
version.

Finally, we add some more `trace!` calls that should hopefully make
diagnosing issues related to the freshness lifetime a bit easier in the
future.

Fixes #5351
2024-07-31 08:12:11 -07:00
Charlie Marsh c2a6cb391b
Prioritize forks based on upper bounds (#5643)
## Summary

Given a fork like:

```
pylint < 3 ; sys_platform == 'darwin'
pylint > 2 ; sys_platform != 'darwin'
```

Solving the top branch will typically yield a solution that also
satisfies the bottom branch, due to maximum version selection (while the
inverse isn't true).

To quote an example from the docs:

```rust
// If there's no difference, prioritize forks with upper bounds. We'd prefer to solve
// `numpy <= 2` before solving `numpy >= 1`, since the resolution produced by the former
// might work for the latter, but the inverse is unlikely to be true due to maximum
// version selection. (Selecting `numpy==2.0.0` would satisfy both forks, but selecting
// the latest `numpy` would not.)
```

Closes https://github.com/astral-sh/uv/issues/4926 for now.
2024-07-31 11:05:12 -04:00
Charlie Marsh f268b7c90a
Prioritize forks based on Python narrowing (#5642)
## Summary

First part of: https://github.com/astral-sh/uv/issues/4926. We should
solve forks that _don't_ expand the world of supported versions (e.g.,
`python_version >= '3.11'` enables us to select new packages, since we
narrow the supported version range).
2024-07-31 10:29:14 -04:00
Vigilans 0dcec9eba8
Detect python version from python project by default in `uv venv` (#5592)
<!--
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? -->

`uv venv` should support adopting python version specified in
`requires-python` from `pyproject.toml`. This allows customization on
the venv setup when syncing from python project.

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

It also serves as a workaround to close
https://github.com/astral-sh/uv/issues/5258.

## Test Plan

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

1. Run `uv venv` in folder with `pyroject.toml` specifying
`requries-python = "<3.10"`. Python 3.9 is selected for venv.
2. Change to `requries-python = "<3.11"` and run `uv venv` again. Python
3.10 is selected now.
3. Switch to a folder without `pyproject.toml` then run `uv venv`.
Python 3.12 is selected now.

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
Co-authored-by: Zanie Blue <contact@zanie.dev>
2024-07-31 13:54:16 +00:00
Zanie Blue 7ef830460e
Replace `--python-preference installed` with `managed` (#5637)
Collapses the previous default into "managed" and makes the "managed"
behavior match "installed". People should use "only-managed" if they
want that behavior, it seems overly complicated otherwise.
2024-07-31 08:40:39 -05:00
konsti 981661c4af
Update pubgrub (#5649)
We improved the API structure in pubgrub, and also update to generally
keep up with upstream.
2024-07-31 12:54:11 +00:00
Charlie Marsh 2574f5b3fd
Omit transitive development dependencies from workspace lockfile (#5646)
## Summary

Omit development dependencies from (e.g.) path dependencies.

Closes https://github.com/astral-sh/uv/issues/5593.
2024-07-30 22:32:33 -04:00
Charlie Marsh 38c232e466
Bump version to v0.2.32 (#5641) 2024-07-30 18:56:39 -04:00
Charlie Marsh 5d727cb0af
Deprecate the `--isolated` flag (#5466)
## Summary

This PR deprecates the `--isolated` flag. The treatment varies across
the APIs:

- For non-preview APIs, we warn but treat it as equivalent to
`--no-config`.
- For preview APIs, we warn and ignore it, with two exceptions...
- For `tool run` and `run` specifically, we don't even warn, because we
can't differentiate the command-specific `--isolated` from the global
`--isolated`.
2024-07-30 22:40:38 +00:00
Charlie Marsh 67b3bfa213
Add `--isolated` support to `uv run` (#5471)
## Summary

The culmination of #4730. We now have `uv run --isolated` which always
uses a fresh environment (but includes the workspace dependencies as
needed). This enables you to test with strict isolation (e.g., `uv run
--isolated -p foo` will ensure that `foo` is unable to import anything
that isn't an actual dependency).

Closes #5430.
2024-07-30 19:27:47 +00:00
Charlie Marsh ff3bcbb639
Reframe use of `--isolated` in `tool run` (#5470)
## Summary

This PR gets rid of the global `--isolated` flag (which serves a bunch
of independent responsibilities right now) on `uv tool run` in favor of
a dedicated `--isolated` flag, which tells uv to avoid re-using an
existing tool environment for this invocation. We'll add the same thing
to `uv run`, to avoid using the base project environment.

This will become a bit clearer in #5466, when we deprecate the
`--isolated` flag on the preview APIs.
2024-07-30 15:09:53 -04:00
Zanie Blue 8545ae2312
Rename more use of "lock file" to "lockfile" (#5629) 2024-07-30 19:09:43 +00:00
Charlie Marsh d6c319a368
Suppress resolver output by default in `uv run` and `uv tool run` (#5580)
## Summary

The idea here is that we hide all resolver output (the grayed out
resolver messages, plus the list of environment modifications) by
default in `uv run` and `uv tool run`. You can pass `--show-resolution`
to re-enable them.

Closes https://github.com/astral-sh/uv/issues/5458.
2024-07-30 18:11:52 +00:00
Charlie Marsh f7494f24cf
Remove `--isolated` usages from the `uv python` API (#5468) 2024-07-30 17:52:53 +00:00
Charlie Marsh f1b3d2e1e1
Add `--no-workspace` and `--no-project` in lieu of `--isolated` (#5465)
## Summary

Right now, `--isolated` is read from `uv run` and `uv init` to avoid
discovering the current workspace (or project). This PR moves that
behavior to a dedicated `--no-workspace` flag for `uv init`, and
`--no-project` for `uv run`. They could use the same flag, but
`--no-project` feels confusing for `uv init`, and `--no-workspace` seems
confusing for `uv run` (especially so once you read the documentation,
where we refer to the thing you're omitting as the project).

Closes https://github.com/astral-sh/uv/issues/5429.
2024-07-30 13:40:35 -04:00
eth3lbert fc78561fa1
Add `git-ref` group for `uv add` (#5502)
## Summary

This PR allows us to reject specifying more than one git-ref at the cli
level.

## Test Plan

Test cases included.
2024-07-30 09:40:28 -05:00
Charlie Marsh dfa780d6f5
Re-enable requires-python narrowing in forks (#5583)
See: https://github.com/astral-sh/uv/issues/4669
See: https://github.com/astral-sh/uv/issues/4668
See: https://github.com/astral-sh/uv/pull/4902
2024-07-30 10:06:59 -04:00
Charlie Marsh 3e2ae93d6c
Improve order implementation for Python bound (#5599)
## Summary

We shouldn't unequivocally treat exclusions as greater than
inclusions...
2024-07-30 10:05:54 -04:00
Andrew Gallant 4e748363f8 uv-resolver: fix marker propagation
This PR represents a different approach to marker propagation in an
attempt to unblock #4640. In particular, instead of propagating markers
when forks are created, we wait until resolution is complete to
propagate all markers to all dependencies in each fork. This ends up
being both more robust (we should never miss anything) and simpler to
implement because it doesn't require mutating a `PubGrubPackage` (which
was pretty annoying). I think the main downside here is that this can
sometimes add markers where they aren't needed.

This actually winds up making quite a few snapshot changes. I went
through each of them. Some of them look like legitimate bug fixes. Some
of them look like superfluous additions. And some of them look like they
would be removed if we had perfect marker normalization. But I don't
think any of the changes are _wrong_.
2024-07-30 06:16:03 -07:00
Charlie Marsh 750b3a7c8c
Avoid setting executable permissions on files we might not own (#5582)
## Summary

If we just created an entrypoint script, we can of course set the
permissions (we just created it). However, if we're copying from the
cache, we might _not_ own the file. In that case, if we need to change
the permissions (we shouldn't, since the script is likely already
executable -- we set the permissions when we unzip, but I guess they
could _not_ be properly set in the zip itself), we have to copy it.

Closes https://github.com/astral-sh/uv/issues/5581.
2024-07-30 12:32:52 +00:00
Ben Beasley dfb4e5bbc8
Add license text to fetch-download-metadata.py (#5587) 2024-07-30 08:15:23 -04:00
konsti dedd913603
Add forks to lockfile, don't read them yet (#5480)
Add the forks to the lockfile, without using them yet, which we'll add
in the next PR.

Please review commit-by-commit

Part of
https://github.com/astral-sh/uv/issues/5180#issuecomment-2247696198
2024-07-30 11:11:18 +00:00
Maksim Bondarenkov 228a803fde
uv-python: use windows-sys instead of winapi (#5591)
<!--
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

use windows-sys bindings maintained by microsoft devs. winapi didn't has
any updates for more than 3 years

## Test Plan

cargo test. it failed locally because I don't have Python 3.12 installed
2024-07-30 11:43:04 +02:00
Ben Beasley c0d3da8b6a
Add LICENSE for cloneable_seekable_reader.rs from ripunzip (#5585) 2024-07-29 22:15:48 -04:00
Charlie Marsh c46adee48d
Make `--directory` a global argument (#5579)
## Summary

Cargo makes this global (and uses the same technique). It's still hidden
so we can always decide to remove it.
2024-07-29 19:43:55 -04:00
eth3lbert 3e329029bc
List installed tools when no command is provided to `uv tool run` (#5553)
## Summary

Part of #4024 

## Test Plan

Test cases included.
2024-07-29 22:12:31 +00:00
Charlie Marsh ecb85c9894
Statically link liblzma (#5577)
## Summary

Found via https://github.com/indygreg/PyOxidizer/issues/585.

Closes https://github.com/astral-sh/uv/issues/5572.
2024-07-29 21:46:43 +00:00
Charlie Marsh 51a03738a2
Use cached current directory everywhere (#5574) 2024-07-29 17:03:45 -04:00
Charlie Marsh 37388f0987
Make directory a required argument (#5573) 2024-07-29 20:47:34 +00:00
bluss e46c24d3cf
Implement `uv run --directory` (#5566)
## Summary

uv run --directory <path> means that one doesn't have to change to a
project's directory to run programs from it. It makes it possible to use
projects as if they are tool installations.

To support this, first the code reading .python-version was updated so
that
it can read such markers outside the current directory. Note the minor
change this causes (if I'm right), described in the commit.

## Test Plan

One test has been added.

## --directory

Not sure what the name of the argument should be, but it's following uv
sync's directory for now.

Other alternatives could be "--project". Uv run and uv tool run should
probably find common agreement on this (relevant for project-locked
tools).

I've implemented this same change in Rye, some time ago, and then we
went
with --pyproject `<`path to pyproject.toml file`>`. I think using
pyproject.toml file path and not directory was probably a mistake, an
overgeneralization one doesn't need.
2024-07-29 15:53:10 -04:00
Charlie Marsh cf94a10054
Skip copying to empty entries in seekable zip (#5571)
## Summary

We cannot do this when streaming, since we may not have the metadata for
the entry.

Closes https://github.com/astral-sh/uv/issues/5565.
2024-07-29 19:00:19 +00:00
Charlie Marsh f70501a22e
Use a consistent buffer size when writing out zip files (#5570) 2024-07-29 14:45:33 -04:00
Charlie Marsh 05b1f51aa1
Use a consistent buffer size for downloads (#5569) 2024-07-29 14:31:39 -04:00
Charlie Marsh 48162de974
Bump version to v0.2.31 (#5568) 2024-07-29 14:06:20 -04:00
konsti 194904b340
Redact packse version in snapshots follow-up (#5563)
I thought i had this included in #5483 but i had it on the wrong branch.
2024-07-29 15:22:20 +00:00
konsti 0f87d174b9
Redact packse version in snapshots (#5483)
Every packse version update is currently causing a huge diff (the size
of the `lock_scenarios.rs` diff in this PR). By redacting the version
from the snapshots, we will only have the actual change in the diff and
not the redundant version change noise.

The second commit moves all remaining packse url arg values to
`common/mod.rs`, which acts as a single source of truth for the packse
version.
2024-07-29 17:04:46 +02:00
Charlie Marsh 7ea95239bd
Use `hatchling` rather than implicit `setuptools` default (#5527)
## Summary

Closes https://github.com/astral-sh/uv/issues/5461.
2024-07-29 14:00:12 +00:00
konsti 0877f76aae
Retry on incomplete body (#5555)
This is an attempt to add
https://github.com/astral-sh/uv/issues/3514#issuecomment-2253562096 to
retrying.

Relevant hyper code:
*
15cd6fa1fc/src/proto/h1/decode.rs (L683)
*
15cd6fa1fc/src/proto/h1/decode.rs (L161-L164)
2024-07-29 15:53:23 +02:00
Charlie Marsh 41c1fc0c4d
Generate hashes for `--find-links` entries (#5544)
## Summary

Closes https://github.com/astral-sh/uv/issues/3874.
2024-07-29 08:49:38 +00:00
Charlie Marsh 51b7e9bff1
Retain editable designation for cached wheel installs (#5545)
## Summary

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

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

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

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

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

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

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

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

Fixes: #3863

## Test Plan

* Relocatable console scripts covered as additional scenarios in
existing test cases.
* Integration testing of boilerplate generation in `venv`.
* Manual testing of `uv venv` with and without `--relocatable`
2024-07-29 00:10:11 +00:00
Charlie Marsh d7c79182ea
Extend Ruff configuration to sort imports (#5528) 2024-07-28 21:49:28 +00:00
Charlie Marsh 2d5c166642
Compare simplified paths in Windows exclusion tests (#5525)
## Summary

Closes https://github.com/astral-sh/uv/issues/5521.
2024-07-28 17:26:46 -04:00
Charlie Marsh efbc9fb78d
Add support for benchmarking `uv sync` and `uv lock` (#5524)
## Summary

This PR adds support for `uv lock` and `uv sync` in the standardized
benchmarks script.

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

## Test Plan

For example:

```sh
python scripts/bench/__main__.py --uv-project --benchmark resolve-cold ./scripts/requirements/trio.in --verbose
```
2024-07-28 21:09:08 +00:00
Charlie Marsh 83412837e5
Warn, but don't error, when encountering tilde .dist-info directories (#5520)
## Summary

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

Closes https://github.com/astral-sh/uv/issues/5360.
2024-07-28 15:01:17 -04:00
Krishnan Chandra 4b4128446d
Support xz compressed packages (#5513)
## Summary

Closes #2187.

The [xz
backdoor](https://gist.github.com/thesamesam/223949d5a074ebc3dce9ee78baad9e27)
is still fairly recent, but luckily the [Rust `xz2` crate bundles
version 5.2.5 of the C `xz`
package](https://github.com/alexcrichton/xz2-rs/tree/main/lzma-sys),
which is before the backdoor was introduced.

It's worth noting that a security risk still exists if you have a
compromised version of `xz` installed on your system, but that risk is
not introduced by `uv` or the Rust packages in general.

## Test Plan

Tried installing the package mentioned in the linked issue: `python-apt
@
https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/python-apt/2.7.6/python-apt_2.7.6.tar.xz`

(Note that this will only work on Ubuntu - I tried on a Mac and while
the archive was extracted properly, the package did not install because
of some missing files)

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2024-07-28 18:37:48 +00:00
Charlie Marsh caf01735fa
Avoid warning users for missing self-extra lower bounds (#5518)
## Summary

Closes https://github.com/astral-sh/uv/issues/5227.
2024-07-28 18:35:18 +00:00
Charlie Marsh 88340fbd0d
Remove some unused methods (#5512) 2024-07-28 17:20:12 +00:00
Charlie Marsh 1734c7ed50
Use existing METADATA parser in wheel installer (#5508) 2024-07-27 14:38:16 -04:00
Jo ae11317cc0
Make `pip list --editable` conflicts with `--exlcude-editable` (#5506)
## Summary

I think it makes no sense to allow `--editable` and `--exclude-editable`
at the same time.

## Test Plan
```console
$ cargo run -- pip list --editable --exclude-editable
error: the argument '--editable' cannot be used with '--exclude-editable'

Usage: uv.exe pip list --editable

For more information, try '--help'.

```
2024-07-27 08:26:46 -04:00
Charlie Marsh 866d844977
Allow `uv pip install` for unmanaged projects (#5504)
## Summary

Just an oversight.

Closes: https://github.com/astral-sh/uv/issues/5500.
2024-07-27 02:10:18 +00:00
Charlie Marsh 24859bd3ee
Upgrade to Rust 1.80.0 (#5472) 2024-07-27 01:49:47 +00:00
Charlie Marsh 3ea5e16e96
Respect reinstalls in cached environments (#5499)
## Summary

Closes #5493.
2024-07-27 01:36:58 +00:00
Charlie Marsh 8f16f1b746
Remove serialize traits from verbatim URL (#5501) 2024-07-27 00:51:24 +00:00
Charlie Marsh 4f3dde34dc
Use 666 rather than 644 for default permissions (#5498)
## Summary

I don't know why I used 644 here. 666 is the actual default:
7c2012d0ec/library/std/src/sys/pal/unix/fs.rs (L1069)

Closes https://github.com/astral-sh/uv/issues/5496.
2024-07-27 00:08:52 +00:00
Charlie Marsh 623ba3885f
Add some missing reinstall-refresh calls (#5497)
## Summary

Turns out I missed a few of these.
2024-07-27 00:01:40 +00:00
Charlie Marsh 561625ed8c
Use hasher to compute resolution hash (#5495)
## Summary

Addressing one TODO. This should be more efficient.
2024-07-26 23:24:09 +00:00
Ahmed Ilyas e8d7c0cb58
Editable installs for `uv tool` (#5454)
## Summary

Resolves #5436. 

## Test Plan

`cargo test` 

```console
❯ ./target/debug/uv tool install -e ~/black
warning: `uv tool install` is experimental and may change without warning
Resolved 6 packages in 894ms
   Built black @ file:///Users/ahmedilyas/black
Prepared 1 package in 468ms
Installed 6 packages in 6ms
 + black==24.4.3.dev23+g7e2afc9 (from file:///Users/ahmedilyas/black)
 + click==8.1.7
 + mypy-extensions==1.0.0
 + packaging==24.1
 + pathspec==0.12.1
 + platformdirs==4.2.2
Installed 2 executables: black, blackd
```

venv has the `.pth` files.
```console
❯ eza /Users/ahmedilyas/Library/Application\ Support/uv/tools/black/lib/python3.12/site-packages/
_black.pth       _virtualenv.py                         click                  mypy_extensions-1.0.0.dist-info  packaging                 pathspec                   platformdirs
_virtualenv.pth  black-24.4.3.dev23+g7e2afc9.dist-info  click-8.1.7.dist-info  mypy_extensions.py               packaging-24.1.dist-info  pathspec-0.12.1.dist-info  platformdirs-4.2.2.dist-info
```

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2024-07-26 16:30:15 -04:00
Andrew Gallant 2186e967f6 uv-resolver: fix basic case of overlapping markers
Consider the following packse scenario:

```toml
[root]
requires = [
  "a>=1.0.0 ; python_version < '3.10'",
  "a>=1.1.0 ; python_version >= '3.10'",
  "a>=1.2.0 ; python_version >= '3.11'",
]

[packages.a.versions."1.0.0"]
[packages.a.versions."1.1.0"]
[packages.a.versions."1.2.0"]
```

On current `main`, this produces a dependency on `a` that looks like
this:

```toml
dependencies = [
    { name = "fork-overlapping-markers-basic-a", marker = "python_version < '3.10' or python_version >= '3.11'" },
]
```

But the marker expression is clearly wrong here, since it implies that
`a` isn't installed at all for Python 3.10. With this PR, the above
dependency becomes:

```toml
dependencies = [
    { name = "fork-overlapping-markers-basic-a" },
]
```

That is, it's unconditional. Which is I believe correct here since there
aren't any other constraints on which version to select.

The specific bug here is that when we found overlapping dependency
specifications for the same package *within* a pre-existing fork, we
intersected all of their marker expressions instead of unioning them.
That in turn resulted in incorrect marker expressions.

While this doesn't fix any known bug on the issue tracker (like #4640),
it does appear to fix a couple of our snapshot tests. And fixes a basic
test case I came up with while working on #4732.

For the packse scenario test: https://github.com/astral-sh/packse/pull/206
2024-07-26 12:06:37 -07:00
Charlie Marsh 6901a14aa0
Bump version to v0.2.30 (#5486) 2024-07-26 13:36:05 -04:00
konsti f1eda3590b
Update to packse 0.3.31 (#5441)
Update packse to 0.3.31, adding the instability scenarios.
2024-07-26 15:39:29 +00:00
konsti cb505d24f8
Unify resolutions only during graph building (#5479)
With our previous eager union, we were losing the fork markers. We now
carry this information into the resolution graph construction and, in
the next step, can read the markers there.

Part of
https://github.com/astral-sh/uv/issues/5180#issuecomment-2247696198
2024-07-26 16:29:48 +02:00
Andrew Gallant 77b005244d uv-resolver: propagate markers to sibling dependencies in forks
When a fork occurs, we divide not just the dependencies that
provoked a fork into distinct groups, but we also add the
corresponding sibling dependencies to each fork. Previously,
while we track markers on the fork itself, the individual
dependencies that had markers only corresponded to markers
written from the dependency specification.

This meant that the sibling dependencies that got added to
each fork would not themselves have markers attached to them.
This in turn meant they would not have markers associated with
them in the lock file.

In many cases, this is actually okay, because the resolver will
pick a version that is "universal" across all forks in most
cases. But in some cases, this just simply isn't possible as
the marker expressions in the fork can and do influence resolution.
In which case, it is possible for the same package with different
versions to show up in the lock file unconditionally. Which is a
big no-no.

So in this commit, after we determine the forks, we intersect the
markers on each fork with each of its dependencies.

This does seem to balloon the marker expressions in some cases.
I plucked one low hanging fruit to avoid doing `x and x` in
trivial cases. (And this eliminated a portion of the snapshot
diffs.) But some pretty gnarly diffs remain.

This commit also fixes another bug: previously, when we created a fork
to capture the "remaining" universe of an incomplete set of markers, we
left out dependencies that should be included in that fork. We rectify
that here.

Fixes #5086

Partially addresses #4732
2024-07-26 07:28:20 -07:00
Andrew Gallant 412780fd99 uv/tests: add regression test from #5086
The snapshot saved here is wrong, but we'll update it in a subsequent
commit.
2024-07-26 07:28:20 -07:00
Andrew Gallant cd1fc7c9a3 uv-normalize: make "name" types implement Default
Interestingly, the empty string appears to be valid for these
types. I'm not sure if that's intended, but having a Default
impl is useful for use with `std::mem::take`.
2024-07-26 07:28:20 -07:00
Andrew Gallant 7fce59e4bc pep508: some simplification in 'and' and 'or'
Basically, and'ing or or'ing the same expression can be entire
skipped. And we try harder to avoid singleton conjunctions or
disjunctions, as these are considered unequal otherwise. (Thus
defeating our attempts to avoid and'ing or or'ing a superfluous
marker.)
2024-07-26 07:28:20 -07:00
Charlie Marsh 8b8f34ac21
Avoid canonicalizing executables on Windows (#5446)
## Summary

If you have an executable path on a network share path (like
`\\some-host\some-share\...\python.exe`), canonicalizing it adds the
`\\?` prefix, but dunce cannot safely strip it.

This PR changes the Windows logic to avoid canonicalizing altogether. We
don't really expect symlinks on Windows, so it seems unimportant to
resolve them.

Closes: https://github.com/astral-sh/uv/issues/5440.
2024-07-26 08:57:33 -04:00
Charlie Marsh 967fcdbb83
Update bundled Pythons to include stripped variants (#5469)
## Summary

The previous update used a slightly botched release.
2024-07-26 00:34:45 +00:00
Charlie Marsh d51b429837
Add `--no-config` to replace `--isolated` (#5463)
## Summary

I'll deprecate `--isolated` separately, since it _is_ still used for
some other behaviors.

Closes #5428.
2024-07-25 19:58:36 -04:00
Charlie Marsh 8cb22f5500
Gate `FromStr` to `pep508` feature (#5464)
## Summary

This is triggering when you run without `--all-features` (but we always
use `--all-features` in CI, so it went unnoticed).
2024-07-25 23:54:07 +00:00
Charlie Marsh e4d1039f49
Use `sitecustomize.py` to implement environment layering (#5462)
## Summary

After consultation with @carljm, we learned that modifying `PYTHONPATH`
is insufficient, because Python won't resolve `.pth` files (editables)
in the base environment. We also saw in
https://github.com/astral-sh/uv/issues/5459 that continuously appending
to `PYTHONPATH` can have some unintended effects.

This PR instead uses a `sitecustomize.py` in the ephemeral environment
to add the base environment's `site-packages`.

Closes https://github.com/astral-sh/uv/issues/5459.
2024-07-25 19:32:44 -04:00
Charlie Marsh 6f45403d31
Infer missing `.exe` in Windows Python discovery (#5456)
## Summary

Closes https://github.com/astral-sh/uv/issues/5445.
2024-07-25 16:57:38 -04:00
Charlie Marsh 1e965b47c3
Set standard permissions for temporary files (#5457)
## Summary

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

## Test Plan

Before:

```
❯ ls -l .venv/lib/python3.12/site-packages/httpx-0.27.0.dist-info
total 48
-rw-------  1 crmarsh  staff     2 Jul 25 14:21 INSTALLER
-rw-r--r--  1 crmarsh  staff  7184 Jul 23 23:20 METADATA
-rw-r--r--  1 crmarsh  staff  2541 Jul 25 14:21 RECORD
-rw-------  1 crmarsh  staff     0 Jul 25 14:21 REQUESTED
-rw-r--r--  1 crmarsh  staff    87 Jul 23 23:20 WHEEL
-rw-r--r--  1 crmarsh  staff    37 Jul 23 23:20 entry_points.txt
drwxr-xr-x  3 crmarsh  staff    96 Jul 25 14:21 licenses
```

After:

```
❯ ls -l .venv/lib/python3.12/site-packages/flask-3.0.3.dist-info/
total 48
-rw-r--r--  1 crmarsh  staff     2 Jul 25 14:21 INSTALLER
-rw-r--r--  1 crmarsh  staff  1475 Jul 25 14:21 LICENSE.txt
-rw-r--r--  1 crmarsh  staff  3177 Jul 25 14:21 METADATA
-rw-r--r--  1 crmarsh  staff  2565 Jul 25 14:21 RECORD
-rw-r--r--  1 crmarsh  staff     0 Jul 25 14:21 REQUESTED
-rw-r--r--  1 crmarsh  staff    81 Jul 25 14:21 WHEEL
-rw-r--r--  1 crmarsh  staff    40 Jul 25 14:21 entry_points.txt
```
2024-07-25 20:50:30 +00:00
Charlie Marsh 75a042d5ff
Allow distributions to be absent in deserialization (#5453)
## Summary

Closes https://github.com/astral-sh/uv/issues/5434.
2024-07-25 18:01:41 +00:00
Charlie Marsh a089e20a35
Use stripped variants by default in Python install (#5451)
## Summary

Will file a separate ticket to support `--debug`.

Closes https://github.com/astral-sh/uv/issues/5447.
2024-07-25 17:29:31 +00:00
Ibraheem Ahmed 4da34a6e2e
Reorganize pep508 marker module (#5433)
## Summary

Just moves some code around into separate modules, the current file is a
bit too large to navigate.
2024-07-25 15:22:46 +00:00
Andrew Gallant 7dff3d7dfe uv/tests: updates snapshots for main
It looks like we had a bad merge where the result caused some test
failures. This commit just updates the snapshots to the new reality. I
haven't found the root cause of the bad merge yet.
2024-07-25 07:42:26 -07:00
Zanie Blue 42e76e2545
Prefer "lockfile" to "lock file" (#5427)
Closes https://github.com/astral-sh/uv/issues/5415
2024-07-25 09:22:36 -05:00
Charlie Marsh d0919329fd
Make `--reinstall` imply `--refresh` (#5425)
## Summary

It's hard for me to imagine a scenario in which a user passed
`--reinstall`, but wanted us to keep respecting cached data for a
package. For example, to actually "rebuild and reinstall" an editable
today, you have to pass both `--reinstall` and `--refresh`.

This PR makes `--reinstall` imply `--refresh`, so we always validate
that the cached data is fresh.

Closes https://github.com/astral-sh/uv/issues/5424.
2024-07-25 09:45:58 -04:00
Charlie Marsh 4d9098a1d7
Cache metadata for source tree dependencies (#5423)
## Summary

This PR re-introduces caching for source trees. In short, we treat the
metadata as cached unless the `pyproject.toml`, `setup.py`, or
`setup.cfg` file changes. This is a heuristic and not a good one,
especially for extension modules, but without it, we have to rebuild
every project every time (unless you have static metadata, like a
`pyproject.toml` that we can read directly).

Now that we support persistent configuration, users should add:

```toml
[tool.uv]
reinstall = ["foo"]
```

If they want a package to always be refreshed (ignore cache) and
reinstalled (ignore environment).

Closes https://github.com/astral-sh/uv/issues/5420.
2024-07-25 09:45:52 -04:00
konsti 375a4152fa
Split `ResolutionGraph::from_state` into methods (#5439)
Two changes split out from the instability work:

* Break `ResolutionGraph::from_state` into methods before adding new
logic to it.
* `ResolutionGraph`: Convert `NodeKey` type to `PackageRef` struct:
Another small refactoring to make subsequent changes easier.

No functional changes.

@BurntSushi I hope this doesn't interfere with your work too much, the
`PackageRef` should at least make debugging panics here easier.
2024-07-25 14:40:09 +02:00
konsti f1dadbe3c6
Restructure `CandidateSelector` methods (#5438)
In preparation for the preferences changes with forking, change the
method structure in `CandidateSelector`. Split out into its own PR to
avoid merge conflicts with main. No functional changes.
2024-07-25 10:26:15 +00:00
konsti 93fb28fd2c
Merge identical forks (#5405)
Consider these requirements from pylint 3.2.5:

```
Requires-Dist: dill >=0.3.6 ; python_version >= "3.11"
Requires-Dist: dill >=0.3.7 ; python_version >= "3.12"
```

We will split on the python version, but then we may pick a version of
`dill` that's `>=0.3.7` in both branches and also have an otherwise
identical resolution in both forks. In this case, we merge both forks
and store only their conjoined markers.
2024-07-25 11:54:54 +02:00
Ibraheem Ahmed 39be71f403
Normalize marker expression order (#5422)
## Summary

Normalize the order of marker expressions on construction. This removes
the distinction between expressions like `os_name == 'Linux'` vs.
`'Linux' == os_name` throughout the codebase. One caveat here is that
the `in` operator does not have a direct inverse, so we introduce
`MarkerOperator::Contains` to handle that case.

I wanted to land this smaller change before some more intrusive changes
as it simplifies the existing code quite a bit.
2024-07-24 18:28:34 -04:00
Zanie Blue 35b6726df5
Bump version to 0.2.29 (#5431) 2024-07-24 22:23:34 +00:00
Charlie Marsh d11d11ef88
Validate successful metadata fetch for direct dependencies (#5392)
## Summary

Prior to this change, the resolver would panic if we ran with
`--offline` and `--no-deps` and we had cached metadata for a _package_
(i.e., the versions) but no cached metadata for the _distribution_
(i.e., the specific wheel), since we weren't validating that the
returned metadata in the `--no-deps` case was actually successful. (We
need metadata, even for `--no-deps`, so that we can validate extras.)

## Test Plan

The added test panics on the previous branch.
2024-07-24 19:44:41 +00:00
Charlie Marsh 4bc04f91e9
Add `--ci` mode to `uv cache prune` (#5391)
## Summary

Users can now run `uv cache prune --ci` (open to feedback on the name of
that flag) to remove all pre-built wheels from the cache, leaving behind
zipped, built wheels (which tend to be the most expensive assets to
re-create). This should greatly increase cache performance in CI
environments, since uploading unzipped wheels can actually hurt
performance if you're persisting the uv cache.

Closes https://github.com/astral-sh/uv/issues/5282.
2024-07-24 19:34:19 +00:00
Charlie Marsh fff3a7d8f9
Always accept already-installed pre-releases (#5419)
## Summary

If a pre-release is already installed, we should allow it to be used
even if it doesn't match the strategy.

Closes https://github.com/astral-sh/uv/issues/5418.
2024-07-24 19:23:14 +00:00
Jo 7bcafec778
Add `uv init --virtual` (#5396)
## Summary

Add `uv init --virtual` to create an explicit virtual workspace.

Relates to #5338
2024-07-24 18:52:33 +00:00
Andrew Gallant ac614ee70f uv/tests: tweak cache clean all test
The test asserts that 28 files were removed. But on my system, 27 files
are removed.

This PR is first about debugging what the difference is (since CI
presumably passes with the status quo snapshot). And then I'm thinking
the right way to fix the test failure is with a filter that replaces the
specific number of files removed (limited to what we know to be
correct) with a placeholder.
2024-07-24 10:41:33 -07:00
Charlie Marsh 9c9510c9ef
Ignore hidden directories in workspace discovery (#5408)
## Summary

This is surprisingly complex because we need to decide what happens if
you run `uv run` from within a hidden folder, etc. For now, I did the
simplest thing: we just ignore workspace members that are hidden
directories if they lack a `pyproject.toml`, so you can still include
hidden members, they're just ignored if they don't seem to be projects.

Closes https://github.com/astral-sh/uv/issues/5403.
2024-07-24 16:21:34 +00:00
Charlie Marsh 22db997240
Always show lock updates in `uv lock` (#5413)
## Summary

Closes https://github.com/astral-sh/uv/issues/5412.
2024-07-24 15:54:18 +00:00
Charlie Marsh 3d36b71ab1
Show additions and removals in `uv lock` updates (#5410)
## Summary

Closes https://github.com/astral-sh/uv/issues/5401.
2024-07-24 15:33:09 +00:00
Zanie Blue eef7a78d7e
Omit interpreter path from output when using managed Python (#5313)
Extending https://github.com/astral-sh/uv/pull/5311 to the project API
2024-07-24 10:19:12 -05:00
Trevor Manz d642705104
Omit empty uv.tool.dev-dependencies on `uv init` (#5406)
<!--
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

Implements #5340

## Test Plan

<!-- How was it tested? -->
2024-07-24 09:53:49 -05:00
Charlie Marsh cf971a86d7
Remove resolved TODO in `uv run` (#5407) 2024-07-24 09:54:16 -04:00
konsti 9b12fcb90d
Remove outdated `DistributionWire` serde annotations (#5400)
This struct doesn't implement `serde::Serialize`, the annotations are
dead.
2024-07-24 15:30:58 +02:00
Charlie Marsh 82f4864386
Ignore Ctrl-C signals in `uv run` and `uv tool run` (#5395)
## Summary

This is a bit simpler than #5333, but seems to work in my testing on
macOS and Windows. It's based on implementations that I found in
[Pixi](36f1bb297d/src/cli/exec.rs (L99))
and
[Wasmer](49e60af8df/lib/wasix/src/state/builder.rs (L1058)).

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

## Test Plan

On both macOS and Windows:

- `cargo run -- tool run --from jupyterlab jupyter-lab` -- hit Ctrl-C;
verify that the process exits and the terminal is left in a good state.
- `cargo run -- run python` -- hit Ctrl-C; verify that the process does
_not_ exit, but does on Ctrl-D.
2024-07-24 08:33:10 -04:00
konsti 20018cd0fc
Add two `ForkState` methods (#5404)
Small refactoring split out of the instability work. No functional
changes.
2024-07-24 12:09:33 +00:00
konsti 6d34f53ee5
Update `Resolution` docs (#5402)
They didn't reflect the recent nodes/edges changes.
2024-07-24 11:39:48 +00:00
Charlie Marsh 41b699e7ac
Add warning to `--link-mode=symlink` documentation (#5387) 2024-07-23 22:35:56 +00:00
Charlie Marsh 2271486e0e
Skip 'Nothing to uninstall' message when removing dangling environments (#5382)
## Summary

Closes https://github.com/astral-sh/uv/issues/5379.
2024-07-23 18:28:22 -04:00
Charlie Marsh ad4a15d0c2
Allow symlinks to files in scripts directory (#5380)
## Summary

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

## Test Plan

Unfortunately, the only packages I know of that use this are Ruff and
uv, and both are too heavy to install in a recurring test, so:

`uv tool install hatch==1.12.0 --with uv==0.2.27 --force
--link-mode=symlink`
2024-07-23 22:24:43 +00:00
Charlie Marsh 8942ec36c0
Mark `--raw-sources` as conflicting with sources-specific arguments (#5378)
## Summary

We should error on, e.g., `--raw-sources --tag 0.0.1`.
2024-07-23 22:03:01 +00:00
Charlie Marsh 76566b09be
Reject Git CLI arguments with non-Git sources (#5377)
## Summary

Closes https://github.com/astral-sh/uv/issues/5335.
2024-07-23 21:48:50 +00:00
Charlie Marsh 4863ec8b5b
Allow `uv init` in unmanaged projects (#5372)
## Summary

Closes https://github.com/astral-sh/uv/issues/5368.
2024-07-23 16:51:30 -04:00
Charlie Marsh c271eda6b6
Retain dependency specifier in `uv add` with sources (#5370)
## Summary

Only clear the version if it's a URL.

Closes https://github.com/astral-sh/uv/issues/5339.
2024-07-23 16:48:41 -04:00
Charlie Marsh 25c7599030
Warn on `requirements.txt`-provided arguments in `uv run` et al (#5364)
## Summary

Also applies to `uv tool run` and `uv tool install`.

Closes https://github.com/astral-sh/uv/issues/5349.
2024-07-23 16:34:01 -04:00
Charlie Marsh ada2b2bc29
Pre-populate authentication sources in Project and Tools APIs (#5367)
## Summary

Closes https://github.com/astral-sh/uv/issues/5366.
2024-07-23 16:33:53 -04:00
Zanie Blue 7908436a76
Display Python installation key for discovered interpreters (#5365)
> DEBUG Found `cpython-3.12.1-macos-aarch64-none` at
`/Users/zb/Library/Application
Support/uv/python/cpython-3.12.1-macos-aarch64-none/bin/python3`
(managed installations)

Instead of `<implementation> <version>`

> DEBUG Found cpython 3.12.1 at `/Users/zb/Library/Application
Support/uv/python/cpython-3.12.1-macos-aarch64-none/bin/python3`
(managed installations)
2024-07-23 15:29:15 -05:00
Charlie Marsh 2cdcc61da9
Support `requirements.txt` files in `uv tool install` and `uv tool run` (#5362)
## Summary

Closes https://github.com/astral-sh/uv/issues/5347.
Closes https://github.com/astral-sh/uv/issues/5348.
2024-07-23 20:06:17 +00:00
Jo 7ddf67a72b
Add PyPy finder (#5337)
## Summary

This PR adds PyPy finder and adds PyPy to uv managed Python versions.

## Test Plan

```console
$ cargo run -- python install
```
2024-07-23 14:58:04 -05:00
Jo 96b24345eb
Allow comments in `.python-version[s]` (#5350)
## Summary

Do the same thing as https://github.com/astral-sh/rye/pull/1038.
2024-07-23 14:56:50 -05:00
Zanie Blue 6fe9bd8a80
Omit interpreter path during `uv venv` with managed Python (#5311)
e.g. 
```
❯ cargo run -q -- venv --preview
Using Python 3.12.1
Creating virtualenv at: .venv
Activate with: source .venv/bin/activate
```

instead of 

```
❯ cargo run -q -- venv --preview
Using Python 3.12.1 interpreter at: /Users/zb/Library/Application Support/uv/python/cpython-3.12.1-macos-aarch64-none/bin/python3
Creating virtualenv at: .venv
Activate with: source .venv/bin/activate
```
2024-07-23 14:20:23 -05:00
Zanie Blue 3a85353707
Bump version to 0.2.28 (#5363) 2024-07-23 14:04:55 -05:00
Jo 68c27cbd06
Avoid project discovery in `uv python pin` if `--isolated` is provided (#5354)
## Summary

Instead of discovering and then discarding, try to avoid unnecessary
discovery.
2024-07-23 13:07:25 -05:00
Zanie Blue 3e067766de
Stylize `Requires-Python` consistently (#5304) 2024-07-23 18:05:21 +00:00
Charlie Marsh 07d038b90c
Add tests for `uv cache clean` (#5356) 2024-07-23 18:03:02 +00:00
Charlie Marsh 097acb628d
Remove Simple API cache files for alternative indexes in `cache clean` (#5353)
## Summary

The `simple-v9` directory was missing the `index` segment. See before:


![Screenshot 2024-07-23 at 1 29
18 PM](https://github.com/user-attachments/assets/3af9ccbf-ba45-4910-ad3b-4f52806dc8c9)

And after:

![Screenshot 2024-07-23 at 1 29
38 PM](https://github.com/user-attachments/assets/15535534-3304-4209-93e8-7f5e572929f0)

Every other bucket has this `index` segment for non-PyPI indexes, e.g.:

![Screenshot 2024-07-23 at 1 29
24 PM](https://github.com/user-attachments/assets/7354c9ad-7757-4a5f-a7b8-ff987a100e39)

Closes https://github.com/astral-sh/uv/issues/5352.
2024-07-23 13:42:51 -04:00
Zanie Blue 5f1f9c8293
Add support for requirements files in `uv run` (#4973)
Closes https://github.com/astral-sh/uv/issues/4824.

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2024-07-23 12:51:09 -04:00
Charlie Marsh 8ebc0d56c7
Fix failing prerelease tests (#5346)
## Summary

Likely due to simultaneous merge.
2024-07-23 12:45:55 -04:00
eth3lbert e05d653a71
Show symbolic links in `uv python list` (#5343)
## Summary

This PR displays symbolic links in `uv python list` and produces output
similar to the following:

```
:) uv python list --preview
cpython-3.12.1-macos-aarch64-none     /Users/eth/workspace/astral-sh/uv/bin/python3.12 -> versions/cpython@3.12.1/install/bin/python3
cpython-3.12.1-macos-aarch64-none     /Users/eth/workspace/astral-sh/uv/bin/python3 -> versions/cpython@3.12.1/install/bin/python3
cpython-3.12.1-macos-aarch64-none     /Users/eth/workspace/astral-sh/uv/bin/python -> versions/cpython@3.12.1/install/bin/python3
cpython-3.11.7-macos-aarch64-none     /Users/eth/workspace/astral-sh/uv/bin/python3.11 -> versions/cpython@3.11.7/install/bin/python3
cpython-3.10.13-macos-aarch64-none    /Users/eth/workspace/astral-sh/uv/bin/python3.10 -> versions/cpython@3.10.13/install/bin/python3
cpython-3.9.18-macos-aarch64-none     /Users/eth/workspace/astral-sh/uv/bin/python3.9 -> versions/cpython@3.9.18/install/bin/python3
cpython-3.8.18-macos-aarch64-none     /Users/eth/workspace/astral-sh/uv/bin/python3.8 -> versions/cpython@3.8.18/install/bin/python3

```


Resolves #5308 

## Test Plan

```
$ cargo run python list
```
2024-07-23 11:41:29 -05:00
Charlie Marsh 0f8186d9ad
Add `requires-python` to `uv init` (#5322)
## Summary

Prefers, in order:

- The major-minor version of an interpreter discovered via `--python`.
- The `requires-python` from the workspace.
- The major-minor version of the default interpreter.

If the `--python` request is a version or a version range, we use that
without fetching an interpreter.

Closes https://github.com/astral-sh/uv/issues/5299.
2024-07-23 16:02:40 +00:00
Ibraheem Ahmed c8ac8ee57a
Allow conflicting prerelease strategies when forking (#5150)
## Summary

Similar to https://github.com/astral-sh/uv/pull/5232, we should also
track prerelease strategies per-fork, instead of globally per package.
The common functionality for tracking locals and prerelease versions
across forks is extracted into the `ForkMap` type.

Resolves https://github.com/astral-sh/uv/issues/4579. This doesn't quite
solve https://github.com/astral-sh/uv/issues/4959, as that issue relies
on overlapping markers.
2024-07-23 11:57:14 -04:00
konsti bea8bc6c61
Stable sorting of requirements.txt in universal mode (#5334)
The `RequirementsTxtComparator` was written assuming there is one
distribution per package name. This changed with the universal
resolution, which allows multiple versions or urls for the same package
name. The sorting we emitted for these new entries was incidental.

With this change, we properly sort these entries by name, version and
then url in universal mode.

This is an output format change for `--universal` users.
2024-07-23 16:46:32 +02:00
Jo 43084249ee
Add mypy type check for uv-python scripts (#5332)
## Summary

Per https://github.com/astral-sh/uv/pull/4853#issuecomment-2212505407

> If we're going to aim for full type coverage, we should probably
follow this by adding type checking in CI too otherwise it seems too
easy for it to become out of date.
2024-07-23 09:14:05 -05:00
Jo 025f2f3162
Fix `python-build-standalone` workflow (#5327)
## Summary

The script reads `GITHUB_TOKEN` instead. And since #4853 merged, there
is no need to use `uv run --with`.
2024-07-23 08:20:36 -04:00
eth3lbert df7a733e51
Fix `uv init .` (#5330)
## Summary

This PR avoids an `Invalid package name` error that occurs when using
`uv init .`. This is achieved by slightly reorganizing the code block to
determine the name after the path is canonicalized. The dot path is
expanded to the current directory, and the `file_name` then works as
expected.

Resolve #5329 .

---------

Co-authored-by: konstin <konstin@mailbox.org>
2024-07-23 08:20:13 -04:00
samypr100 166fe85bb7
feat: fix uv-trampoline renovate issues (#5204)
## Summary

1. Fixes errors from https://github.com/astral-sh/uv/pull/4878
2. More cleanup. Removed the need for `MaybeUninit` and `SizeOf`
helpers. Renamed main entrypoint to expected default in windows
`mainCRTStartup` to avoid re-declaring /ENTRY in build.rs.
3. Adds a small basic test harness that >>on windows<< will generate
both types of launchers and run them. I've had been using this locally
to test changes and edge cases, but it might be useful for others. It's
based on core parts of install-wheel-rs.

## Test Plan

Tested locally on a couple of script/gui apps.

---------

Co-authored-by: konsti <konstin@mailbox.org>
2024-07-23 10:12:28 +02:00
Charlie Marsh e61fcbd7af
Improve consistency of `tool` CLI (#5326)
## Summary

More consistent colors, etc.
2024-07-23 03:10:47 +00:00
Jo 0a6efe4d26
Refactor `fetch-download-metadata.py` script (#4853)
## Summary

Similiar to https://github.com/astral-sh/rye/pull/680, I have made a
major refactor to the `fetch-download-metadata.py` script.

Some notable changes:

- Use PEP 723 inline scripts
- Fully type annotated the script
- Implemented async HTTP fetching
- Introduced a `Finder` base class and move finder logic under
`CPythonFinder` subclass, which will make it easier to add a
`PyPyFinder` later.
- Instead of fetching `xxx.sha256` for each file, the script now fetches
a single `SHA256SUMS` file containing checksums for all files in the
release.

As a result, the script now takes around 10 seconds instead of 10+
minutes.

## Plan for Future PRs

- [ ] Implement the `PyPyFinder`
- [ ] Add an GitHub Action to run `fetch-download-metadata.py` daily and
create PR automatically

## Test Plan

```sh
cargo run -- run --isolated -- ./crates/uv-python/fetch-download-metadata.py
```
2024-07-23 03:06:25 +00:00
Zack Elia f371195536
Allow symlinks with `--find-links` (#5323)
## Summary

In my setup, I have a directory of wheels symlinked from different
directories. I can point `--find-links` at it with `pip` and it works
but not `uv`.

Currently, `uv` checks if a candidate file `is_file` which is for
regular files. By also checking `is_symlink` I was able to install a
symlinked wheel. I'm not *exactly* sure where, but some other place is
eventually resolving the absolute path of the wheel. (`uv`? The OS?)

## Test Plan

Manually tested - I didn't see any tests for `FlatIndexClient` in the
`uv-client` crate.

```
mkdir /tmp/a /tmp/b                               # Create a directory of wheels (/tmp/a) and a directory of symlinked wheels (/tmp/b)
cp test-0.0.1-py3-none-any.whl /tmp/a             # Add a wheel to the directory of wheels
ln -s /tmp/a/test-0.0.1-py3-none-any.whl /tmp/b/  # Create a symlink to that wheel
uv pip install test --find-links /tmp/b           # Install pointing at the symlinked wheels directory
```
2024-07-23 02:53:39 +00:00
Charlie Marsh 41ca3572ab
Avoid redundant members update in `uv init` (#5321)
## Summary

If the path is already covered by `members`, we don't need to update it.

Closes https://github.com/astral-sh/uv/issues/5320.
2024-07-23 00:25:20 +00:00
Charlie Marsh 2f768b8bb0
Respect exclusions in `uv init` (#5318)
## Summary

Avoid adding to the workspace.

Closes https://github.com/astral-sh/uv/issues/5254.
2024-07-23 00:15:17 +00:00
Charlie Marsh 13dd8853d9
Create member `pyproject.toml` prior to workspace discovery (#5317)
## Summary

Otherwise, if the path is already a member, discovery fails.

Also adds a failing test for "adding members that are already covered by
`members`".
2024-07-23 00:03:53 +00:00
Jo d232bfea00
`uv init` should not create nested workspace (#5293)
## Summary

Resolves #5251
2024-07-22 19:48:40 -04:00
Charlie Marsh 26e042a794
Include URLs on graph edges (#5312)
## Summary

Excellent find from @konstin. If we have a package that's included in
two forks at the same version, but with different URLs, we need to avoid
collapsing them in the lockfile.

Closes https://github.com/astral-sh/uv/issues/5294.
2024-07-22 22:41:03 +00:00
Zanie Blue 4f9ac3b61d
Fix test snapshot (#5314)
Fixes failure on `main` from merge conflict
2024-07-22 21:32:16 +00:00
Charlie Marsh 84b351a289
Avoid including empty extras in resolution (#5306)
## Summary

You can still generate instabilities, but at least it's consistent
between including and excluding the extra.

For example, this resolves to 54 and then 52 packages on re-run:

```toml
[project]
name = "transformers"
version = "4.39.0.dev0"
description = "State-of-the-art Machine Learning for JAX, PyTorch and TensorFlow"
requires-python = ">=3.9.0"

dependencies = []

[project.optional-dependencies]
flax = ["jaxlib>=0.4.1,<=0.4.13"]
onnxruntime = ["onnxruntime>=1.4.0"]
ray = ["ray[tune]>=2.7.0"]
deepspeed-testing = [
  "dill<0.3.5",
  "datasets!=2.5.0",
]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
```

I think the difference is just somewhere in PubGrub -- like, we add an
extra dependency, so the iteration order gets changed, and we end up
with a different resolution at the end.

Closes https://github.com/astral-sh/uv/issues/5285.
2024-07-22 15:57:53 -04:00
Jo f00c3f26a2
`uv init` ignores workspace when `--isolated` flag is used (#5290)
## Summary

Per https://github.com/astral-sh/uv/pull/5250#issuecomment-2242137762

> It would also be great to have an argument (perhaps leveraging the
global isolated option) that allows us to disable workspace discovery
when we don't want to add a project as a member.


## Test Plan

```sh

$cargo run -- init work
$ cargo run -- init work/pkg-a --isolated
warning: `uv init` is experimental and may change without warning
Initialized project sub-c in /tmp/work
```
2024-07-22 15:13:05 -04:00
konsti 0a95b7abcd
Simplify `Resolution` type (#5301)
Looking at how to merge identical forks, i found that the `Resolution`
can be simplified by treating it as a nodes and edges store (plus pins,
they are separate since they are per name-version, not per
(virtual-)package-version). This should also make #5294 more apparent,
which i didn't touch here.

I additionally added some doc comments to the `Resolution` types.
2024-07-22 15:10:30 -04:00
konsti e207a909ad
Slim down `solve` (#5300)
Our everything-method `solve` tends to grow large, so before i'm adding
more logic, i'm moving some code and some logging statements around to
keep it manageable.

I made minor changes to the logging, otherwise no logic changes, only
refactoring.
2024-07-22 20:52:45 +02:00
Charlie Marsh 613f16abd4
Make tool install robust to malformed receipts (#5305)
## Summary

Closes https://github.com/astral-sh/uv/issues/5295
2024-07-22 18:46:57 +00:00
Charlie Marsh ca46ce2791
Remove extraneous `are` from wheel tag error messages (#5303)
## Summary

Closes #5297.
2024-07-22 18:42:58 +00:00
Charlie Marsh 2d9df488ef
Use tag error rather than requires-python error for ABI filtering (#5296)
## Summary

`dearpygui==1.9.1 has no wheels are available with a matching Python
ABI` is way better than `he requested Python version (>=3.12.3) does not
satisfy Python>=3.12.3`.

Closes https://github.com/astral-sh/uv/issues/5284.
2024-07-22 18:31:08 +00:00
Zanie Blue 8d12a660c4
Use backticks in project init message (#5302) 2024-07-22 18:18:37 +00:00
Yorick 0c4627e2f2
If multiple indices contain the same version, use the first index (#5288)
This fixes resolving packages that publish an invalid stub to pypi, such
as tensorrt-llm.

## Summary

In https://github.com/astral-sh/uv/pull/3138 , we implemented
`unsafe-best-match`. However, it seems to not quite work as expected.
When multiple indices contain the same version, it's not clear which
index the current code uses. This PR fixes that to use the first index
the package is in.

## Test Plan

```console
$ echo 'tensorrt-llm==0.11.0' | ./target/debug/uv pip compile - --extra-index-url https://pypi.nvidia.com --python-version=3.10 --index-strategy=unsafe-best-match --annotation-style=line
```
2024-07-22 14:03:30 -04:00
Jo c52b767474
`uv init` normalize directory name (#5292)
## Summary

Resolves #5255
2024-07-22 16:09:24 +00:00
Charlie Marsh b6f470416e
Match wheel tags against `Requires-Python` major-minor (#5289)
## Summary

Given `Requires-Python: ">=3.12.3"`, we were rejecting wheels like
`dearpygui-1.11.1-cp312-cp312-win_amd64.whl`, since `3.12.0` is not
included in `>=3.12.3`. We instead need to test against the major-minor
version of `Requires-Python`.

The easiest way to do this, I think, is the use the `RequiresPython`
struct, which has a single bound that we can truncate the major-minor.
This also means that we now allow
`dearpygui-1.11.1-cp312-cp312-win_amd64.whl` for specifiers like
`Requires-Python: "==3.10.*"`. This is incorrect on the surface, but it
does match our semantics for `Requires-Python` elsewhere: we treat it as
a lower bound.

Closes https://github.com/astral-sh/uv/issues/5287.
2024-07-22 14:33:53 +00:00
Pavel Dikov 8f26f379d1
fix(pip.install.wheel): support variations on `pythonw.exe` (#5259)
Emulate `pip`'s behaviour and find `pythonw` executable by doing an
`s/python/pythonw/g` style transformation, as opposed to assuming a
constant `pythonw.exe` path.

See #5256 for more detail e.g. why this is a useful behaviour to
emulate.

Fixes: #5256
2024-07-22 10:28:20 -04:00
Charlie Marsh 479725920d
Avoid cache prune failure due to removed interpreter (#5286)
## Summary

`uv cache prune` can fail if an ephemeral environment includes a
non-existent interpreter, since we then fail to read the symlink.
2024-07-22 13:46:24 +00:00
Charlie Marsh 5a23f05799
Store resolution options in lockfile (#5264)
## Summary

This PR modifies the lockfile to include the impactful resolution
settings, like the resolution and pre-release mode. If any of those
values change, we want to ignore the existing lockfile. Otherwise,
`--resolution lowest-direct` will typically have no effect, which is
really unintuitive.

Closes https://github.com/astral-sh/uv/issues/5226.
2024-07-22 08:28:22 -04:00
Jo 178300d16b
`uv init` discovers workspace from the target path (#5250)
## Summary

Resolves #5249

## Test Plan
2024-07-22 13:43:04 +02:00
Charlie Marsh d798bb3973
Avoid always rebuilding dynamic metadata (#5206)
## Summary

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

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

Closes https://github.com/astral-sh/uv/issues/4946.
2024-07-22 00:04:03 +00:00
Di-Is 32ad3323a1
Add constraint dependencies to pyproject.toml (#5248)
Resolves #4467.

## Summary

This PR implements the following

1. Add `tool.uv.constraint-dependencies` to pyproject.toml
1. Support to refer `tool.uv.constraint-dependencies` in `uv lock`
1. Support to refer `tool.uv.constraint-dependencies` in `uv pip
compile/install`

These are analogues of the override features implemented in #3839 and
#4369.

## Test Plan

Add test.
2024-07-21 19:45:04 -04:00
Charlie Marsh a917cdba51
Fix colors in `uv tool run` suggestion (#5267)
## Summary

More consistent with other commands.

Before:

![Screenshot 2024-07-21 at 2 22
18 PM](https://github.com/user-attachments/assets/9f6dfc7d-3c54-47a4-9b9f-bdf3794ae06d)

Now: all cyan, and green command, following the style guide.
2024-07-21 23:43:27 +00:00
Charlie Marsh 5c3d55afa8
Remove unused error variant (#5266) 2024-07-21 23:38:45 +00:00
Chan Kang 12518a01a4
Implement `--show-version-specifiers` for `tree` (#5240)
## Summary
resolves https://github.com/astral-sh/uv/issues/5217

## Test Plan
existing tests pass (should be perfectly backwards compatible) + added a
few tests to cover the new functionality. in particular, in addition to
the simple use of `--show-version-specifiers`, its interaction with
`--invert` and `--package` flags are tested.
2024-07-20 18:31:16 +00:00
Jo 48921f9455
Fix `uv init` a sub-package by path (#5247)
## Summary

Resolves #5242

## Test Plan

See the [CI
failure](https://github.com/astral-sh/uv/actions/runs/10020728203/job/27698630302?pr=5247)
for the new failing test.
2024-07-20 10:47:11 -05:00
Jo 0611c7b59e
Add `uv add --no-editable` (#5246)
## Summary

Resolves #5241

## Test Plan

```sh
# create a workspace with sub-packages `pkg-a` and `pkg-b`

$ cd ./pkg-b
$ cargo run -- add ./pkg-a --no-editable

$ cat ./pyproject.toml
[project]
name = "pkg-b"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
dependencies = [
    "pkg-a",
]

[tool.uv]
dev-dependencies = []

[tool.uv.sources]
pkg-a = { workspace = true, editable = false }
```
2024-07-20 09:11:34 -04:00
Charlie Marsh 841edc3718
Move workspace abstractions to `uv-workspace` crate (#5236)
## Summary

These are really different from the rest of the existing crate as
evidenced by the bifurcation in the requirements.
2024-07-20 02:15:32 +00:00
Charlie Marsh 1243c5e28c
Avoid URL parsing when deserializing wheels (#5235)
## Summary

This PR slots in `UrlString` for `WheelWire`, which IIUC should avoid
parsing URLs during deserialization?
2024-07-20 02:11:26 +00:00
Zanie Blue 833097b93f
Bump version to 0.2.27 (#5230) 2024-07-19 22:06:49 +00:00
Ibraheem Ahmed bb73edb03b
Respect local versions for all user requirements (#5232)
## Summary

This fixes a few bugs introduced by
https://github.com/astral-sh/uv/pull/5104. I previously thought we could
track conflicting locals the same way we track conflicting URLs in
forks, but it turns out that ends up being very tricky. URL forks work
because we prioritize directly URL requirements. We can't prioritize
locals in the same way without conflicting with the URL prioritization
(this may be possible but it's not trivial), so we run into issues where
a correct resolution depends on the order in which dependencies are
traversed.

Instead, we track local versions across all forks in `Locals`. When
applying a local version, we apply all locals with markers that
intersect with the current fork. This way we end up applying some local
versions without creating a fork. For example, given:
```
// pyproject.toml
dependencies = [
    "torch==2.0.0+cu118 ; platform_machine == 'x86_64'",
]

// requirements.in
torch==2.0.0
.
```

We choose `2.0.0+cu118` in all cases. However, if a disjoint fork is
created based on local versions, the resolver will choose the most
compatible local when it narrows to a specific fork. Thus we correctly
respect local versions when forking:
```
// pyproject.toml
dependencies = [
    "torch==2.0.0+cu118 ; platform_machine == 'x86_64'",
    "torch==2.0.0+cpu ; platform_machine != 'x86_64'"
]

// requirements.in
torch==2.0.0
.
``` 

We should also be able to use a similar strategy for
https://github.com/astral-sh/uv/pull/5150.

## Test Plan

This fixes https://github.com/astral-sh/uv/issues/5220 locally for me,
as well as a few other bugs that were not reported yet.
2024-07-19 16:56:09 -05:00
Charlie Marsh a253913288
Don't apply irrelevant constraints when validating site-packages (#5231)
## Summary

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

## Test Plan

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

Prior to this change, Flask was reported as not satisfied.
2024-07-19 20:49:22 +00:00
Ahmed Ilyas 3ee3db23d6
Check `python pin` compatibility with `Requires-Python` (#4989)
## Summary

Resolves #4969 

## Test Plan

`cargo test` and manual tests.

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2024-07-19 18:17:41 +00:00
Charlie Marsh 7762d78281
Add color to `python pin` CLI (#5215)
## Summary

![Screenshot 2024-07-19 at 9 03
10 AM](https://github.com/user-attachments/assets/5668bd23-3f09-4964-bc09-9f3788f5a841)
2024-07-19 13:19:28 -04:00
Ibraheem Ahmed 12dd450a8e
Implement `uv init` (#4791)
## Summary

Implements the `uv init` command, which initializes a project
(`pyproject.toml`, `README.md`, `src/__init__.py`) in the current
directory, or in the given path. `uv init` also does workspace
discovery.

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

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2024-07-19 15:11:48 +00:00
Charlie Marsh 2169902bd9
Avoid TOCTOU errors in `.python-version` reads (#5223)
## Summary

Not a big deal, but better to try the operation and handle the failure
case than to check if the file exists and _then_ read it.
2024-07-19 15:08:20 +00:00
Charlie Marsh ed9b820815
Remove trailing period from user-facing messages (#5218)
## Summary

Per #5209, we only show periods in messages when the message itself
spans more than a single sentence.
2024-07-19 10:43:49 -04:00
Mathieu Kniewallner f2e2825d1b
docs(settings): bunch of fixes and improvements (#5177)
## Summary

Spotted some issues in the settings documentation, and room for small
improvements by linking to PEPs/RFCs.

Also updating contribution documentation to mention that it's necessary
to enable the virtual environment before running `mkdocs serve`.

## Test Plan

Running documentation locally.
2024-07-19 10:32:21 -04:00
Di-Is 0d9d559785
Change to show only the python installed on the system if `--python-preference only-system` is specified (#5219)
Fix #5211

## Summary

Change to show only the python installed on the system if
`--python-preference only-system` is specified.

Below is an example of running the command before the change, showing
Python not installed on the system.

#### Before
```bash
# Check system python
$ uv python --preview list --python-preference only-system
cpython-3.12.4-linux-x86_64-gnu     <download available>
cpython-3.12.3-linux-x86_64-gnu     /usr/bin/python3.12
cpython-3.12.3-linux-x86_64-gnu     /usr/bin/python3
cpython-3.12.3-linux-x86_64-gnu     /bin/python3.12
cpython-3.12.3-linux-x86_64-gnu     /bin/python3
cpython-3.11.9-linux-x86_64-gnu     <download available>
cpython-3.10.14-linux-x86_64-gnu    <download available>
cpython-3.9.19-linux-x86_64-gnu     <download available>
cpython-3.8.19-linux-x86_64-gnu     <download available>
cpython-3.7.9-linux-x86_64-gnu      <download available>
```

This PR changes the display to show only Python installed on the system.

#### After

```bash
$ cargo run python --preview list --python-preference only-system
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.11s
     Running `target/debug/uv python list --python-preference only-system --preview`
cpython-3.12.3-linux-x86_64-gnu    /usr/bin/python3.12
cpython-3.12.3-linux-x86_64-gnu    /usr/bin/python3
cpython-3.12.3-linux-x86_64-gnu    /bin/python3.12
cpython-3.12.3-linux-x86_64-gnu    /bin/python3
```

## Test Plan
- `cargo run python list --python-preference only-system` in Ubuntu
24.04 to verify the display.
- `cargo run python list` in Ubuntu 24.04 to verify that the results
before and after the change were the same.
2024-07-19 14:15:32 +00:00
Charlie Marsh 40b962e6bb
Fix reference to `uv run` in `uv tree` CLI (#5216) 2024-07-19 13:30:40 +00:00
Charlie Marsh 729148dac9
Add `--frozen` to `uv add`, `uv remove`, and `uv tree` (#5214)
## Summary

E.g., `uv add foo --frozen` will avoid updating or even creating a
`uv.lock`.
2024-07-19 13:18:32 +00:00
Charlie Marsh fb1a529106
Process completed Python installs and uninstalls as a stream (#5203)
## Summary

This ensures that we process Python installs and uninstalls as soon as
they complete, rather than waiting for them all to complete, then
processing them sequentially. In practice, it shouldn't be much of a
difference (since the processing is code is fairly light), but it
strikes me as more correct.
2024-07-19 12:50:38 +00:00
Danny ef56df26bf
Support `--link-mode=symlink` (#5208)
## Summary

Addressing this [issue](https://github.com/astral-sh/uv/issues/5147) by
adding the capability for Symbolic linking as a link mode when
installing or syncing dependencies.
2024-07-19 08:41:18 -04:00
Charlie Marsh bb84cbb39d
Use max rather than min to sort managed Pythons (#5205)
## Summary

See: https://github.com/astral-sh/uv/issues/5139 and
https://github.com/astral-sh/uv/pull/5201#discussion_r1683636935.

## Test Plan

Verified that 3.12 was chosen above 3.8 in:

- `cargo run -- python uninstall --all`
- `cargo run -- python install 3.8 3.12`
- `cargo run -- tool run -v httpx`
2024-07-19 12:35:17 +00:00
konsti 93ba676f2e
Log origin of version selection (#5186)
Log whether a version was picked because it was the next version or
because it was a preference (installed, lockfile or sibling fork)
2024-07-19 08:15:45 +00:00
Charlie Marsh d54ae4e381
Use +- install output for Python versions (#5201)
## Summary

Follow-up to https://github.com/astral-sh/uv/pull/4939. Uses a format
that's closer to `uv pip install`, with some special-casing for single
Pythons.

## Test Plan

A few examples:

![Screenshot 2024-07-18 at 8 39
35 PM](https://github.com/user-attachments/assets/868d4c87-d8f4-4e5f-a52c-1f7a3e8d6a16)
![Screenshot 2024-07-18 at 8 39
46 PM](https://github.com/user-attachments/assets/3a12461e-9d9b-4c33-a685-55ca7256ff52)
![Screenshot 2024-07-18 at 8 39
27 PM](https://github.com/user-attachments/assets/1059e6d6-a445-4531-8496-59bc51d01663)
![Screenshot 2024-07-18 at 8 39
54 PM](https://github.com/user-attachments/assets/dcb69e86-8702-402b-a0cd-6f827b04a6ab)
2024-07-18 20:46:33 -04:00
Charlie Marsh 5d6f793101
Make Python install robust to individual failures (#5199)
## Summary

We have roughly this code for uninstalls, but for installs, we eject as
soon as we hit a failure, leaving some things in a partial state.
2024-07-18 20:31:54 -04:00
Tim Felgentreff 24a0268675
Add GraalPy support (#5141)
<!--
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

Currently, `uv` refuses to install anything on GraalPy. This is
currently blocking GraalPy testing with cibuildwheel, since manylinux
includes both `uv` and `graalpy` (but doesn't test with `uv`), whereas
cibuildwheel defaults to `uv`. See e.g.
https://github.com/pypa/cibuildwheel/actions/runs/9956369360/job/27506182952?pr=1538
where it gives
```
      + python -m build /project/sample_proj --wheel --outdir=/tmp/cibuildwheel/built_wheel --installer=uv
  * Creating isolated environment: venv+uv...
  * Using external uv from /usr/local/bin/uv
  * Installing packages in isolated environment:
    - setuptools >= 40.8.0
  > /usr/local/bin/uv pip install "setuptools >= 40.8.0"
  < error: Unknown implementation: `graalpy`
```

## Test Plan

I simply based the GraalPy support on PyPy and added some small tests.
I'm open to discussing how to test this. GraalPy is available for
manylinux images and with setup-python, so we should be able to add
tests against it to the CI. I locally confirmed by installing `uv` into
a GraalPy venv and then trying things like `uv pip install Pillow` and
testing those extensions.
2024-07-18 19:28:28 -05:00
Charlie Marsh 54bca18184
Use `which`-retrieved path directly when spawning pager (#5198)
## Summary

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

## Test Plan

Ran `cargo run -- help pip compile` on my Windows machine, which failed
before but succeeds after this change.
2024-07-18 20:29:00 +00:00
Charlie Marsh dfe2faa71e
Add `--locked` and `--frozen` to `uv run` CLI (#5196)
## Summary

You can now use `uv run --locked` to assert that the lockfile doesn't
change, or `uv run --frozen` to run without attempting to update the
lockfile at all.

Closes https://github.com/astral-sh/uv/issues/5185.
2024-07-18 18:55:17 +00:00
Charlie Marsh 6a6e3b464f
Make missing project table a tracing warning (#5194)
Closes https://github.com/astral-sh/uv/issues/5068.
2024-07-18 18:21:39 +00:00
konsti 5bcdaedf8b
Merge extras in lockfile (#5181)
As user, you specify a list of extras. Internally, we decompose this
into one virtual package per extra. We currently leak this abstraction
by writing one entry per extra to the lockfile:

```toml
[[distribution]]
name = "foo"
version = "4.39.0.dev0"
source = { editable = "." }
dependencies = [
    { name = "pandas" },
    { name = "pandas", extra = "excel" },
    { name = "pandas", extra = "hdf5" },
    { name = "pandas", extra = "html", marker = "os_name != 'posix'" },
    { name = "pandas", extra = "output-formatting", marker = "os_name == 'posix'" },
    { name = "pandas", extra = "plot", marker = "os_name == 'posix'" },
]
```

Instead, we should merge the extras into a list of extras, creating a
more concise lockfile:

```toml
[[distribution]]
name = "foo"
version = "4.39.0.dev0"
source = { editable = "." }
dependencies = [
    { name = "pandas", extra = ["excel", "hdf5"] },
    { name = "pandas", extra = ["html"], marker = "os_name != 'posix'" },
    { name = "pandas", extra = ["output-formatting", "plot"], marker = "os_name == 'posix'" },
]
```

The base package is now implicitly included, as it is in PEP 508.

Fixes #4888
2024-07-18 14:07:49 -04:00
Charlie Marsh 4a875afc07
Skip invalid tools in `uv tool list` (#5156)
## Summary

Makes the `tools()` return value include per-tool errors. This makes it
easy to skip (rather than failing) in `uv tool list`, _and_ improves `uv
tool uninstall` to remove those invalid tools, rather than leaving them
around. (We already had that behavior for `uv tool uninstall ruff` with
an invalid `ruff`, but `uv tool uninstall --all` just left them.)

Closes https://github.com/astral-sh/uv/issues/5151.
2024-07-18 17:56:40 +00:00
Ibraheem Ahmed bbd65fc626
Set exact version specifiers when resolving from lockfile (#5193)
## Summary

Should resolve https://github.com/astral-sh/uv/issues/5192.

## Test Plan

@konstin can you confirm this fixes your issue?
2024-07-18 19:02:08 +02:00
konsti 7beae77283
Search for all `python3.x` in PATH (#5148)
Search for all `python3.x` minor versions in PATH, skipping those we
already know we can use.

For example, let's say `python` and `python3` are Python 3.10. When a
user requests `>= 3.11`, we still need to find a `python3.12` in PATH.
We do so with a regex matcher.

Fixes #4709
2024-07-18 17:00:01 +02:00
Charlie Marsh 36a0ee9822
Remove executable alias; import anstream (#5187)
Post-push review from https://github.com/astral-sh/uv/pull/5160.
2024-07-18 14:09:29 +00:00
Charlie Marsh 8484611753
Rename `Error::IO` to `Error::Io` (#5174)
## Summary

I believe this is by convention (see, e.g., in Rust itself:
https://github.com/search?q=repo%3Arust-lang%2Frust+%2F%28%3F-i%29Io%2F&type=code).
2024-07-18 04:13:45 +00:00
konsti fbb00f701c
Warn about unconstrained direct deps in lowest resolution (#5142)
Warn when there is a direct dependency without a lower bound and
`--resolution lowest` is set.

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2024-07-18 03:44:53 +00:00
Charlie Marsh 4f73004f95
Remove 'bare' vernacular from virtualenv crate (#5175)
## Summary

"Bare" made sense when we had a variant that seeded the environment, but
now that the crate _only_ creates a bare environment, lets drop that
terminology.
2024-07-18 02:11:16 +00:00
Charlie Marsh 564f4b2958
Use display representation for download error (#5173)
## Summary

Turns out we already have display for this.

Closes https://github.com/astral-sh/uv/issues/4914.
2024-07-18 02:05:17 +00:00
Charlie Marsh 91bf213641
Use specialized error message for invalid Python install / uninstall requests (#5171)
## Summary

Closes https://github.com/astral-sh/uv/issues/4819.
2024-07-17 20:47:55 -04:00
Charlie Marsh 622e9e8799
Add `uv tool list --show-paths` to show install paths (#5164)
## Summary

Closes https://github.com/astral-sh/uv/issues/4823.
2024-07-17 19:11:13 -04:00
Charlie Marsh 6a49dba30c
Enforce hashes in lockfile install (#5170)
## Summary

Hashes will be validated if present, but aren't required (since, e.g.,
some registries will omit them, as will Git dependencies and such).

Closes https://github.com/astral-sh/uv/issues/5168.
2024-07-17 23:10:37 +00:00
Charlie Marsh 218ae2c13e
Key hash policy on version, rather than package (#5169)
## Summary

First part of: https://github.com/astral-sh/uv/issues/5168.
2024-07-17 19:01:49 -04:00
Charlie Marsh 82d94838cb
Implement a `--verify-hashes` hash-checking mode (#4007)
## Summary

This is an alternative to `--require-hashes` which will validate a hash
if it's present, but ignore requirements that omit hashes or are absent
from the lockfile entirely.

So, e.g., transitive dependencies that are missing will _not_ error; nor
will dependencies that are included but lack a hash.

Closes https://github.com/astral-sh/uv/issues/3305.
2024-07-17 21:25:31 +00:00
Charlie Marsh ba4e2e3d2a
Use the strongest hash in the lockfile (#5167)
## Summary

We only need to store one hash -- it should be the "strongest" hash. In
practice, most registries (like PyPI) only serve one, and we only
compute a SHA256 hash for direct URLs.

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

## Test Plan

I verified that changing:

```diff
diff --git a/crates/distribution-types/src/hash.rs b/crates/distribution-types/src/hash.rs
index 553a74f55..d36c62286 100644
--- a/crates/distribution-types/src/hash.rs
+++ b/crates/distribution-types/src/hash.rs
@@ -31,7 +31,7 @@ impl<'a> HashPolicy<'a> {
     pub fn algorithms(&self) -> Vec<HashAlgorithm> {
         match self {
             Self::None => vec![],
-            Self::Generate => vec![HashAlgorithm::Sha256],
+            Self::Generate => vec![HashAlgorithm::Sha256, HashAlgorithm::Sha512],
             Self::Validate(hashes) => {
                 let mut algorithms = hashes.iter().map(HashDigest::algorithm).collect::<Vec<_>>();
                 algorithms.sort();
```

Then running `uv lock` with a URL gave me:

```toml
[[distribution]]
name = "iniconfig"
version = "2.0.0"
source = { url = "62565a6e1ceac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl" }
wheels = [
    { url = "62565a6e1ceac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha512:44cc53a6c8dd7cf4d6d52bded308bcc4b4f85fff2ed081f60f7d4beaa86a7cde6d099e3976331232d4cbd472ad5d1781064725b0999c7cd3a2a4d42df687ee81" },
]
```
2024-07-17 20:38:33 +00:00
Charlie Marsh eb24717a9b
Add `uv tool dir --bin` to show executable directory (#5160)
## Summary

Closes https://github.com/astral-sh/uv/issues/5159.
2024-07-17 16:30:45 -04:00
Charlie Marsh e271d1fdde
Make registry hashes optional in the lockfile (#5166)
## Summary

If a registry doesn't include hashes, then we won't include them in the
lockfile either.

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

Closes: https://github.com/astral-sh/uv/issues/5120.
2024-07-17 16:29:49 -04:00
Charlie Marsh 8edfdbed77
Make entrypoint writes atomic to avoid overwriting symlinks (#5165)
## Summary

It turns out that if `path` is a symlink,
`File::create(path)?.write_all(content.as_ref())?` will overwrite the
_target_ file. That means an entrypoint named `python` would actually
overwrite the user's source Python executable, which is symlinked into
the virtual environment.

This PR replaces that code with our atomic write method.

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

## Test Plan

I ran through the test plan
`https://github.com/astral-sh/uv/issues/5152`, but used an executable
named `bar` linked to `foo.txt` instead...
2024-07-17 19:44:26 +00:00
konsti a6dfd3953a
Handle universal vs. fork markers with `ResolverMarkers` (#5099)
* Use a dedicated `ResolverMarkers` check in the fork state. This is
better than the `MarkerTree::And(Vec::new())` check.
* Report the timing correct naming universal resolution instead of two
spaces around an empty string when there are no markers.
* On resolution error, show the split that we're in. I'm not sure how to
word this, since we're doing a universal resolution until we fork, so
the trace may contain information from requirements that are not part of
this fork.
2024-07-17 18:59:33 +02:00
Charlie Marsh fe403576c5
Bump version to v0.2.26 (#5149) 2024-07-17 12:51:11 -04:00
Charlie Marsh a191f84929
Autogenerate possible values for enums in reference documentation (#5137)
## Summary

For example:

![Screenshot 2024-07-16 at 7 44
10 PM](https://github.com/user-attachments/assets/73ce16ba-eb0e-43c4-a741-65a54637452f)

Closes https://github.com/astral-sh/uv/issues/5129.
2024-07-17 12:37:33 -04:00
konsti 3e93255ac9
Document that `--universal` implies `--no-strip-markers` (#5121)
Prompted by
https://github.com/python-trio/trio/pull/3032#discussion_r1679435422.
2024-07-17 15:54:21 +00:00
Jo 0acb6165dc
Sort `ManagedPythonInstallation` by version (#5140)
## Summary
Resolves #5139

`PythonInstallationKey` was sorted as a string, which caused `3.8` to
appear before `3.11`. This update changes the sorting of
`PythonInstallationKey` to be a descending order by version.

## Test Plan
```sh
$ cargo run -- python install 3.8 3.12
$ cargo run -- tool run -v python -V
DEBUG uv 0.2.25
warning: `uv tool run` is experimental and may change without warning.
DEBUG Searching for Python interpreter in managed installations, system path, or `py` launcher
DEBUG Searching for managed installations at `C:\Users\xx\AppData\Roaming\uv\data\python`
DEBUG Found managed Python `cpython-3.12.3-windows-x86_64-none`
DEBUG Found cpython 3.12.3 at `C:\Users\xx\AppData\Roaming\uv\data\python\cpython-3.12.3-windows-x86_64-none\install\python.exe` (managed installations)
DEBUG Using request timeout of 30s
DEBUG Using request timeout of 30s
DEBUG Acquired lock for `C:\Users\nigel\AppData\Roaming\uv\data\tools`
DEBUG Using existing environment for tool `httpx`: C:\Users\xx\AppData\Roaming\uv\data\tools\httpx
DEBUG Using existing tool `httpx`
DEBUG Running `httpx -v`
```
2024-07-17 09:48:04 -05:00
Ahmed Ilyas eb35c05b89
Indicate that `uv lock --upgrade` has updated the lock file (#5110)
## Summary

Resolves #4346, I've gone with the suggested `cargo` approach here.

## Test Plan

`cargo test`

```console
❯ ../target/debug/uv lock --upgrade
warning: `uv lock` is experimental and may change without warning.
Resolved 11 packages in 41ms
Updating flask v2.3.3 -> v3.0.3
note: pass `--verbose` to see 9 unchanged dependencies
❯ ../target/debug/uv lock --upgrade -vv
    0.002478s DEBUG uv uv 0.2.24
warning: `uv lock` is experimental and may change without warning.
....
Resolved 11 packages in 50ms
    0.103703s DEBUG uv::commands::project::lock Unchanged blinker v1.8.2
    0.103719s DEBUG uv::commands::project::lock Unchanged click v8.1.7
    0.103731s DEBUG uv::commands::project::lock Unchanged colorama v0.4.6
    0.103742s DEBUG uv::commands::project::lock Unchanged flask v3.0.3
    0.103754s DEBUG uv::commands::project::lock Unchanged importlib-metadata v8.0.0
    0.103767s DEBUG uv::commands::project::lock Unchanged itsdangerous v2.2.0
    0.103778s DEBUG uv::commands::project::lock Unchanged jinja2 v3.1.4
    0.103788s DEBUG uv::commands::project::lock Unchanged markupsafe v2.1.5
    0.103798s DEBUG uv::commands::project::lock Unchanged werkzeug v3.0.3
    0.103809s DEBUG uv::commands::project::lock Unchanged zipp v3.19.2
```
2024-07-17 01:14:20 +00:00
Silvano Cerza 426736f7ed
Add `--no-progress` global option to hide all progress animations (#5098)
## Summary

Fixes #5082.

Adds a new `Printer::NoProgress` that is identical to `Printer::Default`
but doesn't draw any progress bar.

## Test Plan

It seems to me that as of now it's not possible to use `insta-cmd` to
get any progress bar in the comparable output of command.

Best way to test this would be to run any command that usually shows
progress indicators like `uv pip install` with and without
`--no-progress` options.
2024-07-16 16:48:57 -05:00
Charlie Marsh 7211e62132
Add reference documentation for pip settings (#5125)
## Summary

Third part of https://github.com/astral-sh/uv/issues/5093.
2024-07-16 21:14:27 +00:00
Charlie Marsh f7c52fdbfb
Add reference documentation for global settings (#5123)
## Summary

Second part of: https://github.com/astral-sh/uv/issues/5093.
2024-07-16 20:50:04 +00:00
Charlie Marsh 616a61a244
Add reference documentation for resolver settings (#5122)
## Summary

First part of https://github.com/astral-sh/uv/issues/5093.

Remaining:

- Global settings
- `pip`-specific settings (some will be copied-over from here)
- Auto-generating the "Possible values" for enums
2024-07-16 16:39:22 -04:00
konsti abb6ac5127
Support workspace to workspace path dependencies (#4833)
Add support for path dependencies from a package in one workspace to a
package in another workspace, which it self has workspace dependencies.

Say we have a main workspace with packages `a` and `b`, and a second
workspace with `c` and `d`. We have `a -> b`, `b -> c`, `c -> d`. This
would previously lead to a mangled path for `d`, which is now fixed.

Like distribution paths, we split workspace paths into an absolute
install path and a relative (or absolute, if the user provided an
absolute path) lock path.

Part of https://github.com/astral-sh/uv/issues/3943
2024-07-16 20:38:46 +00:00
Ivan Shcheklein b5ec859273
fix(git): lock cache on resolve (#5051)
Fixes a concurrency issue when multiple processes are installing the
same package in different virtual environments from Git ref (not a
specific Git commit).

## Symptoms

That's how some of symptoms looked like in our case:

```
DEBUG uv 0.2.21
DEBUG Checking for Python interpreter at path `/tmp/pytest-of-runner/pytest-0/tmp_venv_dir/python3.12/37bf51bfba4699a940ce31349422b24a5bc55a2b179ed7aec74459a9ae8d57b7/bin/python`
DEBUG Using Python 3.12.4 environment at /tmp/pytest-of-runner/pytest-0/tmp_venv_dir/python3.12/37bf51bfba4699a940ce31349422b24a5bc55a2b179ed7aec74459a9ae8d57b7/bin/python
DEBUG Acquired lock for `/tmp/pytest-of-runner/pytest-0/tmp_venv_dir/python3.12/37bf51bfba4699a940ce31349422b24a5bc55a2b179ed7aec74459a9ae8d57b7`
DEBUG At least one requirement is not satisfied: torch
DEBUG Using request timeout of 300s
DEBUG Found 37 packages in `--find-links` entry: /tmp/pytest-of-runner/pytest-0/tmp_venv_dir/python3.12/.cache/pip/wheels
DEBUG Updating git source `Url { scheme: "https", cannot_be_a_base: false, username: "***", password: None, host: Some(Domain("github.com")), port: None, path: "/iterative/datachain", query: None, fragment: None }`
DEBUG Attempting GitHub fast path for: https://api.github.com/repos/iterative/datachain/commits/fix-distributed-test
DEBUG failed to check github HTTP status client error (404 Not Found) for url (https://api.github.com/repos/iterative/datachain/commits/fix-distributed-test)
DEBUG Performing a Git fetch for: https://***@github.com/iterative/datachain
error: Failed to download and build: `datachain @ git+https://***@github.com/iterative/datachain@fix-distributed-test`
Caused by: Git operation failed
Caused by: process didn't exit successfully: `git clone --local /tmp/pytest-of-runner/pytest-0/tmp_venv_dir/python3.12/.cache/uv/git-v0/db/9d45a3e6f56b0a69 /tmp/pytest-of-runner/pytest-0/tmp_venv_dir/python3.12/.cache/uv/git-v0/checkouts/9d45a3e6f56b0a69/56b15b8` (exit status: 128)
--- stderr
fatal: destination path '/tmp/pytest-of-runner/pytest-0/tmp_venv_dir/python3.12/.cache/uv/git-v0/checkouts/9d45a3e6f56b0a69/56b15b8' already exists and is not an empty directory.
```

## Cause of the issue

It is the same command that is failing - `git clone`, and I think it's
happening because it was trying to first get the repo to dereference the
`fix-distributed-test` branch:

`Given a remote source distribution, return a precise variant, if
possible.`

And it's happening w/i acquiring a lock around cache.

## Fix

I thinks we can reuse the existing `fetch` method that has already lock
around cache:


https://github.com/astral-sh/uv/pull/5051/files#diff-f58bb99dee2c4922d156ace3e7de651f0d9a81fc8e9447a2ad865de5c53543fcR61-R68

```python
        // Avoid races between different processes, too.
        let lock_dir = cache.join("locks");
        ....
```

## Questions

- Are there any tests that cover concurrency? I'm quite new to Rust and
if someone can point me to some examples and I can create a similar test
or a new one.
- Is error handling done correctly in this PR (again, I'm new to Rust -
I'll review and read about it, but it's better also for someone else to
review this)
2024-07-16 16:06:06 -04:00
Ibraheem Ahmed d583847f8b
Allow conflicting locals when forking (#5104)
## Summary

Currently, the `Locals` type relies on there being a single local
version for a given package. With marker expressions this may not be
true, a similar problem to https://github.com/astral-sh/uv/pull/4435.
This changes the `Locals` type to `ForkLocals`, which tracks locals for
a given fork. Local versions are now tracked on `PubGrubRequirement`
before forking.

Resolves https://github.com/astral-sh/uv/issues/4580.
2024-07-16 16:57:30 +00:00
Andrew Gallant 048ae8f7f3 uv-resolver: add TRACE dump of resolver output
Specifically, this shows the resolution produced by the
resolver *before* constructing a resolution graph.

Unlike most trace messages, this is a multi-line message
that needs to do some small amount of work to build
itself. So we do an explicit gating on the log level here
instead of just relying on the `trace!` macro itself.
2024-07-16 09:51:54 -07:00
skshetry e2dfab771a
pip compile: change order of check to handle exact argument first (#5111)
I messed up the order of checks in #5033, due to which it failed to
exclude the case of `-P package`, as `arg.startswith("-P")` check came
first and skipped only the first argument.

That means that, in the following command:
```console
uv pip compile --output-file pip_compile_uv_header.txt unpinned_uv.in -P attrs==18.1.0
```

The generated header would exclude `-P`, but keep `attrs==18.1.0`.

```plaintext
# This file was autogenerated by uv via the following command:
#    uv pip compile --output-file pip_compile_uv_header.txt unpinned_uv.in attrs==18.1.0
```

But we want to check for an exact match first and then only check for
the case when option and value are together.

This also affected `--find-links` short option of style `-f <uri>`.


Hopefully, third times going to be a charm. 😳 


<!--
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? -->

## Test Plan

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

I tested locally, and also changed one snapshot test to use `-P` for
variation. I don't think it's worth an extra test, but can do that for
sure.
2024-07-16 12:46:02 -04:00
Charlie Marsh 6d0e6eea6f
Fix depth of settings headers (#5103)
Closes https://github.com/astral-sh/uv/issues/5092.
2024-07-16 14:00:03 +00:00
Charlie Marsh 2ff3b380b1
Cache downloaded wheel when range requests aren't supported (#5089)
## Summary

When range requests aren't supported, we fall back to streaming the
wheel, stopping as soon as we hit a `METADATA` file. This is a small
optimization, but the downside is that we don't get to cache the
resulting wheel...

We don't know whether `METADATA` will be at the beginning or end of the
wheel, but it _seems_ like a better tradeoff to download and cache the
entire wheel?

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

Sort of a revert of: https://github.com/astral-sh/uv/pull/1792.
2024-07-16 09:21:47 -04:00
messense 38504dcaee
Download wheel to disk when streaming unzip failed with HTTP streaming error (#5094)
## Summary

Workaround the `stream_wheel` not retry issue
[found](https://github.com/astral-sh/uv/issues/3514#issuecomment-2229820667)
in #3514, it's not a perfect solution but I think it's acceptable
because the error should not occur frequently.

## Test Plan

Manually using `iptables -A OUTPUT -p tcp -dport 3128 -j REJECT
--reject-with tcp-reset` to inject connection reset error to the HTTP
proxy that proxies PyPI requests.

```
error: Failed to prepare distributions
  Caused by: Failed to fetch wheel: piqp==0.4.1
  Caused by: Request failed after 3 retries
  Caused by: error sending request for url (09ade94dfdd3c368ac505b6ca09831/piqp-0.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl)
  Caused by: client error (Connect)
  Caused by: tcp connect error: Connection refused (os error 111)
  Caused by: Connection refused (os error 111)
```
2024-07-16 09:00:46 -04:00
Charlie Marsh 816d70cd23
Filter out none ABI wheels with mismatched Python versions (#5087)
## Summary

`echo "torch==1.10.0" | cargo run pip compile - -p 3.12 --no-deps` now
correctly fails. Previously, we were accepting the wheel
`torch-1.10.0-cp36-none-macosx_10_9_x86_64.whl` as compatible with
Python 3.10 due to the `none` ABI.

Closes https://github.com/astral-sh/uv/issues/5085.
2024-07-15 21:41:13 -04:00
Charlie Marsh 9a44bc1d35
Filter out invalid wheels based on `requires-python` (#5084)
## Summary

The example in the linked issue doesn't quite work, but I think it has
to do with the existing filtering logic. Will follow-up separately.

Closes https://github.com/astral-sh/uv/issues/5012.
2024-07-15 21:01:38 -04:00
Alexander Gherm 14a1ea460d
Rework reformatting in PyProjectTomlMut to respect original indentation (#5075)
## Summary

So this PR introduces change to how `Array` of dependencies
representation is reformatted while `PyProjectTomlMut` is manipulated.
These changes are here for it to respect the original indentation.
Closes https://github.com/astral-sh/uv/issues/5009

## Test Plan
Using `pyproject.toml` like
```
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
  "requests"
]
```
Executed 
```
$ uv add httpx
```
And expected in `pyproject.toml`
```
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
  "requests",
  "httpx",
]
```
Preserving original indentation
2024-07-15 19:13:22 -04:00
Charlie Marsh d1010228b3
Bump version to v0.2.25 (#5083) 2024-07-15 22:38:59 +00:00
Charlie Marsh 41cd4bee58
Add a `generate-all` step and auto-generate `settings.md` (#5080)
## Summary

Ensures that `generate-all` generates both the JSON Schema and the
`settings.md` API reference.
2024-07-15 19:58:53 +00:00
Charlie Marsh 6275b54d51
Generate API reference for options documentation (#5072)
## Summary

Generates Markdown from the `OptionsMetadata`, following the same
strategy as in Ruff.

## Test Plan

`cargo dev generate-options-reference`
2024-07-15 19:48:40 +00:00
Zanie Blue 1b1eba12c7
Rename "built-wheels" cache bucket to "source-dists" (#5077)
This name should lead to less confusion. Unfortunately this is a
"breaking cache change" so everyone's cache will be invalidated. I'm not
sure if we should support a rename-on-upgrade.

edit: We can make the breaking change next time we bump the version
2024-07-15 14:41:03 -05:00
Ahmed Ilyas 492e778fe7
`uvx` warn when executable is not part of `--from PKG` (#5071)
## Summary

Resolves #5017.

Note: This re-uses the same function defined in #5019 to find matching
packages.

## Test Plan

`cargo test`

```console
❯ ./target/debug/uvx --from fastapi fastapi
warning: `uvx` is experimental and may change without warning.
Resolved 33 packages in 427ms
warning: The fastapi executable is not part of the fastapi package. It is provided by the fastapi-cli package. Use `uvx --from fastapi-cli fastapi` instead.
Usage: fastapi [OPTIONS] COMMAND [ARGS]...
Try 'fastapi --help' for help.
```

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2024-07-15 19:27:10 +00:00
Charlie Marsh 8c0ad5b75e
Add `OptionsMetadata` macro to uv (#5063)
## Summary

The bulk of the change is copied directly from Ruff:

-
dc8db1afb0/crates/ruff_workspace/src/options_base.rs
-
dc8db1afb0/crates/ruff_macros/src/config.rs
2024-07-15 19:24:08 +00:00
Silvano Cerza c2ef825d7b
Add `pypy` executables when calling `uv venv` (#5047)
## Summary

Should fix #2092.

This PR changes `uv venv` so it also creates symlinks to `pypy` on Unix
and copies executables on Windows when creating a new environment using
PyPy.

I found a bit of discrepancy between creation of a venv using `python`
and `uv`, as using `python` brings all the executables with it. While
`uv` brings only those without any version number, at least on Windows.
The behaviour is different on Unix as we take the versioned symlinks
too.

Some examples below.

`python -m venv` generates the following `Scripts` folder.
```
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         7/14/2024     15:41           2031 activate
-a----         7/14/2024     15:41           1029 activate.bat
-a----         7/14/2024     15:41           9033 Activate.ps1
-a----         7/14/2024     15:41            393 deactivate.bat
-a----         7/14/2024     15:40          27648 libffi-8.dll
-a----         7/14/2024     15:41       44290560 libpypy3.10-c.dll
-a----         7/14/2024     15:41         108424 pip.exe
-a----         7/14/2024     15:41         108424 pip3.10.exe
-a----         7/14/2024     15:41         108424 pip3.exe
-a----         7/14/2024     15:41          79360 pypy.exe
-a----         7/14/2024     15:41          79360 pypy3.10.exe
-a----         7/14/2024     15:41          79360 pypy3.10w.exe
-a----         7/14/2024     15:41          79360 pypy3.exe
-a----         7/14/2024     15:41          79360 pypyw.exe
-a----         7/14/2024     15:41          79360 python.exe
-a----         7/14/2024     15:41          79360 python3.10.exe
-a----         7/14/2024     15:41          79360 python3.exe
-a----         7/14/2024     15:41          79360 pythonw.exe
```

`uv venv` instead generates this. 
```
-a----         7/14/2024     16:27           3360 activate
-a----         7/14/2024     16:27           2251 activate.bat
-a----         7/14/2024     16:27           2627 activate.csh
-a----         7/14/2024     16:27           4191 activate.fish
-a----         7/14/2024     16:27           3875 activate.nu
-a----         7/14/2024     16:27           2766 activate.ps1
-a----         7/14/2024     16:27           2378 activate_this.py
-a----         7/14/2024     16:27           1728 deactivate.bat
-a----         7/13/2024     19:19          27648 libffi-8.dll
-a----         7/13/2024     19:19       44290560 libpypy3.10-c.dll
-a----         7/14/2024     16:27           1215 pydoc.bat
-a----         7/13/2024     19:19          79360 pypy.exe
-a----         7/13/2024     19:19          79360 pypyw.exe
-a----         7/13/2024     19:19          79360 python.exe
-a----         7/13/2024     19:19          79360 pythonw.exe
```

## Test Plan

To verify the correct behaviour:

1. Download and install PyPy from [official
website](https://www.pypy.org/download.html)
2. Call `uv venv -p <path_to_pypy_>`
3. Run `.\.venv\Scripts\activate` on Windows or
`./.venv/Scripts/activate` on Unix
4. Run `pypy`

I thought of writing some automated tests but I couldn't rely on `uv
python install` command to install PyPy as it's not in the list of
installable Python builds.
2024-07-15 13:28:31 -05:00
Zanie Blue dab7fc7e9f
Retry on permission errors when persisting extracted source distributions to the cache (#5076)
Another case for https://github.com/astral-sh/uv/issues/1491

ref #4606
2024-07-15 12:56:07 -05:00
Andrew Gallant 563507edba uv-resolver: add support for incomplete markers
In some cases, it's possible for the marker expressions on conflicting
dependency specification to be disjoint but *incomplete*. That is, if
one unions the disjoint markers, the result is not the complete set of
marker environments possible. There may be some "gap" of marker
environments not covered by the markers.

This is a problem in practice because, before this commit, we only
created forks in the resolver for specific marker expressions. So if a
dependency happened to fall in a "gap," our resolver would never see it.

This commit fixes this by adding a new split covering the negation of
the union of all marker expressions in a set of forks for a specific
package.

Originally, I had planned on only creating this split when it was known
that the gap actually existed. That is, when the negation of the marker
expressions did *not* correspond to the empty set. After a lot of
thought, unfortunately, this (I believe) effectively boils down to 3SAT,
which is NP-complete.

Instead, what we do here is *always* create an extra split unless we can
definitively tell that it is empty. We look for a few cases, but
otherwise throw our hands up and potentially do wasted work.

This also updates the lock scenario tests to reflect the actual bug fix
here.
2024-07-15 10:09:01 -07:00
Andrew Gallant f36f2f41ac uv/tests: update packse tests for packse 0.3.30
An important update here is the new `fork-incomplete-markers` test.
The snapshot saved here is actually wrong; it is the bug we want to
fix. In particular, it is missing a dependency on `c` in its lock file
because it falls into a gap created by incomplete-but-disjoint marker
expressions.
2024-07-15 10:09:01 -07:00
Ahmed Ilyas 493a2bfe63
`uv tool install` hint the correct when the executable is available (#5019)
## Summary

Resolves #5018.

## Test Plan

`cargo test`

<img width="704" alt="Screenshot 2024-07-12 at 22 16 53"
src="https://github.com/user-attachments/assets/d2d4d85b-d6c3-4b47-8f1a-bb07112d5931">

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2024-07-15 16:54:39 +00:00
konsti e34ab96e80
Remove special casing from no solution error (#5067)
The only pubgrub error that can occur is a `NoSolutionError`, and the
only place it can occur is `unit_propagation`, all other variants if
`PubGrubError` are unreachable. By changing the return type on pubgrub's
side (https://github.com/astral-sh/pubgrub/pull/28), we can remove the
pattern matching and the `unreachable!()` asserts on `PubGrubError`.

Our pubgrub error wrapper used to have a two phased initialization,
first mostly stubs in `solve[_tracked]()` and then adding the actual
context in `resolve()`. When constructing the error in `solve` we
already have all this context, so we can unify this to a regular
constructor and remove the special casing in `resolve()` and `hints()`.
2024-07-15 17:43:35 +02:00
konsti 00c055a6bd
Use correct pyproject.toml path in warnings (#5069)
One part of #5068. I think the other is not warning when the version is
dynamic, but this fix is needed either way.
2024-07-15 11:15:58 +00:00
renovate[bot] 97d2a7c567
Update Rust crate tikv-jemallocator to 0.6.0 (#5058) 2024-07-14 20:39:50 -04:00
konsti f3430c3a2a
Improve error message when package has no installation candidates (#5010)
Currently, with
```toml
[project]
name = "transformers"
version = "4.39.0.dev0"
requires-python = ">=3.10"
dependencies = [
  "torch==1.10.0"
]
```
i get
```
$ uv sync --preview
Resolved 3 packages in 7ms
error: found distribution torch==1.10.0 @ registry+https://pypi.org/simple with neither wheels nor source distribution
```
This error message is wrong, there are wheels, they are just not
compatible. I initially got this error message during `uv lock` (in a
build), so i also added that this is about installation, not about
locking.

We should reject this version immediately because with the current
requires python, it can never be installed, but even then we need to
change the error message because you can be on the correct python
version, but an unsupported platform.
2024-07-15 00:00:40 +00:00
Charlie Marsh a571150949
Normalize out complementary == or != markers (#5050)
## Summary

Closes https://github.com/astral-sh/uv/issues/5044.
2024-07-14 23:53:58 +00:00
konsti 04c96c8df8
Remove non-existent feature (#5049)
Nightly rustc is complaining about this.
2024-07-14 19:49:22 -04:00
Di-Is 720ae195a1
Respect the libc of the execution environment with `uv python list` (#5036)
Fix #4988

## Summary

Running `uv python list` on glibc-based Linux will list musl pythons.

```bash
$ uv version
uv 0.2.24
$ uv python list
warning: `uv python list` is experimental and may change without warning.
cpython-3.12.3-linux-x86_64-musl     <download available>
cpython-3.12.3-linux-x86_64-gnu      /usr/bin/python3
cpython-3.12.3-linux-x86_64-gnu      /bin/python3
cpython-3.11.9-linux-x86_64-musl     <download available>
cpython-3.10.14-linux-x86_64-musl    <download available>
cpython-3.9.19-linux-x86_64-musl     <download available>
cpython-3.8.19-linux-x86_64-musl     <download available>
cpython-3.7.9-linux-x86_64-musl      <download available>
```

Change it to show Python matching the environment's libc as follows.

```bash
$ uv python list
warning: `uv python list` is experimental and may change without warning.
cpython-3.12.3-linux-x86_64-gnu     /usr/bin/python3
cpython-3.12.3-linux-x86_64-gnu     /bin/python3
cpython-3.12.3-linux-x86_64-gnu     <download available>
cpython-3.11.9-linux-x86_64-gnu     <download available>
cpython-3.10.14-linux-x86_64-gnu    <download available>
cpython-3.9.19-linux-x86_64-gnu     <download available>
cpython-3.8.19-linux-x86_64-gnu     <download available>
cpython-3.7.9-linux-x86_64-gnu      <download available>
```

Also, if --all-platforms is specified, change to list Python for all
architectures and libc.

```bash
$ uv python list --all-platforms
warning: `uv python list` is experimental and may change without warning.
cpython-3.12.3-windows-x86_64-none       <download available>
cpython-3.12.3-windows-x86-none          <download available>
cpython-3.12.3-macos-x86_64-none         <download available>
cpython-3.12.3-macos-aarch64-none        <download available>
cpython-3.12.3-linux-x86_64-musl         <download available>
cpython-3.12.3-linux-x86_64-gnu          /usr/bin/python3
cpython-3.12.3-linux-x86_64-gnu          /bin/python3
cpython-3.12.3-linux-x86_64-gnu          <download available>
cpython-3.12.3-linux-s390x-gnu           <download available>
cpython-3.12.3-linux-powerpc64le-gnu     <download available>
cpython-3.12.3-linux-armv7-gnueabihf     <download available>
cpython-3.12.3-linux-armv7-gnueabi       <download available>
cpython-3.12.3-linux-aarch64-gnu         <download available>
...
```

## Test Plan

The following commands were executed on the command line to confirm the
results in Ubuntu 24.04.
- `cargo run python list`
- `cargo run python list --all-platforms`
2024-07-14 11:14:57 -05:00
Charlie Marsh afe35e787d
Update standalone Pythons to include 3.12.4 (#5042) 2024-07-14 01:51:47 +00:00
Charlie Marsh a2edc33ead
Add a custom error message for `--no-build-isolation` `torch` dependencies (#5041)
## Summary

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

## Test Plan

```
❯ cargo run pip install torch torch-scatter --no-cache
⠼ torch-scatter==2.1.2                                                                                                    error: Failed to download and build `torch-scatter==2.1.2`
  Caused by: Failed to build: `torch-scatter==2.1.2`
  Caused by: Build backend failed to determine extra requires with `build_wheel()` with exit status: 1
--- stdout:

--- stderr:
Traceback (most recent call last):
  File "<string>", line 14, in <module>
  File "/private/var/folders/nt/6gf2v7_s3k13zq_t3944rwz40000gn/T/.tmpuxrhWj/builds-v0/.tmp1OBLbw/lib/python3.12/site-packages/setuptools/build_meta.py", line 327, in get_requires_for_build_wheel
    return self._get_build_requires(config_settings, requirements=[])
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/private/var/folders/nt/6gf2v7_s3k13zq_t3944rwz40000gn/T/.tmpuxrhWj/builds-v0/.tmp1OBLbw/lib/python3.12/site-packages/setuptools/build_meta.py", line 297, in _get_build_requires
    self.run_setup()
  File "/private/var/folders/nt/6gf2v7_s3k13zq_t3944rwz40000gn/T/.tmpuxrhWj/builds-v0/.tmp1OBLbw/lib/python3.12/site-packages/setuptools/build_meta.py", line 497, in run_setup
    super().run_setup(setup_script=setup_script)
  File "/private/var/folders/nt/6gf2v7_s3k13zq_t3944rwz40000gn/T/.tmpuxrhWj/builds-v0/.tmp1OBLbw/lib/python3.12/site-packages/setuptools/build_meta.py", line 313, in run_setup
    exec(code, locals())
  File "<string>", line 8, in <module>
ModuleNotFoundError: No module named 'torch'
---
  Caused by: This error likely indicates that torch-scatter==2.1.2 depends on torch, but doesn't declare it as a build dependency. If torch-scatter==2.1.2 is a first-party package, consider adding torch to its `build-system.requires`. Otherwise, `uv pip install torch` into the environment and re-run with `--no-build-isolation
```
2024-07-13 21:12:26 +00:00
skshetry e8c16889f1
pip compile: exclude --upgrade-package when option and value are passed as a single argument (#5033)
This excludes `--upgrade-package` from `compile_command` when value and
option are passed as a single argument. Eg:

```console
--upgrade-package=package
-P=package
-Ppackage
```

I missed this on #5032.
Fixes #5031.

## Test Plan

Tested locally
2024-07-13 16:51:36 +00:00
Zanie Blue 9997dc0870
There are no rage requests here (#5037) 2024-07-13 15:35:51 +00:00
skshetry f770b25be2
pip compile: exclude --upgrade-package from the header (#5032)
## Summary

Fixes #5031.

## Test Plan

Existing snapshot tests should cover it.
2024-07-12 23:24:35 -05:00
Charlie Marsh 4eb19c76bd
Add Windows path updates for `uv tool` (#5029)
## Summary

Largely based on rustup's implementation (linked in the source).

Closes #5027.

## Test Plan

- Changed the executable directory to `uv/foo`.
- Ran script; verified that I could access executables in `foo`.
2024-07-13 01:55:05 +00:00
Charlie Marsh a61464e802
Move shell manipulation into its own crate (#5028)
## Summary

This is going to get a little more complex as we support Windows, so
carving it out.
2024-07-12 21:12:58 -04:00
Ibraheem Ahmed ba217f1059
Use lockfile to prefill resolver index (#4495)
## Summary

Use the lockfile to prefill the `InMemoryIndex` used by the resolver.
This enables us to resolve completely from the lockfile without making
any network requests/builds if the requirements are unchanged. It also
means that if new requirements are added we can still avoid most I/O
during resolution, partially addressing
https://github.com/astral-sh/uv/issues/3925.

The main limitation of this PR is that resolution from the lockfile can
fail if new versions are requested that are not present in the lockfile,
in which case we have to perform a fresh resolution. Fixing this would
likely require lazy version/metadata requests by `VersionMap` (this is
different from the lazy parsing we do, the list of versions in a
`VersionMap` is currently immutable).

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

## Test Plan

Added a `deterministic!` macro that ensures that a resolve from the
lockfile and a clean resolve result in the same lockfile output for all
our current tests.
2024-07-12 18:49:28 -04:00
Charlie Marsh df2ee8ad14
Improve rc file detection based on rustup (#5026)
## Summary

Brings in some learnings from `rustup`:
fede22fea7/src/cli/self_update/shell.rs (L197).

For example: we only need to write to `.zshenv` (but we have to respect
`ZDOTDIR`). Additionally, for Fish, we need to respect `XDG_CONFIG_HOME`
2024-07-12 22:40:31 +00:00
Charlie Marsh a4cb21e081
Add a command to append uv's binary directory to PATH (#4975)
## Summary

I'll open follow-up tickets for Windows support.

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

## Test Plan

```
❯ cargo run tool install flask
Resolved 7 packages in 353ms
Prepared 7 packages in 392ms
Installed 7 packages in 17ms
 + blinker==1.8.2
 + click==8.1.7
 + flask==3.0.3
 + itsdangerous==2.2.0
 + jinja2==3.1.4
 + markupsafe==2.1.5
 + werkzeug==3.0.3
Installed 1 executable: flask
warning: /Users/crmarsh/.local/bin is not on your PATH. To use installed tools, run:
  export PATH="/Users/crmarsh/.local/bin:$PATH"
```

Then:

```
❯ which flask
flask not found
```

Then:

```
❯ cargo run tool ensurepath
warning: `uv tool ensurepath` is experimental and may change without warning.
Updated configuration file: /Users/crmarsh/workspace/puffin/bar
Restart your shell for the changes to take effect.
```

Then:
```
❯ which flask
/Users/crmarsh/.local/bin/flask
```
2024-07-12 22:09:34 +00:00
Charlie Marsh 5f851d1d19
Warn when unused `pyproject.toml` configuration is detected (#5025)
## Summary

Closes https://github.com/astral-sh/uv/issues/5022.
2024-07-12 17:50:04 -04:00
Ahmed Ilyas 26d8879c3a
`uv tool run` error messages references `uvx` when appropriate (#5014)
## Summary

Resolves #5013. 

## Test Plan

```console
❯ ./target/debug/uv tool run fastapi-cli
warning: `uv tool run` is experimental and may change without warning.
Resolved 9 packages in 28ms
The executable fastapi-cli was not found.
However, the following executables are available via uv tool run --from fastapi-cli <EXECUTABLE>:
- fastapi
```

```console
❯ ./target/debug/uvx fastapi-cli
warning: `uvx` is experimental and may change without warning.
Resolved 9 packages in 23ms
The executable fastapi-cli was not found.
However, the following executables are available via uvx --from fastapi-cli <EXECUTABLE>:
- fastapi
```

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2024-07-12 17:17:26 +00:00
Silvano Cerza 2ccb7ed305
Add `--no-pager` option in `help` command (#5007)
## Summary

Fixes #4941.

This PR adds a `--no-pager` option in `help` command to explicitly
disable the pager.

I noted that the template used for the text printed when calling `help`
with no argument or option doesn't show any option. It made sense before
this PR since `help` didn't have any available option. Though I'm unsure
if it makes sense to update the template as it would make it extremely
verbose as all the global options would be shown too.

I leave the decision to you.

## Test Plan

I ran `cargo run -- help` to verify `--isolated` was visible and it.
I ran clippy with `cargo clippy --workspace --all-targets --all-features
--locked -- -D warnings` as CI does.

I also ran tests locally with:
```
cargo nextest run \
            --features python-patch \
            --workspace \
            --status-level skip --failure-output immediate-final --no-fail-fast -j 12 --final-status-level slow
```
2024-07-12 11:11:50 -05:00
Ibraheem Ahmed a1f71a36e7
Fix substring marker expression disjointness checks (#4998)
## Summary

Noticed a bug here, `'a' in env` and `env not in 'a'` are not disjoint
given `env == 'ab'`.
2024-07-12 15:21:21 +00:00
Andrew Gallant abdb58d2df uv: fix doc test
[Doc tests can't use crate internal APIs unfortunately.][internal-doc]
I really want them to be able to, but for now, mark such tests as
`ignore`.

I was motivated to do this because it otherwise breaks `cargo t --all`
for me.

[internal-doc]: https://github.com/rust-lang/rust/issues/50784
2024-07-12 07:57:29 -07:00
Silvano Cerza 663c190c2d
Unhide `--isolated` global argument (#5005)
## Summary

This PR makes the `--isolated` global argument visible, previously it
was hidden.
Fixes #4981.

## Test Plan

I ran `cargo run -- help` to verify `--isolated` was visible and it is.
I ran clippy with `cargo clippy --workspace --all-targets --all-features
--locked -- -D warnings` as CI does.

I also ran tests locally with:
```
cargo nextest run \
            --features python-patch \
            --workspace \
            --status-level skip --failure-output immediate-final --no-fail-fast -j 12 --final-status-level slow
```
2024-07-12 09:34:00 -05:00
Andrew Gallant 8d6c49b36c pep508: add MarkerTree::negate
It does what you think it does, for the most part.
2024-07-12 04:37:36 -07:00
Andrew Gallant da8a4a6faa pep508: write x.y.* when serializing MarkerExpression
It's unclear to me whether this was intentional or not, but
I realized that converting a MarkerExpression to a string
treated EqualStar and NotEqualStar as Equal and NotEqual,
respectively. I tweaked this to match the Display impl for
VersionSpecifier.

(Negation tests in the next commit cover this change.)
2024-07-12 04:37:36 -07:00
Ahmed Ilyas 23c6cd774b
`uv tool run` suggest valid commands when command is not found (#4997)
## Summary

Resolves #4979.


## Test Plan

`cargo test`

<img width="619" alt="Screenshot 2024-07-11 at 22 45 36"
src="https://github.com/user-attachments/assets/62526010-9123-43f5-9f8d-1f9e89f6be59">

<img width="636" alt="Screenshot 2024-07-11 at 22 45 23"
src="https://github.com/user-attachments/assets/a348cd73-f891-40b1-8934-afbd1aa19326">
2024-07-12 02:26:15 +00:00
Charlie Marsh 6949796110
Allow URL dependencies in tool run `--from` (#5002)
## Summary

Converting to a lock requires that we generate hashes; but generating
hashes isn't required here. So let's just use a different representation
for the cache key.

Closes https://github.com/astral-sh/uv/issues/4990.
2024-07-12 01:31:07 +00:00
Caíque Porfirio 9643fb99d1
Rename `python install --force` parameter to `--reinstall` (#4999)
## Summary

Rename the `--force` parameter of `uv python install` to `--reinstall`.

Closes #4961.
2024-07-12 01:06:54 +00:00
Charlie Marsh c345484c93
Fall back to streaming wheel when `Content-Length` header is absent (#5000)
## Summary

Closes https://github.com/astral-sh/uv/issues/4993
2024-07-12 01:04:21 +00:00
Charlie Marsh 55b41d7d3d
Lock directories to synchronize wheel-install copies (#4978)
## Summary

Closes https://github.com/astral-sh/uv/issues/4831.
2024-07-12 00:53:20 +00:00
Billy Doyle 22cca77329
Exit with zero when `uv tool install` request is already satisfied (#4986)
## Summary

`uv tool install X` fails for tools already installed and exits with
code 1. Allow already installed tools to exit with code 0.
2024-07-11 20:43:31 -04:00
Charlie Marsh 9307928765
Improve missing `wheel` error message with `--no-build-isolation` (#4964)
Closes https://github.com/astral-sh/uv/issues/4069.
2024-07-10 21:10:20 +00:00
Zanie Blue 527b711bc7
Bump version to 0.2.24 (#4974) 2024-07-10 13:50:12 -05:00
Zanie Blue c14de2a92a
Allow `uv` crate to be used as a library (#4642)
This is pulled out of #4632 — a user noted that it would be useful to
use the `uv` crate from Rust. This makes it way easier to invoke `uv`
from Rust with arbitrary arguments as well as use various functionality
in the `uv` crate.

Note this is no longer needed for #4632 and is not particularly urgent.
2024-07-10 17:15:54 +00:00
Zanie Blue e0fae8e6f4
Add `uv python pin` (#4950)
Adds a `uv python pin` command to write to a `.python-version` file.

We support all of our Python version request formats. We also support a
`--resolved` flag to pin to a specific interpreter instead of the
provided version. We canonicalize the request with #4949, it's not just
printed verbatim. We always attempt to find the interpreter so we can
warn if it's not available. With `--resolved`, if we can't find the
interpreter we fail. If no arguments are provided, we'll attempt to
display the current pin.

In the future:

- We should confirm that this satisfies the `Requires-Python` metadata
if a `pyproject.toml` is present
- We should support writing to a `uv.python-version` field if
`pyproject.toml` or `uv.toml` are present
- We should support finding and updating the "nearest" Python version
file (looking in ancestors)
- We should support finding version files in workspaces
- We should support some sort of global pin
2024-07-10 16:52:24 +00:00
Charlie Marsh 7925d255f7
Add `manylinux_2_31` to supported `--python-platform` (#4965)
## Summary

I'll make an issue for arbitrary `manylinux_x_y` support.

Closes https://github.com/astral-sh/uv/issues/4956.
2024-07-10 16:30:35 +00:00
Zanie Blue f3c5d26417
Lock for the duration of tool commands (#4720)
Feedback from
https://github.com/astral-sh/uv/pull/4501#discussion_r1655391958
2024-07-10 16:16:13 +00:00
Zanie Blue a4044be95b
Respect `--isolated` in `uv python install` (#4938)
We ignore Python version files when `--isolated` is used, logging that
we skipped them if they exist.
2024-07-10 15:36:25 +00:00
Zanie Blue acfb57b072
Add support for serializing `PythonRequest` to a canonical string (#4949)
For #4950
2024-07-10 10:24:45 -05:00
Charlie Marsh 1fcc3c4797
Warn if tool binary directory is not on path (#4951)
## Summary

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

## Test Plan

```
❯ XDG_BIN_HOME="/Users/crmarsh/workspace/uv/foo bar" cargo run tool install black --force
Installed 2 executables: black, blackd
warning: `/Users/crmarsh/workspace/uv/foo bar` is not on your PATH. To use installed tools, run:
  export PATH="/Users/crmarsh/workspace/uv/foo bar:$PATH"
```
2024-07-10 15:24:16 +00:00
Zanie Blue 3d1ab81c28
Add support for any Python requests (#4948)
For roundtrip in #4949 — it should also be fine to request `any` but the
user can't construct it right now.
2024-07-10 10:20:06 -05:00
Zanie Blue aa8f126f13
Add standard filters for virtual environment bin directories and python executables (#4787)
Needed over in https://github.com/astral-sh/uv/pull/4674

These filters are relatively aggressive and may have a high false
positive rate, we don't need them for most tests so we leave them as
opt-in for now.
2024-07-10 10:09:43 -05:00
Zanie Blue f5dce1124b
Retry on connection reset network errors (#4960)
See helpful discussion at
https://github.com/seanmonstar/reqwest/issues/1602#issuecomment-1220990725
and https://github.com/astral-sh/uv/issues/3514#issuecomment-2216986250

Should help with #3514 though I'll wait to close until it's confirmed as
we cannot reproduce this.
2024-07-10 10:08:47 -05:00
Zanie Blue d497adaacb
Improve 'any' search message during `uv python install` (#4940)
Special cases the `Any` request in output

e.g.,

```
❯ cargo run -q -- python install --isolated
warning: `uv python install` is experimental and may change without warning.
Searching for Python installations
Found existing installation: cpython-3.12.3-macos-aarch64-none
Python is already available. Use `uv python install <request>` to install a specific version.
```

instead of 

```
❯ cargo run -q -- python install --isolated
warning: `uv python install` is experimental and may change without warning.
Searching for Python versions matching: any Python
Found existing installation for any Python: cpython-3.12.3-macos-aarch64-none
Python is already available. Use `uv python install <request>` to install a specific version.
```
2024-07-10 15:03:22 +00:00
Jo 42ccce9641
Fix `index_strategy` doc (#4955)
## Summary

There is a missing `)` after `first_match`.
2024-07-10 08:54:23 -05:00
Ibraheem Ahmed d833910a5d
Avoid reparsing wheel URLs (#4947)
## Summary

We currently store wheel URLs in an unparsed state because we don't have
a stable parsed representation to use with rykv. Unfortunately this
means we end up reparsing unnecessarily in a lot of places, especially
when constructing a `Lock`. This PR adds a `UrlString` type that lets us
avoid reparsing without losing the validity of the `Url`.

## Test Plan

Shaves off another ~10 ms from
https://github.com/astral-sh/uv/issues/4860.

```
➜  transformers hyperfine "../../uv/target/profiling/uv lock" "../../uv/target/profiling/baseline lock" --warmup 3
Benchmark 1: ../../uv/target/profiling/uv lock
  Time (mean ± σ):     120.9 ms ±   2.5 ms    [User: 126.0 ms, System: 80.6 ms]
  Range (min … max):   116.8 ms … 125.7 ms    23 runs
 
Benchmark 2: ../../uv/target/profiling/baseline lock
  Time (mean ± σ):     129.9 ms ±   4.2 ms    [User: 127.1 ms, System: 86.1 ms]
  Range (min … max):   123.4 ms … 141.2 ms    23 runs

Summary
  ../../uv/target/profiling/uv lock ran
    1.07 ± 0.04 times faster than ../../uv/target/profiling/baseline lock
```
2024-07-10 05:16:30 -04:00
Charlie Marsh 23eb42deed
Allow constraints to be provided in `--upgrade-package` (#4952)
## Summary

Allows, e.g., `--upgrade-package flask<3.0.0`.

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

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

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

## Test Plan

```
Benchmark 1: ./target/profiling/uv (resolve-warm)
  Time (mean ± σ):      14.9 ms ±   0.3 ms    [User: 3.0 ms, System: 17.3 ms]
  Range (min … max):    14.1 ms …  15.8 ms    169 runs
 
Benchmark 2: ./target/profiling/baseline (resolve-warm)
  Time (mean ± σ):      16.1 ms ±   0.3 ms    [User: 3.9 ms, System: 18.7 ms]
  Range (min … max):    15.1 ms …  17.3 ms    162 runs
 
Summary
  ./target/profiling/uv (resolve-warm) ran
    1.08 ± 0.03 times faster than ./target/profiling/baseline (resolve-warm)
```
2024-07-09 18:21:16 -04:00
Charlie Marsh 540ff24302
Perform lock in `uv sync` by default (#4839)
## Summary

- `uv sync` will now lock by default.
- `uv sync --locked` will lock, and error if the generated lock does not
match `uv.lock` on-disk.
- `uv sync --frozen` will skip locking and just use `uv.lock`.

Closes https://github.com/astral-sh/uv/issues/4812.
Closes https://github.com/astral-sh/uv/issues/4803.
2024-07-09 15:18:30 -07:00
Ibraheem Ahmed 8c9bd70c71
Avoid serializing if lockfile does not change (#4945)
## Summary

Avoid serializing and writing the lockfile if a cheap comparison shows
that the contents have not changed.

## Test Plan

Shaves ~10ms off of https://github.com/astral-sh/uv/issues/4860 for me.

```
➜  transformers hyperfine "../../uv/target/profiling/uv lock" "../../uv/target/profiling/baseline lock" --warmup 3
Benchmark 1: ../../uv/target/profiling/uv lock
  Time (mean ± σ):     130.5 ms ±   2.5 ms    [User: 130.3 ms, System: 85.0 ms]
  Range (min … max):   126.8 ms … 136.9 ms    23 runs
 
Benchmark 2: ../../uv/target/profiling/baseline lock
  Time (mean ± σ):     140.5 ms ±   5.0 ms    [User: 142.8 ms, System: 85.5 ms]
  Range (min … max):   133.2 ms … 153.3 ms    21 runs
 
Summary
  ../../uv/target/profiling/uv lock ran
    1.08 ± 0.04 times faster than ../../uv/target/profiling/baseline lock
```
2024-07-09 17:08:27 -04:00
Zanie Blue dc80fdba2c
Do not use pager for root `uv help` and improve after help hint (#4936)
Adds a nice hint at the bottom of `uv help` output indicating how to get
more details about a specific command, roughly matching Cargo's
interface.

We use the short help and skip the pager for the root `uv help` since
it's intended to be a landing page for the help interface more than an
in-depth display. This also matches Cargo, though I like that they have
the global options above the commands and I've not changed that here.
2024-07-09 14:38:28 -05:00
Charlie Marsh 55e1a7e011
Enable `--all` to uninstall all managed tools (#4937)
## Summary

Like #4932 but for tools.
2024-07-09 19:26:17 +00:00
Charlie Marsh bb703b8343
Reinstall and recreate environments when interpreter is removed (#4935)
## Summary

We now recreate the environment in `uv sync`, `uv tool install`, and `uv
tool run` if the underlying interpreter has been removed.

Closes https://github.com/astral-sh/uv/issues/4933.
2024-07-09 19:25:23 +00:00
konsti 53db63f6dd
Apply extra to overrides and constraints (#4829)
This is an attempt to solve https://github.com/astral-sh/uv/issues/ by
applying the extra marker of the requirement to overrides and
constraints.

Say in `a` we have a requirements
```
b==1; python_version < "3.10"
c==1; extra == "feature"
```

and overrides
```
b==2; python_version < "3.10"
b==3; python_version >= "3.10"
c==2; python_version < "3.10"
c==3; python_version >= "3.10"
```

Our current strategy is to discard the markers in the original
requirements. This means that on 3.12 for `a` we install `b==3`, but it
also means that we add `c` to `a` without `a[feature]`, causing #4826.
With this PR, the new requirement become,

```
b==2; python_version < "3.10"
b==3; python_version >= "3.10"
c==2; python_version < "3.10" and extra == "feature"
c==3; python_version >= "3.10" and extra == "feature"
```

allowing to override markers while preserving optional dependencies as
such.

Fixes #4826
2024-07-09 20:37:24 +02:00
Charlie Marsh 0a04108a15
Enable `--all` to uninstall all managed Pythons (#4932)
## Summary

Allows `--all` as an alternative to specifying specific targets.

## Test Plan

Verified that `cargo run python uninstall` still fails.

```
❯ cargo run python uninstall --all
   Compiling uv-cli v0.0.1 (/Users/crmarsh/workspace/puffin/crates/uv-cli)
   Compiling uv v0.2.23 (/Users/crmarsh/workspace/puffin/crates/uv)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.86s
     Running `target/debug/uv python uninstall --all`
warning: `uv python uninstall` is experimental and may change without warning.
Searching for Python installations
Found existing installation: cpython-3.9.18-macos-aarch64-none
Found existing installation: cpython-3.8.18-macos-aarch64-none
Found existing installation: cpython-3.8.12-macos-aarch64-none
Found existing installation: cpython-3.12.1-macos-aarch64-none
Found existing installation: cpython-3.11.7-macos-aarch64-none
Found existing installation: cpython-3.10.13-macos-aarch64-none
Uninstalled cpython-3.10.13-macos-aarch64-none
Uninstalled cpython-3.11.7-macos-aarch64-none
Uninstalled cpython-3.12.1-macos-aarch64-none
Uninstalled cpython-3.8.12-macos-aarch64-none
Uninstalled cpython-3.8.18-macos-aarch64-none
Uninstalled cpython-3.9.18-macos-aarch64-none
Uninstalled 6 versions in 479ms
```
2024-07-09 18:15:16 +00:00
Zanie Blue bd7a25f604
Use paging for `uv help` display when available (#4909)
Extends https://github.com/astral-sh/uv/pull/4906

Adds paged display of "long' help to `uv help` invocations when `less`
or `more` is available.
2024-07-09 18:06:27 +00:00
Charlie Marsh 92290d8dcb
Respect resolver settings in `uv remove` (#4930)
## Summary

Closes https://github.com/astral-sh/uv/issues/4925
2024-07-09 17:46:31 +00:00
Zanie Blue 5f20bdb2ee
Implement `uv help` manually instead of using Clap default (#4906)
Extends #4772 

Implements `uv help` ourselves so we can do things like #4909 
Adds hints to use `uv help` for more details during short help display.
2024-07-09 17:43:13 +00:00
Charlie Marsh 2e307d9081
Avoid inferring package name for GitHub Archives (#4928)
## Summary

Closes https://github.com/astral-sh/uv/issues/4917.
2024-07-09 17:30:43 +00:00
Zanie Blue 0bf562f197
Display short help menu when `--help` is used (#4772)
I feel like I'm always drowning in the help output from `uv` because we
have so many options.

I basically agree with the commentary in
https://github.com/clap-rs/clap/issues/4687 that having different
behaviors for `-h` and `--help` is surprising. I think `--help` is more
obvious for users and I want to optimize for that experience.

This roughly matches the help menus in Cargo and pip.

The `uv help` command can be used for long help. In #4906 and #4909 we
improve that command.

Extends #4904 which adds test cases for the existing behavior.
2024-07-09 17:12:01 +00:00
Charlie Marsh 72dd34b225
Filter out markers based on Python requirement (#4912)
## Summary

In marker normalization, we now remove any markers that are redundant
with the `requires-python` specifier (i.e., always true for the given
Python requirement).

For example, given `iniconfig ; python_version >= '3.7'`, we can remove
the `python_version >= '3.7'` marker when resolving with
`--python-version 3.8`.

Closes #4852.
2024-07-09 09:15:58 -07:00
Charlie Marsh a046d23f79
Avoid AND-ing multi-term specifiers in marker normalization (#4911)
## Summary

Given `python_version != '3.8' and python_version < '3.10'`, the first
term was expanded to `python_version < '3.8'` and `python_version >
'3.8'`. We then AND'd all three terms together. We don't seem to have a
way to differentiate between the terms to AND and the terms to OR in the
normalization code (it all gets flattened together), so instead this PR
expands the expressions at the leaf level and then flattens them at the
level above when appropriate.

Closes https://github.com/astral-sh/uv/issues/4910.
2024-07-09 16:04:26 +00:00
Zanie Blue b4a7d96d4e
Add test cases for the CLI help menu (#4904)
No changes in behavior here, adding these test cases to demonstrate
changes to come.
2024-07-09 09:07:43 -05:00
Charlie Marsh 72982c1bff
Add command-separation for Python discovery display (#4916)
## Summary

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

```
error: No interpreter found for Python 3.12.4 in virtual environments, managed installations, or system path
```
2024-07-09 05:51:30 +00:00
Charlie Marsh f862457f05
Avoid debug error for `uv run` with unknown Python version (#4913)
## Summary

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

## Test Plan

```
> cargo run -- run -vv --preview --isolated --python 3.12.4 python -V
error: No interpreter found for Python 3.12.4 in virtual environments or managed installations or system path
```
2024-07-09 05:29:55 +00:00
Ibraheem Ahmed ed4234d52e
Filter and flatten markers (#4639)
## Summary

More marker simplification:
- Filters out redundant subtrees based on outer expressions, e.g. `a and (a or
b)` simplifies to `a`.
- Flattens nested trees internally, e.g. `(a and b) and c`

Resolves https://github.com/astral-sh/uv/issues/4536.
2024-07-08 18:59:21 +00:00
Ibraheem Ahmed dc7ad3abdb
Implement `uv tree` (#4708)
## Summary

Implements the `uv tree`, which displays dependencies from the lockfile
as a tree. Resolves https://github.com/astral-sh/uv/issues/4699.
2024-07-08 18:07:48 +00:00
Zanie Blue 4bc36c0cb8
Bump version to 0.2.23 (#4903) 2024-07-08 12:29:37 -05:00
Andrew Gallant 857d2e8f1e uv-resolver: partially revert Requires-Python version narrowing
The PR #4707 introduced the notion of "version narrowing," where a
Requires-Python constraint was _possibly_ narrowed whenever the
universal resolver created a fork. The version narrowing would occur
when the fork was a result of a marker expression on `python_version`
that is *stricter* than the configured `Requires-Python` (via, say,
`pyproject.toml`).

The crucial conceptual change made by #4707 is therefore that
`Requires-Python` is no longer an invariant configuration of resolution,
but rather a mutable constraint that can vary from fork to fork. This in
turn can result in some cases, such as in #4885, where different
versions of dependencies are selected. We aren't sure whether we can fix
those or not, with version narrowing, so for now, we do this revert to
restore the previous behavior and we'll try to address the version
narrowing some other time.

This also adds the case from #4885 as a regression test, ensuring that
we don't break that in the future. I confirmed that with version
narrowing, this test outputs duplicate distributions. Without narrowing,
there are no duplicates.

Ref #4707, Fixes #4885
2024-07-08 09:56:59 -07:00
Charlie Marsh ac3a085084
Respect `requires-python` when prefetching (#4900)
## Summary

This is fallout from https://github.com/astral-sh/uv/pull/4705. We need
to respect `requires-python` in the prefetch code to avoid building
unsupported distributions.

Closes https://github.com/astral-sh/uv/issues/4898.
2024-07-08 16:32:09 +00:00
Charlie Marsh 71c6a9fad3
Sort dependencies before wheels and source distributions (#4897)
Closes https://github.com/astral-sh/uv/issues/4889.
2024-07-08 14:25:05 +00:00
Charlie Marsh b9d661012d
Initialize all `--prefix` subdirectories (#4895)
## Summary

We need to initialize the same directories that we create in `bare.rs`,
since the installer expects them to exist.

Closes #4892.
2024-07-08 14:15:25 +00:00
Charlie Marsh 2d651fe264
Add some text decoration to toolchain CLI (#4882)
## Summary

Attempts to make the CLI output a little more consistent with the `pip`
interface. I opted to make the Python versions, requests, and filenames
blue, and the keys green, but open to opinions on that. (We use blue for
filenames elsewhere.)

Closes #4813.
Closes https://github.com/astral-sh/uv/issues/4814.

![Screenshot 2024-07-07 at 9 18
48 PM](https://github.com/astral-sh/uv/assets/1309177/8518b559-196b-4cd0-bc16-8e79e66460bb)
2024-07-08 10:03:38 -04:00
konsti 57cfe1e229
Small forking log improvements (#4894)
I found the current messages insufficient when tracking down a bug.
2024-07-08 13:56:57 +00:00
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
Andrew Gallant 20b44f3017 uv-resolver: add some tracing logs for when we filter requirements
Specifically, these are emitted when requirements fail to satisfy
`Requires-Python` or the markers associated with the current fork in the
resolver.

Closes #4373
2024-06-18 11:15:16 -04:00
Zanie Blue 58f53f01bb
Ignore query errors during `uv toolchain list` (#4382)
Closes #4380 

This is the same logic as `should_stop_discovery` but I changed the log
level and duplicated it because I don't really want that method to be
public. Maybe it should be though?
2024-06-18 14:52:59 +00:00
Zanie Blue 1ce21475a5
Respect `.python-version` files and fetch manged toolchains in uv project commands (#4361)
As in #4360, updates the uv project CLI to respect `.python-version`
files as default Python version requests. Additionally, updates project
interpreter discovery to fetch managed toolchains as in `uv venv
--preview`.
2024-06-18 09:43:52 -05:00
Zanie Blue 903dfc2f1f
Respect `.python-version` in `uv venv --preview` (#4360)
Adds support for reading Python version files (introduced in #4335) to
`uv venv`. If present, we'll use the file version as the default.
2024-06-18 14:21:35 +00:00
Zanie Blue 76c26db444
Move virtual environment test context into main context (#4370)
It was becoming problematic that the virtual environment test context
diverged from the other one i.e. we had to implement filtering twice.
This combines the contexts and tweaks the `TestContext` API and
filtering mechanisms for Python versions. Combined with my previous
changes to the test context at #4364 and
https://github.com/astral-sh/uv/pull/4368 this finally unblocks the
snapshots for test cases in #4360 and
https://github.com/astral-sh/uv/pull/4362.
2024-06-18 09:11:47 -05:00
Michał Górny a193834813
Fix cache-prune-test to work outside the git repository (#4375)
## Summary

Make the git commit/date part of the version string matched in
cache_prune optional, so that the test also works correctly when uv is
built from an unpacked release tarball rather than a git repository.

Fixes #4374

## Test Plan

Ran `cargo test` inside the git repository and inside unpacked archive
for `0.2.12` release with the patch applied on top.
2024-06-18 10:15:40 +03:00
Charlie Marsh c996e8e3f3
Enable workspace lint configuration in remaining crates (#4329)
## Summary

We didn't have Clippy enabled (to match our workspace settings) in a few
crates.
2024-06-18 03:02:28 +00:00
Zanie Blue b8c0391667
Bump version to 0.2.12 (#4371) 2024-06-17 16:46:28 -05:00
Ibraheem Ahmed a813a1de4c
`uv sync --no-clean` (#4367)
## Summary

Adds a `--no-clean` flag to `uv sync` that keeps extraneous
installations. This is the default in `uv run` and `uv add`, but not in
`uv sync` or `uv remove`. This means you need to run an explicit `uv
sync/remove` to clean the virtual environment.
2024-06-17 20:24:22 +00:00
Zanie Blue 05870609ee
Add filtering of interpreter names for tests with multiple Python versions (#4368)
Extends new filters for interpreter paths to apply to tests with
multiple Python versions. Adds patch version filtering for them as well,
which is needed for #4360 tests.
2024-06-17 20:22:46 +00:00
Zanie Blue 3f164b5a3a
Add Python version filtering for ad-hoc virtual environments (#4365)
Extends #4364 automatically adding filters to the test context for
additional test virtual environments.

It turns out that the `pip sync` tests were really on the loose with
their virtual environment creation and it was difficult to use the new
helpers because they require mutability and the tests had immutable
borrows to extend the filters 😭. I refactored the tests to just reset
the environment.
2024-06-17 15:15:00 -05:00
Zanie Blue 56f0a117ca
Move version file reading to `uv-toolchain` (#4340)
In preparation for using this in other commands.
2024-06-17 18:54:22 +00:00
Zanie Blue 631994c485
Remove `cargo dev fetch-python` (#4337)
This has been fully replaced by `uv toolchain install`
2024-06-17 18:49:06 +00:00
Ibraheem Ahmed 05d79f8d38
Remove extraneous installations in `uv sync` by default (#4366)
## Summary

First step of https://github.com/astral-sh/uv/issues/4358. `uv sync`
will now remove any extraneous installations by default.
2024-06-17 14:38:34 -04:00
Zanie Blue 47d3834fd3
Read Python version files during toolchain installs (#4335)
A bare `uv toolchain install` invocation now reads default requests from
Python version files in the working directory. In order, a bare
invocation means:

- requests from `.python-versions`
- a single request from`.python-version`
- any installed managed toolchain
- the latest managed toolchain download

This replaces all the functionality of `cargo dev fetch-python`, which
we drop in #4337
2024-06-17 18:37:52 +00:00
samypr100 a0eca1ac14
feat: display keyring stderr (#4343)
## Summary

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

Changes keyring subprocess to allow display of stderr.
This aligns with pip's behavior since pip 23.1.

## Test Plan

* Tested using gnome-keyring-backend on a self-hosted private registry
as well as the keyring script described in #4162 to confirm both
existing functionality and the new stderr display.
* Existing tests using `scripts/packages/keyring_test_plugin` are now
showing its stderr output as well.
2024-06-17 13:29:33 -05:00
Zanie Blue fdcdc2cbe6
Allow multiple toolchains to be requested in `uv toolchain install` (#4334)
Allows installation of multiple toolchains in a single invocation
because I don't want to be limited to one! Most of the implementation
for concurrent downloads ported from `cargo dev fetch-python`.
2024-06-17 18:24:11 +00:00
Zanie Blue 5248269d27
Add support for toolchain requests by key (#4332)
Adds support for toolchain keys e.g. `cpython-3.11.2-macos` allowing you
to download toolchains for specific architectures and operating systems
using the format we use to uniquely identify a toolchain.
2024-06-17 13:11:24 -05:00
Zanie Blue 94fe70d547
Add filtering of the test context Python interpreter (#4364)
Does not handle tests with multiple Python versions yet, working on that
separately because the change is more invasive
2024-06-17 13:11:12 -05:00
Zanie Blue b5d280dc40
Refactor `Toolchain` API to always take `ToolchainRequest` instead of `str` (#4341)
This API was taking an `Option<&str>` for caller convenience in some
places but we ought to just take a `ToolchainRequest` consistently.
2024-06-17 11:16:15 -05:00
Zanie Blue 67f1285ce3
Add `EXTERNALLY-MANAGED` markers to managed toolchains (#4312)
Closes #4240 

e.g.

```
❯ cargo run -q -- pip install anyio --python "/Users/zb/Library/Application Support/uv/toolchains/cpython-3.12.0-macos-aarch64-none/install/bin/python3"
error: The interpreter at /Users/zb/Library/Application Support/uv/toolchains/cpython-3.12.0-macos-aarch64-none/install is externally managed, and indicates the following:

  This toolchain is managed by uv and should not be modified.

Consider creating a virtual environment with `uv venv`.
```
2024-06-17 15:25:34 +00:00
Andrew Gallant e264637b63 uv/tests: add more fork marker tests
These were prompted by @konstin's question here:
https://github.com/astral-sh/uv/pull/4339#discussion_r1642622391
2024-06-17 09:30:37 -04:00
Andrew Gallant 6a7b56ca05 uv/tests: add fork marker packse tests 2024-06-17 09:30:37 -04:00
Andrew Gallant dbb12bcfe4 uv-resolver: fix bug in marker disjointness checking
I found this while testing the tracking of marker expressions across
resolver forks. Namely, given

    sys_platform == 'darwin' and implementation_name == 'pypy'

And:

    sys_platform == 'bar' or implementation_name == 'foo'

These should be disjoint, but the disjointness checker was reporting
them as overlapping. I fixed this by giving handling of disjunctions
higher precedence than conjunctions, although I am not 100% confident
that this is correct for all cases.
2024-06-17 09:30:37 -04:00
Andrew Gallant 407f1e370b uv-resolver: filter dependencies that can't exist in a fork
This commit adds marker expressions to our `Fork` type, which are in
turn passed down into `PubGrubDependencies::from_requirements` to filter
our any dependencies with markers that are disjoint from the fork's
marker expression.

This is necessary to avoid visiting packages in the dependency graph
that can never actually be installed. This is because when a fork is
created in the resolver, it always happens when there are two sibling
dependency specifications on a package with the same name, but with
non-overlapping marker expressions. Each fork corresponds to each
such conflicting dependency specification, and each fork assumes the
the corresponding marker expression as a pre-condition for any future
dependencies considered by it. That is, since the fork represents an
installation path that can only be taken when the corresponding
dependency specification (and its marker expression) is actually used,
it also therefore follows that the marker expression is true. Therefore,
any dependency visited in that fork with a marker expression that cannot
possibly be true when the markers of the fork are true can and ought to
be completely ignored.
2024-06-17 09:30:37 -04:00
Andrew Gallant 07db2b167f uv-resolver: document some of our intermediate data structures
There are some key invariants that I had to re-learn by reading the
code. This hopefully makes those invariants easier to discover by future
me (and others).
2024-06-17 09:30:37 -04:00
Zanie Blue 52bb9a694c
Isolate virtual environment tests from developer toolchains (#4342)
Otherwise, when testing `uv venv --preview` the default toolchain
directory will leak into the test.

I believe I've made a similar change for the standard `TestContext` in
another commit somewhere in my stack, if not I'll add it after.
2024-06-17 05:40:11 -05:00
Ibraheem Ahmed 294f0e0c41
Add support for adding/removing development dependencies (#4327)
## Summary

Support adding/removing dependencies from `tool.uv.dev-dependencies`
with `uv add/remove --dev`.

Part of https://github.com/astral-sh/uv/issues/3959.
2024-06-14 19:17:29 +00:00
Ibraheem Ahmed 042fdea087
Support unnamed requirements in `uv add` (#4326)
## Summary

Support unnamed URL requirements in `uv add`. For example, `uv add
git+https://github.com/pallets/flask`.

Part of https://github.com/astral-sh/uv/issues/3959.
2024-06-14 13:42:39 -04:00
Zanie Blue accbb9b695
Add `uv toolchain find` (#4206)
Adds a command to find a toolchain on the system. Right now, it displays
the path to the first matching toolchain. We'll probably have more rich
output in the future (after implementing `toolchain show`).

The eventual plan (separate from here) is to port all of the toolchain
discovery tests to use this command. I'll add a few tests for this
command here anyway.
2024-06-14 17:03:16 +00:00
Charlie Marsh b7fb0b445f
Use portable slash paths in lockfile (#4324)
## Summary

This would be a lightweight solution to
https://github.com/astral-sh/uv/issues/4307 that doesn't fully engage
with all the possibilities in the design space (but would unblock
cross-platform for now).
2024-06-14 09:05:14 -04:00
Charlie Marsh 74c05683bb
Add a derive macro for `Combine` (#4325)
## Summary

Saves us some boilerplate when adding settings in the future.
2024-06-14 04:53:27 +00:00
Charlie Marsh 83067c1802
Reduce some `anyhow` usages (#4323) 2024-06-14 04:15:53 +00:00
Charlie Marsh 7d9541d0f4
Add `--no-build`, `--no-build-package`, and binary variants (#4322)
## Summary

These are now supported on `uv run`, `uv lock`, `uv sync`, and `uv tool
run`.

Closes https://github.com/astral-sh/uv/issues/4297.
2024-06-14 04:05:00 +00:00
Charlie Marsh f01ab57518
Add a `--show-settings` option for configuration testing (#4304)
## Summary

The fixtures here are pretty large, but it lets us test what we actually
care about (the resolved settings) rather than inferring the resolved
settings from behavior, which I think is a big improvement.

I also broke the tests down into more granular cases.
2024-06-14 03:14:23 +00:00
Charlie Marsh 1d6d98f3a3
Make `--reinstall`, `--upgrade`, and `--refresh` shared arguments (#4319)
## Summary

Ensures that we respect these in all the relevant `uv` APIs.

Closes https://github.com/astral-sh/uv/issues/4316.
2024-06-14 01:43:18 +00:00
Charlie Marsh db84825908
Omit project name from workspace errors (#4299)
## Summary

Because the workspace member itself is part of the resolution, adding
the workspace name for the project leads to confusing errors, like:

```
❯ cargo run lock --preview
   Compiling uv v0.2.11 (/Users/crmarsh/workspace/puffin/crates/uv)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.79s
     Running `/Users/crmarsh/workspace/puffin/target/debug/uv lock --preview`
  × No solution found when resolving dependencies:
  ╰─▶ Because only albatross==0.1.0 is available and albatross==0.1.0 depends on anyio<=3, we can conclude that all versions of albatross depend on anyio<=3.
      And because bird-feeder==1.0.0 depends on anyio>=4.3.0,<5 and only bird-feeder==1.0.0 is available, we can conclude that all versions of albatross and all versions of bird-feeder are incompatible.
      And because albatross depends on albatross and bird-feeder, we can conclude that the requirements are unsatisfiable.
```

(Notice "albatross depends on albatross".)
2024-06-14 01:32:51 +00:00
Charlie Marsh cacd1a2b5a
Load configuration options from workspace root (#4295)
## Summary

In a workspace, we now read configuration from the workspace root.
Previously, we read configuration from the first `pyproject.toml` or
`uv.toml` file in path -- but in a workspace, that would often be the
_project_ rather than the workspace configuration.

We need to read configuration from the workspace root, rather than its
members, because we lock the workspace globally, so all configuration
applies to the workspace globally.

As part of this change, the `uv-workspace` crate has been renamed to
`uv-settings` and its purpose has been narrowed significantly (it no
longer discovers a workspace; instead, it just reads the settings from a
directory).

If a user has a `uv.toml` in their directory or in a parent directory
but is _not_ in a workspace, we will still respect that use-case as
before.

Closes #4249.
2024-06-14 01:26:20 +00:00
Charlie Marsh e0a389032f
Add persistent configuration for non-`pip` APIs (#4294)
## Summary

This PR introduces top-level configuration for uv, such that you can do:

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

And `uv pip compile`, `uv run`, `uv tool run`, etc., will all respect
that configuration.

The settings that were escalated to the top-level remain on
`tool.uv.pip` too, but they're only respected in `uv pip` commands. If
they're specified in both places, then the `pip` settings win out.

While making this change, I also wired up some of the global options,
like `connectivity` and `native_tls`, through to all the relevant
places.

Closes #4250.
2024-06-13 20:56:38 -04:00
Zanie Blue b74de31967
Add `--force` option to `uv toolchain install` (#4313) 2024-06-13 16:43:40 -05:00
Zanie Blue 92802df223
Suggest correct command to create a virtual environment when encountering externally managed interpreters (#4314) 2024-06-13 16:43:31 -05:00
Zanie Blue 572551c108
Refactor toolchain discovery to use `satisfies_system_python` explicitly (#4310)
Splitting out the refactor from
https://github.com/astral-sh/uv/pull/4309
2024-06-13 17:44:53 +00:00
Zanie Blue b07c132ede
Skip invalid interpreters when searching for requested interpreter executable name (#4308)
Previously, we took the first executable on the `PATH` but if it was not
a usable interpreter we'd fail. Now, we'll continue searching in the
path until we find an interpreter as we do with the standard executable
names.
2024-06-13 12:36:12 -05:00
konsti 30126950fe
Fix relative and absolute path handling in lockfiles (#4266)
Previously, `b` in the test case would have been incorrectly locked to
the path of `a`. I've moved `relative_to` into uv-fs since it's now used
in two different places.

Previously failing lockfile when `a/pyproject.toml` and
`a/b/pyproject.toml` exist (not in a workspace) and `a` was depending on
`b`:

```toml
version = 1
requires-python = ">=3.11, <3.13"

[[distribution]]
name = "b"
version = "0.1.0"
source = "directory+/home/konsti/projects/uv/a"
sdist = { path = "/home/konsti/projects/uv/a" }

[[distribution]]
name = "black"
version = "0.1.0"
source = "editable+."
sdist = { path = "." }

[[distribution.dependencies]]
name = "b"
version = "0.1.0"
source = "directory+/home/konsti/projects/uv/a"
```
2024-06-13 11:51:08 -04:00
Zanie Blue 89daa51dbe
Add support for listing system toolchains (#4172)
Includes system interpreters in `uv toolchain list`.

This includes a refactor of `find_toolchain` to support iterating over
all toolchains
that match a request rather than ending earlier.
2024-06-13 10:25:30 -05:00
Charlie Marsh b1bf7f0524
Ignore `compile_invalid_pyc_invalidation_mode` on macOS (#4305)
## Summary

This keeps failing in CI.
2024-06-13 10:08:28 -04:00
Brian Mego cd461f1243
Allow `--no-binary` with `uv pip compile` (#4301)
## Summary

This i still a draft, but it gets some of the work started on issue
#4064 , which requests --no-binary functionality similar to `uv pip
install` to exist on `uv pip compile`.

So far this has moved the command line shape from install and cloned it
over to compile. The actual functionality of respecting --no-binary
<package> and generating the resulting line in requirements.txt I could
use a hand with.

My understanding is we want to create a requirements.in file such as:

```
yt
```

Then when running `cargo run -- pip compile --no-binary yt
requirements.in`
we want the file to have this line in it:

```
yt==4.3.1 --no-binary yt
```

## Test Plan

Existing unit tests continue to pass.
No new unit tests have been created yet.
The new command line options do show up when testing with `cargo run --
pip compile -h`

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2024-06-13 09:59:03 -04:00
Charlie Marsh 5d1305aa6b
Respect workspace-wide `requires-python` in interpreter selection (#4298)
## Summary

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

## Test Plan

Ran `cargo run lock --verbose` from
`scripts/workspaces/albatross-virtual-workspace`:

```
DEBUG uv 0.2.11 (ef3bc1612 2024-06-12)
warning: `uv lock` is experimental and may change without warning.
DEBUG Found workspace root: `/Users/crmarsh/workspace/puffin/scripts/workspaces/albatross-virtual-workspace`
DEBUG Adding discovered workspace member: /Users/crmarsh/workspace/puffin/scripts/workspaces/albatross-virtual-workspace/packages/albatross
DEBUG Adding discovered workspace member: /Users/crmarsh/workspace/puffin/scripts/workspaces/albatross-virtual-workspace/packages/bird-feeder
DEBUG Adding discovered workspace member: /Users/crmarsh/workspace/puffin/scripts/workspaces/albatross-virtual-workspace/packages/seeds
DEBUG Searching for Python >=3.12 in search path or managed toolchains
DEBUG Searching for managed toolchains at `/Users/crmarsh/Library/Application Support/uv/toolchains`
DEBUG Found managed toolchain `cpython-3.12.3-macos-aarch64-none`
DEBUG Found CPython 3.12.3 at `/Users/crmarsh/Library/Application Support/uv/toolchains/cpython-3.12.3-macos-aarch64-none/install/bin/python3` (managed toolchains)
Using Python 3.12.3 interpreter at: /Users/crmarsh/Library/Application Support/uv/toolchains/cpython-3.12.3-macos-aarch64-none/install/bin/python3
```
2024-06-13 12:55:56 +00:00
Zanie Blue b43de79275
Fix incorrect parsing of requested Python version as empty version specifiers (#4289)
Before 0.2.10 we would parse `--python=python` as an executable name.
After https://github.com/astral-sh/uv/pull/4214, we started treating
this as a Python version range request (with an empty version range).
This is not entirely unreasonable, but it was an unexpected regression
and I don't think `VersionRequest` should support empty ranges in its
`from_str` implementation without more consideration.
2024-06-12 19:48:59 -05:00
Charlie Marsh a547d7f9dc
Hide `--no-system` from the CLI (#4292) 2024-06-12 20:22:34 -04:00
Charlie Marsh 544b900432
Tweak copy on some command-line arguments (#4293) 2024-06-12 20:18:22 -04:00
Zanie Blue 5a007b6b9f
Add `BuildOptions` for centralized combination of `NoBuild` and `NoBinary` (#4284)
As requested in review of https://github.com/astral-sh/uv/pull/4067
2024-06-12 21:33:33 +00:00
Zanie Blue 1ab4041baa
Allow specific `--only-binary` and `--no-binary` packages to override `:all:` (#4067)
Updates `--no-binary <package>` to take precedence over `--only-binary
:all:` and `--only-binary <package>` to take precedence over
`--no-binary :all:`.

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

Closes https://github.com/astral-sh/uv/issues/4063
2024-06-12 15:47:45 -05:00
Charlie Marsh cf830288f3
Rename some internal settings structs (#4288)
## Summary

In preparation for future refactors.
2024-06-12 20:35:41 +00:00
Charlie Marsh d8f1de6134
Use separate path types for directories and files (#4285)
## Summary

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

Closes https://github.com/astral-sh/uv/issues/4286.
2024-06-12 15:54:01 -04:00
Zanie Blue 3910b7a90c
Respect `requires-python` in `uv lock` (#4282)
We weren't using the common interface in `uv lock` because it didn't
support finding an interpreter without touching the virtual environment.
Here I refactor the project interface to support what we need and update
`uv lock` to use the shared implementation.
2024-06-12 13:19:00 -05:00
Andrew Gallant e6d0c4d9fe uv/tests: add Requires-Python packse tests
Ref https://github.com/astral-sh/packse/pull/187
Ref https://github.com/astral-sh/packse/pull/188
Ref https://github.com/astral-sh/packse/pull/189
2024-06-12 13:30:47 -04:00
Andrew Gallant 75b323232d uv-resolver: use Requires-Python to filter dependencies during universal resolution
In the time before universal resolving, we would always pass a
`MarkerEnvironment`, and this environment would capture any relevant
`Requires-Python` specifier (including if `-p/--python` was provided on
the CLI).

But in universal resolution, we very specifically do not use a
`MarkerEnvironment` because we want to produce a resolution that is
compatible across potentially multiple environments. This in turn meant
that we lost `Requires-Python` filtering.

This PR adds it back. We do this by converting our `PythonRequirement`
into a `MarkerTree` that encodes the version specifiers in a
`Requires-Python` specifier. We then ask whether that `MarkerTree` is
disjoint with a dependency specification's `MarkerTree`. If it is, then
we know it's impossible for that dependency specification to every be
true, and we can completely ignore it.
2024-06-12 13:30:47 -04:00
Charlie Marsh c32667caec
Avoid treating direct path archives as always dynamic (#4283)
## Summary

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

I want to fix the TODO properly but I will do so in a separate PR.
2024-06-12 17:28:29 +00:00
Charlie Marsh baee826517
Use `FxHashMap` for available versions (#4278)
## Summary

I don't think we ever iterate over these in-order so I'd rather use
`FxHash` to avoid creating the appearance that the order matters.
2024-06-12 13:16:37 -04:00
Charlie Marsh 44f1afd6b0
Use registry URL for fetching source distributions from lockfile (#4280)
## Summary

This is just a logic bug with no testing. We were using the registry URL
(like `https://pypi.org/simple`) as the URL from which a source
distribution should be downloaded.

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

## Test Plan

`cargo test`
2024-06-12 17:01:29 +00:00
Charlie Marsh 16b4a886a8
Use consistent order for extra groups in lockfile (#4275)
## Summary

Closes #4274.
2024-06-12 11:46:16 -04:00
Charlie Marsh aef74dac2c
Allow normalization to completely eliminate markers (#4271)
## Summary

`normalize` now takes an owned value and returns `Option<MarkerTree>`,
such that if any sub-expression evaluates to `true`, we can normalize
out the entire marker.

Closes https://github.com/astral-sh/uv/issues/4267.
2024-06-12 10:25:43 -04:00
Zanie Blue f7f55ede2f
Refactor `uv-toolchain::platform` to use `target-lexicon` (#4236)
Closes https://github.com/astral-sh/uv/issues/3857

Instead of using custom `Arch`, `Os`, and `Libc` types I just use
`target-lexicon`'s which enumerate way more variants and implement
display and parsing. We use a wrapper type to represent a couple special
cases to support the "x86" alias for "i686" and "macos" for "darwin".
Alternatively we could try to use our `platform-tags` types but those
capture more information (like operating system versions) that we don't
have for downloads.

As discussed in https://github.com/astral-sh/uv/pull/4160, this is not
sufficient for proper libc detection but that work is larger and will be
handled separately.
2024-06-12 09:11:56 -05:00
Nicolas Delaby 5a09c26e77
Fix doc for `uv add` cli command s/remove/add/ (#4269)
## Summary

Fix the docsting where `remove` was used instead of `add` in the context
of `uv add` command.

## Test Plan

```
cargo run -- add --help
```
```
Add one or more packages to the project requirements

Usage: uv add [OPTIONS] <REQUIREMENTS>...

Arguments:
  <REQUIREMENTS>...
          The packages to add, as PEP 508 requirements (e.g., `flask==2.2.3`)

```
2024-06-12 13:44:08 +00:00
Charlie Marsh 5e7b98d3e7
Use relative path for lib64 symlink (#4268)
## Summary

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

## Test Plan

```
❯ ls -l .venv
total 16
-rw-r--r--   1 crmarsh  staff   43 Jun 12 09:23 CACHEDIR.TAG
drwxr-xr-x  14 crmarsh  staff  448 Jun 12 09:23 bin
drwxr-xr-x   3 crmarsh  staff   96 Jun 12 09:23 lib
lrwxr-xr-x   1 crmarsh  staff    3 Jun 12 09:23 lib64 -> lib
-rw-r--r--   1 crmarsh  staff  174 Jun 12 09:23 pyvenv.cfg
```

```
❯ ls .venv/lib64/
python3.12
```
2024-06-12 09:36:27 -04:00
Charlie Marsh 034b4790ea
Add uv version to debug output (#4259)
## Summary

I think this is a useful piece of connective tissue that will let us
avoid back-and-forths when folks include traces.

## Test Plan

```
❯ cargo run pip list --verbose
DEBUG uv 0.2.11 (44041bccd 2024-06-11)
DEBUG Searching for Python interpreter in virtual environments
DEBUG Found CPython 3.12.3 at `/Users/crmarsh/workspace/puffin/.venv/bin/python3` (virtual environment)
DEBUG Using Python 3.12.3 environment at .venv/bin/python3
```
2024-06-11 22:59:31 -04:00
Charlie Marsh 8a8e1af513
Deduplicate markers during normalization (#4263)
## Summary

We need to sort _before_ deduplicating; otherwise, we can't detect
adjacent elements, so we aren't guaranteed to deduplicate anything.
2024-06-12 02:38:15 +00:00
Charlie Marsh cc2e9ec111
DRY up index argument parsing (#4262)
## Summary

Stealing this from @ibraheemdev's
https://github.com/astral-sh/uv/pull/4237 because it's a nice, isolated
change and I'm about to build atop it.
2024-06-11 22:25:28 -04:00
Charlie Marsh a1aa35b640
Move project commands into their own subcommand struct (#4261)
## Summary

No changes to the CLI itself (since this is flattened); just code
reorganization.
2024-06-12 02:18:16 +00:00
Charlie Marsh 22795f85bc
Flatten ORs and ANDs in marker construction (#4260)
## Summary

If we're ORing an OR, we should just append rather than nesting in
another OR.

In my branch, this let us simplify:

```
python_version < '3.10' or python_version > '3.12' or (python_version < '3.8' or python_version > '3.12')
```

To:

```
python_version < '3.10' or python_version > '3.12
```
2024-06-11 21:44:49 -04:00
Charlie Marsh 44041bccd2
Bump version to v0.2.11 (#4258) 2024-06-11 20:47:25 -04:00
Charlie Marsh 44592681a0
Represent build tag as `u64` (#4253)
## Summary

The build tags in this case are like, e.g., `202206090410`. That's
larger than a `u32`, so we're rejecting the wheel. In theory build tags
could be even larger, but we already use `u64` for version segment so I
think it's fine to keep that constraint here.

I'm going to look into surfacing these errors separately.

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

## Test Plan

`cargo run pip install monailabel`
2024-06-11 21:40:08 +00:00
Charlie Marsh 6dae1920af
Make missing `METADATA` file a recoverable error (#4247)
## Summary

I don't have a great way to test it, but this makes the error described
in https://github.com/astral-sh/uv/issues/4246 an incompatibility rather
than a fatal error.

Closes https://github.com/astral-sh/uv/issues/4246.
2024-06-11 19:49:38 +00:00
Zanie Blue 8cfe202e4e
Improve output when an older toolchain version is already installed (#4248)
e.g.

```
❯ uv toolchain install
Found installed toolchain 'cpython-3.9.19-macos-aarch64-none'
A toolchain is already installed. Use `uv toolchain install <request>` to install a specific toolchain
```

instead of

```
❯ uv toolchain install
Using latest Python version
Found installed toolchain 'cpython-3.9.19-macos-aarch64-none'
Already installed at /Users/zb/Library/Application Support/uv/toolchains/cpython-3.9.19-macos-aarch64-none
```
2024-06-11 19:49:15 +00:00
Charlie Marsh dce913c542
Warn when 'requires-python' does not include a lower bound (#4234)
## Summary

Closes https://github.com/astral-sh/uv/issues/4089.
2024-06-11 18:50:05 +00:00
Charlie Marsh b3a99d9ff9
Allow direct URLs for dev dependencies (#4233)
## Summary

Ensures that they're included in the lookahead resolver.

Closes https://github.com/astral-sh/uv/issues/4230.
2024-06-11 15:30:34 +00:00
Ibraheem Ahmed 3ea5a2a65d
De-duplicate resolution environment logic (#4232)
## Summary

Cleans up some duplicated logic in `pip install/sync/compile`. Will also
be needed for `uv add`.
2024-06-11 11:13:30 -04:00
Ibraheem Ahmed a75ed22a2f
Fix outdated comment (#4229)
## Summary

Looks like this wasn't updated at some point. I think it's referring to
`UnresolvedRequirement`?
2024-06-11 16:06:47 +02:00
Ibraheem Ahmed eefa9e62fc
Initial implementation of `uv add` and `uv remove` (#4193)
## Summary

Basic implementation of `uv add` and `uv remove` that supports writing
PEP508 requirements to `project.dependencies`.

First step for https://github.com/astral-sh/uv/issues/3959 and
https://github.com/astral-sh/uv/issues/3960.
2024-06-11 09:21:28 -04:00
Nyakku Shigure 60431ce78c
Replace `toolchain fetch` with `toolchain install` (#4228)
## Summary

Something that looks like it was forgotten to replace in #4164.

## Test Plan

Run `cargo run toolchain install` should display the warning: ``warning:
`uv toolchain install` is experimental and may change without warning.``
2024-06-11 08:00:33 -04:00
konsti 44833801b3
Support locking relative paths (#4205)
By splitting `path` into a lockable, relative (or absolute) and an
absolute installable path and by splitting between urls and paths by
dist type, we can store relative paths in the lockfile.
2024-06-11 11:58:03 +00:00
Charlie Marsh 33cf47182f
Migrate lock errors to `thiserror` (#4225)
## Summary

Do we prefer this?
2024-06-11 07:40:48 -04:00
Charlie Marsh 656fc427b9
Add support for local directories with `--index-url` (#4226)
## Summary

Closes #4078.
2024-06-10 22:27:04 -04:00
Zanie Blue f296ef08d6
Refactor project interpreter request for `requires-python` specifiers (#4216)
Refactor following #4214 to avoid parsing the specifiers again
2024-06-10 20:32:40 -05:00
samypr100 68abf85f0d
feat: mTLS support (#4171)
## Summary

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

This adds mTLS support to uv via the standard env var `SSL_CLIENT_CERT`.

## Test Plan

Tested locally using a [nginx proxy to
pypi](https://github.com/hauntsaninja/nginx_pypi_cache) using my own
self-signed ca + certs + client certs generated via
[mkcert](https://github.com/FiloSottile/mkcert). Used this proxy with
both uv and pip to make sure we have feature partity in mTLS
functionality.
2024-06-10 20:11:35 -05:00
Zanie Blue 5f37395f45
Allow version specifiers to be used in Python version requests (#4214)
In service of https://github.com/astral-sh/uv/issues/4212 but this is
user-facing e.g. Python discovery will support version specifiers
everywhere now.

Closes https://github.com/astral-sh/uv/issues/4212
2024-06-10 18:20:09 -05:00
Charlie Marsh 10e0abc9b1
Create temporary environments in dedicated cache bucket (#4223)
## Summary

We may choose to persist these eventually, but for now, it's useful to
have them colocated with the cache, and in their own dedicated bucket
(so, at the very least, we can keep track of the use-cases).

Closes https://github.com/astral-sh/uv/issues/4219.
2024-06-10 23:17:35 +00:00
Zanie Blue b5c9003883
Fix `pip_compile::missing_venv` test (#4224)
A merge kerfuffle from #4222  and #4218 

Now we fail because we genuinely can't find any interpreters since tests
contexts are isolated by default. I'll improve the error message and
maybe add another test case once `main` is fixed.
2024-06-10 22:39:25 +00:00
Zanie Blue 546e23bb1d
Update test context to avoid discovery of external Pythons (#4222)
By setting the test search path to an empty path, we avoid accidentally
pulling interpreters from the system during a test case.

Cherry-picked from https://github.com/astral-sh/uv/pull/4214
2024-06-10 17:26:53 -05:00
Zanie Blue 98d1ea6bb0
Improve handling of missing interpreters during discovery (#4218)
Cherry-picked from https://github.com/astral-sh/uv/pull/4214

The first commit gets us some context on an IO error during queries:

Previously:

```
failed to canonicalize path `[VENV]/bin/python3`
    Caused by: No such file or directory (os error 2)
```

Now:

```
Failed to query Python interpreter
    Caused by: failed to canonicalize path `[VENV]/bin/python3`
    Caused by: No such file or directory (os error 2)
```

but really we shouldn't attempt to query a missing interpreter during
discovery anyway, so we improve handling of that too.
2024-06-10 22:26:34 +00:00
Charlie Marsh 0c1dcb797a
Remove usages of verbatim URL in URL resolver (#4221)
## Summary

Should be no behavior changes, but one piece of technical debt I noticed
left over in the URL resolver. We already have structured paths, so we
shouldn't need to compare verbatim URLs.
2024-06-10 21:55:48 +00:00
Zanie Blue fd52fe74ce
Update the `Toolchain::find_requested` API to take a parsed request (#4215)
Pulled out of https://github.com/astral-sh/uv/pull/4206, need this for
#4214
2024-06-10 20:07:45 +00:00
Charlie Marsh d7e10bb4a2
Remove project dependency from `sync` (#4211)
## Summary

This is architecturally desirable because it means syncing is
independent from the project (e.g., the `pyproject.toml` and friends).
2024-06-10 19:23:37 +00:00
Charlie Marsh e31604e38b
Always install as editable when duplicates are requested (#4208)
## Summary

If the user requests a package as both editable and non-editable, the
editable now "wins".

Previously, `pip install -e . .` would install as editable. However,
`pip install -e . -r requirements.txt` would _not_ if `requirements.txt`
contained `.`, because we ignored `editable` when deduplicating and the
order of iteration was just dependent on internals.

Closes https://github.com/astral-sh/uv/issues/4053.
2024-06-10 15:02:17 -04:00
Zanie Blue 06a0fc65d4
Improve `uv toolchain list` implementation (#4203)
Amends #4163 with review from Jane, thank you!

No behavior changes.
2024-06-10 17:49:17 +00:00
Charlie Marsh 652c1126d3
Avoid crash for `XDG_CONFIG_HOME=/dev/null` (#4200)
## Summary

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

## Test Plan

`XDG_CONFIG_HOME=/dev/null cargo run venv`
2024-06-10 17:36:29 +00:00
Zanie Blue 907727cb1b
Bump version to 0.2.10 (#4201) 2024-06-10 11:40:19 -05:00
Zanie Blue 14d535f384
Add `uv toolchain install` (#4164)
Adds a command (following #4163) to download and install specific
toolchains. While we fetch toolchains on demand, this is useful for,
e.g., pre-downloading a toolchain in a Docker image build.

~I kind of think we should call this `install` instead of `fetch`~ I
changed the name from `fetch` to `install`.
2024-06-10 10:56:08 -05:00
konsti 90947a933d
Recreate project environment if `--python` or `requires-python` doesn't match (#3945)
Fixes #4131
Fixes #3895
2024-06-10 14:36:14 +00:00
Charlie Marsh 125a4b220e
Improve static metadata extraction for Poetry projects (#4182)
## Summary

Adds handling for a few cases to improve interoperability with Poetry:

- If the `project` schema is invalid, we now raise a hard error, rather
than treating the metadata as dynamic and then falling back to the build
backend. This could cause problems, I'm not sure. It's stricter than
before.
- If the project contains `tool.poetry` but omits
`project.dependencies`, we now treat it as dynamic. We could go even
further and treat _any_ Poetry project as dynamic, but then we'd be
ignoring user-declared dependencies, which is also confusing.

Closes https://github.com/astral-sh/uv/issues/4142.
2024-06-10 10:26:38 -04:00
Zanie Blue c6da4f15b7
Add `uv toolchain list` (#4163)
Adds the `uv toolchain` namespace and a `list` command to get us
started.

```
❯ cargo run -q -- toolchain list
warning: `uv toolchain list` is experimental and may change without warning.
3.8.12   (cpython-3.8.12-macos-aarch64-none)
3.8.13   (cpython-3.8.13-macos-aarch64-none)
3.8.14   (cpython-3.8.14-macos-aarch64-none)
3.8.15   (cpython-3.8.15-macos-aarch64-none)
3.8.16   (cpython-3.8.16-macos-aarch64-none)
3.8.17   (cpython-3.8.17-macos-aarch64-none)
3.8.18   (cpython-3.8.18-macos-aarch64-none)
3.8.18   (cpython-3.8.18-macos-aarch64-none)
3.8.19   (cpython-3.8.19-macos-aarch64-none)
3.9.2    (cpython-3.9.2-macos-aarch64-none)
3.9.3    (cpython-3.9.3-macos-aarch64-none)
3.9.4    (cpython-3.9.4-macos-aarch64-none)
3.9.5    (cpython-3.9.5-macos-aarch64-none)
3.9.6    (cpython-3.9.6-macos-aarch64-none)
3.9.7    (cpython-3.9.7-macos-aarch64-none)
3.9.10   (cpython-3.9.10-macos-aarch64-none)
3.9.11   (cpython-3.9.11-macos-aarch64-none)
3.9.12   (cpython-3.9.12-macos-aarch64-none)
3.9.13   (cpython-3.9.13-macos-aarch64-none)
3.9.14   (cpython-3.9.14-macos-aarch64-none)
3.9.15   (cpython-3.9.15-macos-aarch64-none)
3.9.16   (cpython-3.9.16-macos-aarch64-none)
3.9.17   (cpython-3.9.17-macos-aarch64-none)
3.9.18   (cpython-3.9.18-macos-aarch64-none)
3.9.19   (cpython-3.9.19-macos-aarch64-none)
3.10.0   (cpython-3.10.0-macos-aarch64-none)
3.10.2   (cpython-3.10.2-macos-aarch64-none)
3.10.3   (cpython-3.10.3-macos-aarch64-none)
3.10.4   (cpython-3.10.4-macos-aarch64-none)
3.10.5   (cpython-3.10.5-macos-aarch64-none)
3.10.6   (cpython-3.10.6-macos-aarch64-none)
3.10.7   (cpython-3.10.7-macos-aarch64-none)
3.10.8   (cpython-3.10.8-macos-aarch64-none)
3.10.9   (cpython-3.10.9-macos-aarch64-none)
3.10.11  (cpython-3.10.11-macos-aarch64-none)
3.10.12  (cpython-3.10.12-macos-aarch64-none)
3.10.13  (cpython-3.10.13-macos-aarch64-none)
3.10.14  (cpython-3.10.14-macos-aarch64-none)
3.11.1   (cpython-3.11.1-macos-aarch64-none)
3.11.3   (cpython-3.11.3-macos-aarch64-none)
3.11.4   (cpython-3.11.4-macos-aarch64-none)
3.11.5   (cpython-3.11.5-macos-aarch64-none)
3.11.6   (cpython-3.11.6-macos-aarch64-none)
3.11.7   (cpython-3.11.7-macos-aarch64-none)
3.11.8   (cpython-3.11.8-macos-aarch64-none)
3.11.9   (cpython-3.11.9-macos-aarch64-none)
3.12.0   (cpython-3.12.0-macos-aarch64-none)
3.12.1   (cpython-3.12.1-macos-aarch64-none)
3.12.2   (cpython-3.12.2-macos-aarch64-none)
3.12.3   (cpython-3.12.3-macos-aarch64-none)
```

Closes https://github.com/astral-sh/uv/issues/4189
2024-06-10 09:22:00 -05:00
Zanie Blue a2e6aaa0ff
Fetch managed toolchains in `uv run` (#4143) 2024-06-10 14:20:44 +00:00
Zanie Blue 45df889fe4
Implement `Toolchain::find_or_fetch` and use in `uv venv --preview` (#4138)
Extends https://github.com/astral-sh/uv/pull/4121
Part of #2607 

Adds support for managed toolchain fetching to `uv venv`, e.g.

```
❯ cargo run -q -- venv --python 3.9.18 --preview -v
DEBUG Searching for Python 3.9.18 in search path or managed toolchains
DEBUG Searching for managed toolchains at `/Users/zb/Library/Application Support/uv/toolchains`
DEBUG Found CPython 3.12.3 at `/opt/homebrew/bin/python3` (search path)
DEBUG Found CPython 3.9.6 at `/usr/bin/python3` (search path)
DEBUG Found CPython 3.12.3 at `/opt/homebrew/bin/python3` (search path)
DEBUG Requested Python not found, checking for available download...
DEBUG Using registry request timeout of 30s
INFO Fetching requested toolchain...
DEBUG Downloading https://github.com/indygreg/python-build-standalone/releases/download/20240224/cpython-3.9.18%2B20240224-aarch64-apple-darwin-pgo%2Blto-full.tar.zst to temporary location /Users/zb/Library/Application Support/uv/toolchains/.tmpgohKwp
DEBUG Extracting cpython-3.9.18%2B20240224-aarch64-apple-darwin-pgo%2Blto-full.tar.zst
DEBUG Moving /Users/zb/Library/Application Support/uv/toolchains/.tmpgohKwp/python to /Users/zb/Library/Application Support/uv/toolchains/cpython-3.9.18-macos-aarch64-none
Using Python 3.9.18 interpreter at: /Users/zb/Library/Application Support/uv/toolchains/cpython-3.9.18-macos-aarch64-none/install/bin/python3
Creating virtualenv at: .venv
INFO Removing existing directory
Activate with: source .venv/bin/activate
```

The preview flag is required. The fetch is performed if we can't find an
interpreter that satisfies the request. Once fetched, the toolchain will
be available for later invocations that include the `--preview` flag.
There will be follow-ups to improve toolchain management in general,
there is still outstanding work from the initial implementation.
2024-06-10 14:10:45 +00:00
Charlie Marsh 04c4da4e65
Fix `>=` to `==` typo in `is_contained_by` docs (#4196) 2024-06-10 13:28:33 +00:00
Charlie Marsh 72bc739a64
Remove `PubGrubPackage` dependency from `ResolutionGraph` (#4168)
## Summary

Similar to how we abstracted the dependencies into
`ResolutionDependencyNames`, I think it makes sense to abstract the base
packages into a `ResolutionPackage`. This also avoids leaking details
about the various `PubGrubPackage` enum variants to `ResolutionGraph`.
2024-06-10 12:50:32 +00:00
konsti 18b40b0c7d
Don't panic with invalid wheel source (#4191)
Remove the panic when there is an invalid wheel source, instead surface
the error. This error can only occur when manually editing the lock
file, but since it's an external file, we should error and not panic.

This change is helpful since the method needs to be able to error for
relative path support.
2024-06-10 08:44:36 -04:00
Charlie Marsh 763e2d2e84
Add markers to edges rather than distributions (#4166)
## Summary

We've debated this a bit but the thing that tipped me over the edge is
https://github.com/astral-sh/uv/issues/4157. As-is, there's no way to
represent "a package should be installed, but the extra should only be
installed conditionally based on the markers", because the markers sit
on the _distribution_. By placing the markers on the edge, we can now
represent scenarios that weren't previously representable.

Closes https://github.com/astral-sh/uv/issues/4137.
Closes https://github.com/astral-sh/uv/issues/4125.
Closes https://github.com/astral-sh/uv/issues/4157.
2024-06-10 08:40:51 -04:00
Charlie Marsh 5269a0dba8
Ignore tags in universal resolution (#4174)
## Summary

If a package lacks a source distribution, and we can't find a compatible
wheel for the current platform, we need to just _assume_ that the
package will have a valid wheel on all platforms on which it's
requested; if not, we raise an error at install time.

It's possible that we can be smarter about this over time. For example,
if the package was requested _only_ for macOS, we could verify that
there's at least one macOS-compatible wheel. See the linked issue for
more details.

Closes https://github.com/astral-sh/uv/issues/4139.
2024-06-10 08:38:21 -04:00
Charlie Marsh 4125cb26b8
Add `pyproject.toml` to CLI help (#4181) 2024-06-09 22:48:39 -04:00
Charlie Marsh e7c573cfcb
Fix existing typos and enable `typos` in CI (#4184) 2024-06-10 01:50:54 +00:00
Charlie Marsh 04717e1a92
Respect `--find-links` in `lock` and `sync` (#4183)
## Summary

We already respect this command-line argument, I just forgot to wire it
up to the resolver.
2024-06-09 21:42:52 -04:00
Charlie Marsh 72859d8f9b
Move PEP 440 and PEP 508 parsing out of TOML deserialization (#4176)
## Summary

If we want more granular control over how these errors are handled, then
we need to move them out of the TOML deserialization.

No actual behavior changes here.

Part of https://github.com/astral-sh/uv/issues/4142.
2024-06-10 00:09:39 +00:00
Charlie Marsh a761047df9
Reduce visibility of `pyproject.toml` fields (#4175) 2024-06-09 23:57:43 +00:00
Charlie Marsh 8ae5c2aee3
Skip version iteration for non-base packages (#4167) 2024-06-08 18:46:08 +00:00
Charlie Marsh ab0f8afe1f
Remove version from graph edge (#4165)
## Summary

We're actually not using the edge data, so lets remove it.
2024-06-08 17:39:02 +00:00
Zanie Blue 7c07ca8090
Fix test snapshot for `lock_conditional_dependency_extra` (#4159)
Introduced in #4156 and is failing on main
2024-06-08 12:04:44 -05:00
Charlie Marsh 477c860c9b
Add incorrect conditional-extra test (#4156) 2024-06-07 21:24:35 -04:00
Charlie Marsh eb239ff640
Cap `Requires-Python` comparisons at the patch version (#4150)
## Summary

See the long comment inline. I think this is debatable but probably
right for now. The other options have their own problems, but there are
a few alternate ideas in the comment.

Closes https://github.com/astral-sh/uv/issues/4132.
2024-06-08 01:22:57 +00:00
Charlie Marsh ac1ddf5e4e
Allow transitive URLs via recursive extras (#4155)
## Summary

Closes https://github.com/astral-sh/uv/issues/4152.
2024-06-08 01:10:18 +00:00
Andrew Gallant c46fa74e65
make universal resolver fork only when markers are disjoint (#4135)
The basic idea here is to make it so forking can only ever result in a
resolution that, for a particular marker environment, will only install
at most one version of a package. We can guarantee this by ensuring we
only fork on conflicting dependency specifications only when their
corresponding markers are completely disjoint. If they aren't, then
resolution _must_ find a single version of the package in the
intersection of the two dependency specifications.

A test for this case has been added to packse here:
https://github.com/astral-sh/packse/pull/182. Previously, that test
would result in a resolution with two different unconditional versions
of the same package. With this change, resolution fails (as it should).

A commit-by-commit review should be helpful here, since the first commit
is a refactor to make the second commit a bit more digestible.
2024-06-07 23:40:55 +00:00
Charlie Marsh 0db1bf4df7
Avoid pre-fetching for unbounded minimum versions (#4149)
## Summary

I think we should be able to model PubGrub such that this isn't
necessary (at least for the case described in the issue), but for now,
let's just avoid attempting to build very old distributions in
prefetching.

Closes https://github.com/astral-sh/uv/issues/4136.
2024-06-07 22:05:14 +00:00
Charlie Marsh d7cc622d6c
Accept `file://` URLs for `requirements.txt` et all references (#4145)
## Summary

Closes https://github.com/astral-sh/uv/issues/4124.
2024-06-07 22:03:08 +00:00
Zanie Blue e3b274413d
Do not create a virtual environment when locking (#4147)
Closes https://github.com/astral-sh/uv/issues/4141
2024-06-07 16:56:45 -05:00
Zanie Blue f9ea304be4
Drop "registry" prefix from request timeout log (#4144)
We use this base client for more than registry requests
2024-06-07 16:56:32 -05:00
Zanie Blue 13f03e9d3f
Reduce `uv-toolchain` discovery API to `Toolchain` (#4148)
Drops `find_toolchain`, `find_best_toolchain`, etc. in favor of
`Toolchain::find_...`

We can change this in the future, but there should only be one "right"
way to do it not two redundant ways in the public interface.
2024-06-07 16:56:25 -05:00
Zanie Blue 365bcfce1a
Update `init_environment` to use `Toolchain::find_default` API (#4146)
In service of https://github.com/astral-sh/uv/pull/4148
2024-06-07 16:16:58 -05:00
Ibraheem Ahmed 7232c53718
Simplify marker expressions in lockfile (#4066)
## Summary

Simplify and normalize marker expressions in the lockfile. Right now
this does a simple analysis by only looking at related operators at the
same level of precedence. I think anything more complex would be out of
scope.

Resolves https://github.com/astral-sh/uv/issues/4002.
2024-06-07 16:14:24 -04:00
Charlie Marsh bcfe88dfdc
Track `Markers` via a PubGrub package variant (#4123)
## Summary

This PR adds a lowering similar to that seen in
https://github.com/astral-sh/uv/pull/3100, but this time, for markers.
Like `PubGrubPackageInner::Extra`, we now have
`PubGrubPackageInner::Marker`. The dependencies of the `Marker` are
`PubGrubPackageInner::Package` with and without the marker.

As an example of why this is useful: assume we have `urllib3>=1.22.0` as
a direct dependency. Later, we see `urllib3 ; python_version > '3.7'` as
a transitive dependency. As-is, we might (for some reason) pick a very
old version of `urllib3` to satisfy `urllib3 ; python_version > '3.7'`,
then attempt to fetch its dependencies, which could even involve
building a very old version of `urllib3 ; python_version > '3.7'`. Once
we fetch the dependencies, we would see that `urllib3` at the same
version is _also_ a dependency (because we tack it on). In the new
scheme though, as soon as we "choose" the very old version of `urllib3 ;
python_version > '3.7'`, we'd then see that `urllib3` (the base package)
is also a dependency; so we see a conflict before we even fetch the
dependencies of the old variant.

With this, I can successfully resolve the case in #4099.

Closes https://github.com/astral-sh/uv/issues/4099.
2024-06-07 19:57:02 +00:00
Zanie Blue 0f4f3b4714
Update `uv run` and `uv tool run` to use `Toolchain::find` (#4134)
Extends https://github.com/astral-sh/uv/pull/4121
2024-06-07 19:28:59 +00:00
Zanie Blue 53035d65a1
Refactor `uv-toolchain` types (#4121)
Extends #4120 
Part of #2607 

There should be no behavior changes here. Restructures the discovery API
to be focused on a toolchain first perspective in preparation for
exposing a `find_or_fetch` method for toolchains in
https://github.com/astral-sh/uv/pull/4138.
2024-06-07 14:20:28 -05:00
Zanie Blue 325982c418
Rename `uv-interpreter` crate to `uv-toolchain` (#4120)
In preparation for managed toolchains #2607, just renames the crate to
something broader.

See #4121 and https://github.com/astral-sh/uv/pull/4138 to see the final
intent.
2024-06-07 13:59:14 -05:00
Charlie Marsh 2803a8c475
Omit URL dependencies from pre-release hints (#4140)
## Summary

Closes https://github.com/astral-sh/uv/issues/4127.
2024-06-07 18:43:50 +00:00
Charlie Marsh 7d1b7b99d9
Rename `Dependency.id` to `Dependency.distribution_id` (#4114)
## Summary

I think this makes clearer that the `Dependency.id` is not an identifier
for the dependency itself.

No functional changes.
2024-06-07 18:28:54 +00:00
Charlie Marsh fa10679275
Add extra and dev dependency validation to lockfile (#4112)
## Summary

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

Closes https://github.com/astral-sh/uv/issues/4115.
2024-06-07 14:18:31 -04:00
Charlie Marsh d3651c13f0
Set `--dev` to default for `uv run` and `uv sync` (#4118)
## Summary

Closes https://github.com/astral-sh/uv/issues/4117.
2024-06-07 00:06:05 +00:00
Zanie Blue dcf70a1f29
Include non-standard ports in keyring host queries (#4061)
Partially addresses https://github.com/astral-sh/uv/issues/4056

We were incorrectly omitting the port from requests to `keyring` when
falling back to a realm/host query, e.g. `localhost` was used instead of
`localhost:1234`. We still won't include "standard" ports like `80` for
an HTTP request.
2024-06-06 19:02:47 -05:00
Zanie Blue cb7d6245ae
Use `PythonEnvironment` API in `uv pip compile` (#4030)
Same as https://github.com/astral-sh/uv/pull/4029
2024-06-06 18:54:40 -05:00
Charlie Marsh cc7c780523
Remove PubGrub dependency from `uv` (#4116)
## Summary

Encapsulates more of the details are `Requires-Python` and PubGrub.

Closes https://github.com/astral-sh/uv/issues/4110.
2024-06-06 23:45:58 +00:00
Charlie Marsh 52bdee2e85
Add support for `--prefix` (#4085)
## Summary

Closes #3076.
2024-06-06 16:15:28 -04:00
Charlie Marsh 677a7f157b
Avoid showing dev hints for Python requirements (#4111)
Closes https://github.com/astral-sh/uv/issues/4096.
2024-06-06 19:58:30 +00:00
konsti e4e2590076
Use union of `requires-python` in workspace (#4041)
Follow-up to #4016.

This exposes `Range` and `PubGrubSpecifier` from outside the resolver to
use pubgrub's union creating a dependency edge we don't really want.
2024-06-06 19:21:02 +00:00
konsti a6f53e2aa4
Lock all packages in workspace (#4016)
When creating a lockfile, lock the combined dependencies for all
packages in a workspace. This make the lockfile independent of where you
are in the workspace.

Fixes #3983
2024-06-06 19:09:44 +00:00
Charlie Marsh e9fc99e622
Bump version to v0.2.9 (#4107) 2024-06-06 14:21:33 -04:00
Charlie Marsh 31bb01f0be
Ignore upper-bounds on `Requires-Python` (#4086)
## Summary

This PR modifies our `Requires-Python` handling to treat
`Requires-Python` as a lower bound. There's extensive discussion around
this in https://github.com/astral-sh/uv/issues/4022 and the references
linked therein. I think it's an experiment worth trying. Even in my own
small projects, I'm running into issues whereby I'm being "forced" to
add a `<4` upper bound to my `Requires-Python` due to these caps.

Separately, we should explore adding a mechanism that's distinct from
`Requires-Python` to enable users to declare a supported range for
locking.

Closes https://github.com/astral-sh/uv/issues/4022.
2024-06-06 13:52:57 -04:00
Charlie Marsh 30e73a60de
Avoid enforcing distribution ID uniqueness for extras (#4104)
## Summary

The condition enforced here isn't quite right. The same dependency can
appear multiple times, as long as the extra is different.

Closes https://github.com/astral-sh/uv/issues/4101.
2024-06-06 15:21:31 +00:00
Charlie Marsh 8798e91dd5
Avoid extra-only filtering for constraints (#4095)
## Summary

The "only include if relevant for the extra" filtering should _not_ be
applied to constraints. Otherwise, we'd only constrain when the extra
was included in the constraints file itself, which is incorrect.

Closes https://github.com/astral-sh/uv/issues/4091.
2024-06-06 13:58:46 +00:00
konsti 39f8978920
Fix logging in uv-dev (#4093)
Set the correct default logging directive and filtering in uv-dev. See
#4090.
2024-06-06 13:06:57 +00:00
Charlie Marsh fa2b6a28bc
Prefix sys fields with `sys_` consistently on Interpreter (#4084)
## Summary

This is more consistent across the struct _and_ opens up space for
`--prefix`.
2024-06-06 02:11:21 +00:00
Charlie Marsh 120148f0a1
Remove integration tests from `uv-resolver` (#4083)
## Summary

I don't think it's worth maintaining this separate test harness for ~18
tests, when they can all be tested in the `uv` package itself. Let's
drop the maintenance burden.
2024-06-06 01:48:42 +00:00
Charlie Marsh 0acae9bd9c
Add support for development dependencies (#4036)
## Summary

Externally, development dependencies are currently structured as a flat
list of PEP 580-compatible requirements:

```toml
[tool.uv]
dev-dependencies = ["werkzeug"]
```

When locking, we lock all development dependencies; when syncing, users
can provide `--dev`.

Internally, though, we model them as dependency groups, similar to
Poetry, PDM, and [PEP 735](https://peps.python.org/pep-0735). This
enables us to change out the user-facing frontend without changing the
internal implementation, once we've decided how these should be exposed
to users.

A few important decisions encoded in the implementation (which we can
change later):

1. Groups are enabled globally, for all dependencies. This differs from
extras, which are enabled on a per-requirement basis. Note, however,
that we'll only discover groups for uv-enabled packages anyway.
2. Installing a group requires installing the base package. We rely on
this in PubGrub to ensure that we resolve to the same version (even
though we only expect groups to come from workspace dependencies anyway,
which are unique). But anyway, that's encoded in the resolver right now,
just as it is for extras.
2024-06-06 01:40:17 +00:00
Charlie Marsh a81fb92ee6
Respect existing `.egg-link` files in site packages (#4082)
## Summary

As with other `.egg-info` and `.egg-link` distributions, it's easy to
support _existing_ `.egg-link` files. Like pip, we refuse to uninstall
these, since there's no way to know which files are part of the
distribution.

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

## Test Plan

Verify that `vtk` is included here, which is installed as a `.egg-link`
file:

```
> conda create -c conda-forge -n uv-test python h5py vtk pyside6 cftime psutil

> cargo run pip freeze --python /opt/homebrew/Caskroom/miniforge/base/envs/uv-test/bin/python
aiohttp @ file:///Users/runner/miniforge3/conda-bld/aiohttp_1713964997382/work
aiosignal @ file:///home/conda/feedstock_root/build_artifacts/aiosignal_1667935791922/work
attrs @ file:///home/conda/feedstock_root/build_artifacts/attrs_1704011227531/work
cached-property @ file:///home/conda/feedstock_root/build_artifacts/cached_property_1615209429212/work
cftime @ file:///Users/runner/miniforge3/conda-bld/cftime_1715919201099/work
frozenlist @ file:///Users/runner/miniforge3/conda-bld/frozenlist_1702645558715/work
h5py @ file:///Users/runner/miniforge3/conda-bld/h5py_1715968397721/work
idna @ file:///home/conda/feedstock_root/build_artifacts/idna_1713279365350/work
loguru @ file:///Users/runner/miniforge3/conda-bld/loguru_1695547410953/work
msgpack @ file:///Users/runner/miniforge3/conda-bld/msgpack-python_1715670632250/work
multidict @ file:///Users/runner/miniforge3/conda-bld/multidict_1707040780513/work
numpy @ file:///Users/runner/miniforge3/conda-bld/numpy_1707225421156/work/dist/numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl
pip==24.0
psutil @ file:///Users/runner/miniforge3/conda-bld/psutil_1705722460205/work
pyside6==6.7.1
setuptools==70.0.0
shiboken6==6.7.1
vtk==9.2.6
wheel==0.43.0
wslink @ file:///home/conda/feedstock_root/build_artifacts/wslink_1716591560747/work
yarl @ file:///Users/runner/miniforge3/conda-bld/yarl_1705508643525/work
```
2024-06-06 01:00:00 +00:00
Zanie Blue e6817bd997
Add regression test for `VIRTUAL_ENV` and `uv venv` interaction (#4074)
For https://github.com/astral-sh/uv/pull/4073

Demonstrated to fail without those changes.
2024-06-06 00:28:45 +00:00
Zanie Blue e48b9cd94b
Bump version to 0.2.8 (#4076) 2024-06-05 21:09:05 +00:00
Zanie Blue bacde427f1
Fix `uv venv` handling when `VIRTUAL_ENV` refers to an non-existant environment (#4073)
Closes https://github.com/astral-sh/uv/issues/4072

This was an accidental change in
https://github.com/astral-sh/uv/pull/4029 in which I had updated the
pull request to support virtual environments as requested in review and
forgot to revert it.

Separately, we shouldn't fail if `VIRTUAL_ENV` points to an empty
directory and `SystemPython::Allowed` is used, will address that
separately.
2024-06-05 20:50:28 +00:00
Charlie Marsh e5f95186de
Default to current Python minor if `Requires-Python` is absent (#4070)
## Summary

If `Requires-Python` is omitted in `uv lock` or `uv run`, we now warn
and default to `>=` the current minor version.

Closes https://github.com/astral-sh/uv/issues/4050.
2024-06-05 20:45:50 +00:00
Charlie Marsh 0b6d5b37dc
Enforce `Requires-Python` when syncing (#4068)
## Summary

Ensures that we raise if the user attempts to use a Python version that
wasn't included in the locked range.

Closes https://github.com/astral-sh/uv/issues/4052.
2024-06-05 16:22:08 -04:00
Charlie Marsh 642cef0dad
Track supported Python range in lockfile (#4065)
## Summary

This PR adds the `Requires-Python` range to the user's lockfile. This
will enable us to validate it when installing.

For now, we repeat the `Requires-Python` back to the user;
alternatively, though, we could detect the supported Python range
automatically.

See: https://github.com/astral-sh/uv/issues/4052
2024-06-05 16:21:59 -04:00
konsti 8596525d97
Update pubgrub to new `add_incompatibility_from_dependencies` (#4062)
We had previously changed the signature of
`DependencyProvider::get_dependencies` to return an iterator instead of
a hashmap to avoid the conversion cost from our dependencies `Vec` to
the pubgrub's hashmap. These changes are difficult to make in pubgrub
since they complicate the public api. But we don't actually use
`DependencyProvider::get_dependencies`, so we rolled those
customizations back in https://github.com/pubgrub-rs/pubgrub/pull/226
and instead opted to change only the internal
`add_incompatibility_from_dependencies` method that we exposed in our
fork. This aligns us closer with upstream, removes the design questions
about `DependencyProvider` from our concerns and reduces our diff (not
counting the github action) to +36 -12.
2024-06-05 20:46:00 +02:00
konsti 9f1b592fca
Retry flaky `compile_invalid_pyc_invalidation_mode` test (#4043)
Retry the flaky `compile_invalid_pyc_invalidation_mode` if it fails. I
don't understand why this happening in the first place (we have code
that should catch those cases, but also those cases shouldn't be
happening at all) and this is terrible hack, but it fixes the test
flakes.

Fixes #2672
2024-06-05 20:37:17 +02:00
Charlie Marsh a241f148de
Bump version to v0.2.7 (#4060) 2024-06-05 14:25:25 -04:00
Charlie Marsh 191f9556b7
Avoid building packages with dynamic versions (#4058)
## Summary

This PR separates "gathering the requirements" from the rest of the
metadata (e.g., version), which isn't required when installing a
package's _dependencies_ (as opposed to installing the package itself).
It thus ensures that we don't need to build a package when a static
`pyproject.toml` is provided in `pip compile`.

Closes https://github.com/astral-sh/uv/issues/4040.
2024-06-05 18:11:58 +00:00
Charlie Marsh a0173760f1
Remove unused PEP 621 error (#4057) 2024-06-05 17:45:42 +00:00
Charlie Marsh c97427d530
Reduce visibility of `lowering` (#4055)
## Summary

This makes `lowering.rs` internal to the metadata package.
2024-06-05 13:39:37 -04:00
Charlie Marsh 34f847bb68
Remove unused `Requirements` struct (#4054) 2024-06-05 17:14:57 +00:00
Zanie Blue db3c36dbcc
Use `PythonEnvironment` API in `uv venv` (#4029)
There's no reason to be reaching into the lower-level `find_interpreter`
manually here.
2024-06-05 11:49:29 -05:00
konsti b05a39c735
Store explicit project on workspace member (#4048)
We know that `[project]` must exist for each workspace member, so we can
store it directly and avoid going through the `.and_then()` when we need
to access it. This requires cloning the struct due to lack of
self-referential structs. An alternative would taking the `Project` from
`PyProjectToml` instead, but this could be confusing when passing the
`PyProjectToml` around.
2024-06-05 12:48:19 -04:00
Charlie Marsh ae9610104a
Avoid dropping `pip sync` requirements with markers (#4051)
## Summary

Thankfully this is pretty rare since `pip sync` is usually run on `pip
compile` output, and `pip compile` never outputs markers.

Closes https://github.com/astral-sh/uv/issues/4044
2024-06-05 16:05:46 +00:00
Zanie Blue b0d1fc85a9
Use standard path filters for `uv venv` tests (#4046)
Over in #4045 the existing filters were insufficient. We should use the
same strategy we use for our standard `TestContext` instead.
2024-06-05 10:25:10 -05:00
Zanie Blue f2dc08b242
Drop `git` dependency from `pip_entrypoints` test (#4049)
There's a release with the changes we want test coverage for now
2024-06-05 17:22:32 +02:00
Zanie Blue 91c5ac44ac
Add `ProvidedPath` to interpreter sources considered when `UV_TEST_PYTHON_PATH` is set (#4027)
Just a theory, but I presume this would close
https://github.com/astral-sh/uv/issues/4023.

I'm not sure how else we'd end up in this case.
2024-06-05 09:52:28 -05:00
Zanie Blue 5db7f7b3ac
Move `uv-interpreter::managed::*` modules into crate top-level (#4020)
Should be no functional changes, just some file renames in preparation
for exposing toolchain management.
2024-06-05 07:27:30 -05:00
Zanie Blue 2be93c0b2c
Display selected interpreter sources during not selected error (#4026)
This should help us narrow down the weird error in
https://github.com/astral-sh/uv/issues/4023
2024-06-05 07:26:56 -05:00
Charlie Marsh 6d148da0ab
Preserve fragments when applying verbatim redirects (#4038)
## Summary

`echo
"git+https://github.com/pypa/sample-namespace-packages.git#subdirectory=pkg_resources/pkg_a"
| cargo run pip compile -` now resolves to a compliant URL.

Closes https://github.com/astral-sh/uv/issues/4037.
2024-06-05 03:53:23 +00:00
Charlie Marsh 27e5bfe397
Remove unnecessary requirements conversions (#4035) 2024-06-05 01:52:16 +00:00
Charlie Marsh 8de3e38b94
Read all extras directly from lockfile (#4033)
## Summary
We now pass `ExtrasSpecification` to the lock routine.
2024-06-05 01:03:55 +00:00
samypr100 1b3200b2af
feat: support `NO_COLOR` and `FORCE_COLOR` env vars (#3979)
## Summary

Closes #3955

Adds explicit support to `NO_COLOR` and `FORCE_COLOR` via
GlobalSettings.

The order, per specs is now `NO_COLOR` > `FORCE_COLOR` > `color`.

This PR is a backup plan pending rust-cli/anstyle#192.

## Test Plan

Tested all cases locally for now; I didn't see existing tests for
GlobalSettings parsing.
2024-06-04 17:00:42 -04:00
Charlie Marsh 57ea55d218
Add a hint for `Requires-Python` (#4021)
## Summary

As requested in the originating PR.
2024-06-04 16:52:15 -04:00
Charlie Marsh 8eea470d49
Bias towards local directories for bare editable requirements (#3995)
## Summary

Given `install -e dagster`, we need to assume that the user meant
`install -e ./dagster`, even though `install dagster` should _not_ be
treated as `install ./dagster`. I suspect pip will change this in the
future (since `pip install dagster` does _not_ meant `pip install
./dagster`) but for now it's what users expect.

Closes https://github.com/astral-sh/uv/issues/3994.
2024-06-04 19:37:05 +00:00
Charlie Marsh 420333a40e
Avoid 'are incompatible' for singular bounded versions (#4003)
## Summary

Not sure if this is worth the complexity, but it does read better.
2024-06-04 19:17:36 +00:00
Andrew Gallant 365ca637c7 uv/tests: add new universal tests
This updates to packse 0.3.17. There are a few incidental changes in
places, but the main addition here are the tests for universal
resolutions.
2024-06-04 14:24:59 -04:00
Andrew Gallant 459966a132
uv/tests: update packse tests (#4015)
This is just the result of running

    ./scripts/sync_scenarios.sh

From the root of the `uv` repository.

When I initially ran this, it produced some tests with snapshots that
weren't being updated. It turned out this was because the tests weren't
running, as they were gated behind the `python-patch` feature. In this
commit, we add `python-patch` to our `cargo insta` command, which should
update all relevant snapshots.

There are still some superfluous updates as a result of a spell checker
being run on generated files, but
2024-06-04 13:56:20 -04:00
Andrew Gallant 5c30b39fe3
uv-resolver: normalize marker expressions (#4017)
This is a quick fix for some flaky tests where the output in the lock
file isn't stable because marker expressions can be combined in a
non-deterministic order.

I believe there is ongoing work to simplify marker expressions which
will help here, but I think some kind of normalization is still
ultimately needed to guarantee consistent output.

I first noticed the flaky test in:
https://github.com/astral-sh/uv/pull/4015
2024-06-04 13:45:54 -04:00
Ibraheem Ahmed 3b8f3a7f0d
Avoid work-stealing in bytecode compilation (#4004)
## Summary

Avoid using work-stealing Tokio workers for bytecode compilation,
favoring instead dedicated threads. Tokio's work-stealing does not
really benefit us because we're spawning Python workers and scheduling
tasks ourselves — we don't want Tokio to re-balance our workers. Because
we're doing scheduling ourselves and compilation is a primarily
compute-bound task, we can also create dedicated runtimes for each
worker and avoid some synchronization overhead.

This is part of a general desire to avoid relying on Tokio's
work-stealing scheduler and be smarter about our workload. In this case
we already had the custom scheduler in place, Tokio was just getting in
the way (though the overhead is very minor).

## Test Plan

This improves performance by ~5% on my machine.

```
$ hyperfine --warmup 1 --prepare "target/profiling/uv-dev clear-compile .venv" "target/profiling/uv-dev compile .venv" "target/profiling/uv-dev-dedicated compile .venv"
Benchmark 1: target/profiling/uv-dev compile .venv
  Time (mean ± σ):      1.279 s ±  0.011 s    [User: 13.803 s, System: 2.998 s]
  Range (min … max):    1.261 s …  1.296 s    10 runs
 
Benchmark 2: target/profiling/uv-dev-dedicated compile .venv
  Time (mean ± σ):      1.220 s ±  0.021 s    [User: 13.997 s, System: 3.330 s]
  Range (min … max):    1.198 s …  1.272 s    10 runs

Summary
  target/profiling/uv-dev-dedicated compile .venv ran
    1.05 ± 0.02 times faster than target/profiling/uv-dev compile .venv

$ hyperfine --warmup 1 --prepare "target/profiling/uv-dev clear-compile .venv" "target/profiling/uv-dev compile .venv" "target/profiling/uv-dev-dedicated compile .venv"
Benchmark 1: target/profiling/uv-dev compile .venv
  Time (mean ± σ):      3.631 s ±  0.078 s    [User: 47.205 s, System: 4.996 s]
  Range (min … max):    3.564 s …  3.832 s    10 runs
 
Benchmark 2: target/profiling/uv-dev-dedicated compile .venv
  Time (mean ± σ):      3.521 s ±  0.024 s    [User: 48.201 s, System: 5.392 s]
  Range (min … max):    3.484 s …  3.566 s    10 runs
 
Summary
  target/profiling/uv-dev-dedicated compile .venv ran
    1.03 ± 0.02 times faster than target/profiling/uv-dev compile .venv
```
2024-06-04 10:48:23 -04:00
Charlie Marsh 6afb659c9a
Respect `Requires-Python` in universal resolution (#3998)
## Summary

Closes #3982.
2024-06-04 13:56:08 +00:00
konsti 63c84ed4a6
Log transient network request failures (#3933)
We retry several kinds of network request failures, but it's often
unclear whether a request was retried or not
(https://github.com/astral-sh/uv/issues/3514#issuecomment-2105485773).
This PR adds a small intermediary layer that logs all transient request
failures, adding the `DEBUG Transient request failure` lines:

```
DEBUG Searching for Python interpreter in virtual environments
DEBUG Found CPython 3.12.3 at `/home/konsti/projects/uv/.venv/bin/python3` (active virtual environment)
DEBUG Using Python 3.12.3 environment at .venv/bin/python3
DEBUG Acquired lock for `.venv`
DEBUG At least one requirement is not satisfied: tqdm
DEBUG Using registry request timeout of 30s
DEBUG Solving with target Python version 3.12.3
DEBUG Adding direct dependency: tqdm*
DEBUG No cache entry for: https://pypi.org/simple/tqdm/
DEBUG Transient request failure for https://pypi.org/simple/tqdm/, retrying: Request error: error sending request for url (https://pypi.org/simple/tqdm/)
  Caused by: error sending request for url (https://pypi.org/simple/tqdm/)
  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
DEBUG Transient request failure for https://pypi.org/simple/tqdm/, retrying: Request error: error sending request for url (https://pypi.org/simple/tqdm/)
  Caused by: error sending request for url (https://pypi.org/simple/tqdm/)
  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
DEBUG Transient request failure for https://pypi.org/simple/tqdm/, retrying: Request error: error sending request for url (https://pypi.org/simple/tqdm/)
  Caused by: error sending request for url (https://pypi.org/simple/tqdm/)
  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
DEBUG Transient request failure for https://pypi.org/simple/tqdm/, retrying: Request error: error sending request for url (https://pypi.org/simple/tqdm/)
  Caused by: error sending request for url (https://pypi.org/simple/tqdm/)
  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
error: Could not connect, are you offline?
  Caused by: error sending request for url (https://pypi.org/simple/tqdm/)
  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
```

I decided for multi-line logging to show the complete error trace since
only `Transient request failure for https://pypi.org/simple/tqdm/,
retrying: Request error: error sending request for url
(https://pypi.org/simple/tqdm/)` doesn't tell you the actual problem (a
dns error).

Note that running with `-v` will not show messages about retry backoff
timing, but running with `RUST_LOG=debug` now shows a complete picture:

```
DEBUG starting new connection: https://pypi.org/
DEBUG resolving host="pypi.org"
DEBUG Transient request failure for https://pypi.org/simple/tqdm/, retrying: Request error: error sending request for url (https://pypi.org/simple/tqdm/)
  Caused by: error sending request for url (https://pypi.org/simple/tqdm/)
  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
WARN Retry attempt #2. Sleeping 528.728192ms before the next attempt
```

Fixes #3572
2024-06-04 15:39:16 +02:00
Di-Is 41ec302557
Fix a bug where no warning is output when parsing of workspace settings fails. (#4014)
## Summary

See #4013

`uv pip ...` command loads workspace settings from pyproject.toml and
uv.toml.

Although a warning is implemented to output a warning when parsing
fails, it is not actually output.


https://github.com/astral-sh/uv/blob/main/crates/uv-workspace/src/workspace.rs#L38-L61

The reason is that the flag to display warnings is enabled after loading
the workspace settings.

This PR turns on the warning output flag before loading the workspace.

## Test Plan

pyproject.toml for test

```toml
[project]
name = "sample"
version = "0.0.0"
dependencies = ["ruff"]

[tool.uv.pip]
# originally string type.
index-url = 1
```

command output (before modification)
```bash
uv pip compile pyproject.toml 

Resolved 1 package in 383ms
# This file was autogenerated by uv via the following command:
#    uv pip compile pyproject.toml
ruff==0.4.7
    # via sample (pyproject.toml)
```

command output (after modification)

```bash
uv pip compile pyproject.toml

warning: Failed to parse `pyproject.toml`: TOML parse error at line 7, column 13
  |
7 | index-url = true
  |             ^^^^
invalid type: boolean `true`, expected a string

Resolved 1 package in 107ms
# This file was autogenerated by uv via the following command:
#    uv pip compile pyproject.toml
ruff==0.4.7
    # via sample (pyproject.toml)
```
2024-06-04 09:21:19 -04:00
konsti da7d5549a3
Don't copy gitignored files in workspace tests (#4012)
The workspace test directories can be used both in tests and directly
for developing/debugging. In the latter, we shouldn't copy the venv and
the lockfile when running tests. Using the ignore crate over manual
recursion we exclude those files.
2024-06-04 12:58:07 +00:00
konsti 36f7fa3917
`impl TryFrom<&VersionSpecifiers> for PubGrubSpecifier` (#4010)
Add a missing utility conversion method from PEP 440 versions specifiers
to a pubgrub range.
2024-06-04 08:00:07 +00:00
Charlie Marsh 77e93157fb
Make target Python version an optional field (#4000)
## Summary

Instead of checking if the target and installed version are the same, we
model the data such that the target version is only present if it was
specified by the user. This also means that we correctly say "requested
version" even if the two happen to be the same.
2024-06-03 22:37:15 +00:00
Charlie Marsh 037e7e345c
Remove unused `dummy` method (#4001) 2024-06-03 22:28:45 +00:00
Charlie Marsh b27d36baee
Remove some unnecessary `Interpreter` clones (#3999) 2024-06-03 22:09:42 +00:00
Charlie Marsh ef43bcb233
Remove Python from available versions (#3996)
## Summary

I believe this is no longer necessary. Part of the problem here is that
we can't _know_ the full set of available Python versions, especially
once we start resolving against a `Requires-Python` rather than a fixed
set of two versions.
2024-06-03 20:11:45 +00:00
Charlie Marsh 10cd6b94c9
Normalize extras in lockfile (#3958)
## Summary

Previously, when we locked something like `flask[dotenv]`, we created
two separate distributions in the lockfile: one for `flask`, which
included the base dependencies, and one for `flask[dotenv]`, which
included the base dependencies _and_ the `dotenv` dependencies. This was
easy to implement, but it meant that we were duplicating all of the
distribution files for every extra, and duplicating all of the base
dependencies for every extra.

This PR normalizes the data such that we now have one entry per
distribution (i.e., `ExtraName` was removed from `DistributionId`), with
an optional dependencies table with an entry per extra, like:

```toml
[[distribution]]
name = "project"
version = "0.1.0"
source = "editable+file://[TEMP_DIR]/"
sdist = { url = "file://[TEMP_DIR]/" }

[[distribution.dependencies]]
name = "anyio"
version = "3.7.0"
source = "registry+https://pypi.org/simple"

[distribution.optional-dependencies]

[[distribution.optional-dependencies.test]]
name = "iniconfig"
version = "2.0.0"
source = "registry+https://pypi.org/simple"
```

This requires a bit more work upfront, because we now need to merge
multiple packages from the `PetGraph` representation when creating the
lockfile.

Closes https://github.com/astral-sh/uv/issues/3916.
2024-06-03 19:00:35 +00:00
Charlie Marsh 362b00cc12
Remove need to return Python version in `get_dependencies` (#3993)
## Summary

Once we use a _range_ rather than a precise version, it won't actually
make sense to return a version here. It's no longer required, so I'm
removing it.
2024-06-03 18:42:38 +00:00
Charlie Marsh 1a60368ce4
Use `PubGrubPython` type in Python incompatibility reporting (#3992)
## Summary

Rather than re-testing compatibility, I think we can just rely on the
types directly.
2024-06-03 14:32:22 -04:00
Charlie Marsh a589ad5066
Bump version to v0.2.6 (#3991) 2024-06-03 17:40:28 +00:00
Ibraheem Ahmed 1ffe18d861
Avoid race condition in `OnceMap` (#3987)
## Summary

Fixes a race condition in `OnceMap::wait_blocking` where the inserted
value could potentially be missed, leading to a deadlock. Fairly certain
this will resolve https://github.com/astral-sh/uv/issues/3724.
2024-06-03 12:25:58 -04:00
Charlie Marsh 29ea5d5d9a
Fix reference to `--python-version` patch behavior (#3989)
## Summary

We changed this at some point but didn't update the documentation.
2024-06-03 15:34:12 +00:00
Charlie Marsh 650638fa52
Remove unstable uv lock from pip interface (#3970)
## Summary

I think we can start using `uv lock` and `uv sync` to test this instead.
2024-06-03 15:14:11 +00:00
Andrew Gallant fbf562d5a8
uv {lock,sync}: propagate index URLs to registry client (#3986)
Otherwise the `uv lock` command wasn't respecting the index URL option.

This is a follow-up to #3984, and I believe should now allow #3970 to be
merged.
2024-06-03 14:38:36 +00:00
Charlie Marsh a4c73fd07e
Extract index arguments into their own Clap group (#3985)
## Summary

Just removes a lot of repeated documentation. We can expand this
strategy in the future.
2024-06-03 14:27:35 +00:00
Charlie Marsh da1782808a
Add index URL parameters to Project CLI (#3984)
## Summary

For now, this exists to facilitate testing. We may remove it in the
future in favor of other APIs.
2024-06-03 10:17:41 -04:00
Tim de Jager 1b1600c40e
feat: add back the use of extra env vars to the build dispatch (#3981)
Seems like a recent Pull removed this, couldn't directly find out which.
I'm adding it back as we rely on this API, and I do not see another way
of accessing this, or am I mistaken?

Thanks!
2024-06-03 09:13:44 -04:00
Di-Is 5c776939d2
Add override namespace to pyproject.toml/uv.toml (#3839)
<!--
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

See #3834 .

This PR adds a new namespace, `override-dependencies`, to
pyproject.toml/uv.toml.
This namespace assumes that the dependencies you want to override are
written in the form of `requirements.txt`.


a example of pyproject.toml
```toml
[project]
name = "example"
version = "0.0.0"
dependencies = [
  "flask==3.0.0"
]

[tool.uv]
override-dependencies = [
  "werkzeug==2.3.0"
]
```

This will improve usability by allowing you to override dependencies
without having to specify the --override option when running `uv pip
compile/install`.

## Test Plan

added test to `crates/uv/tests/pip_compile.rs`.

---------

Co-authored-by: konstin <konstin@mailbox.org>
2024-06-03 12:15:51 +02:00
Charlie Marsh a23ca5bab7
Use universal resolution in `uv lock` (#3969)
## Summary

Wires up the optional markers in resolution, and adds
respecting-the-markers to `Lock:: to_resolution`.
2024-06-02 21:33:18 -04:00
Charlie Marsh c500b78936
Avoid re-adding solutions to forked state (#3967)
## Summary

Running a resolution that required forking was failing due to breaking
an invariant in PubGrub. It looks like we were adding the same
incompatibility multiple times, or something like that. The issue
appears to be that when forking, we modify the current state, then clone
it as the "next state", then push to the "forked states" -- but that
means we're cloning the _modified_ state.

This PR changes the order of operations such that we clone, then modify.
It shouldn't introduce any additional clones though.
2024-06-02 17:58:25 -04:00
konsti 01d1a39c21
Add `uv run --package` (#3864)
Add a `--package` option that allows switching the current project in
the workspace. Wherever you are in a workspace, you should be able to
run with any other project as root. This is the uv equivalent of `cargo
run -p`.

I don't love the `--package` name, esp. since `-p` is already taken and
in general to many things start with p already.

Part of this change is moving the workspace discovery of
`ProjectWorkspace` to `Workspace` itself.

## Usage

In albatross-virtual-workspace:

```console
$ uv venv
$ uv run --preview --package bird-feeder python -c "import albatross"
   Built file:///home/konsti/projects/uv/scripts/workspaces/albatross-virtual-workspace/packages/bird-feeder
   Built file:///home/konsti/projects/uv/scripts/workspaces/albatross-virtual-workspace/packages/seeds
Built 2 editables in 167ms
Resolved 5 packages in 4ms
Installed 5 packages in 1ms
 + anyio==4.4.0
 + bird-feeder==1.0.0 (from file:///home/konsti/projects/uv/scripts/workspaces/albatross-virtual-workspace/packages/bird-feeder)
 + idna==3.6
 + seeds==1.0.0 (from file:///home/konsti/projects/uv/scripts/workspaces/albatross-virtual-workspace/packages/seeds)
 + sniffio==1.3.1
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'albatross'
$ uv venv
$ uv run --preview --package albatross python -c "import albatross"
   Built file:///home/konsti/projects/uv/scripts/workspaces/albatross-virtual-workspace/packages/albatross
   Built file:///home/konsti/projects/uv/scripts/workspaces/albatross-virtual-workspace/packages/bird-feeder
   Built file:///home/konsti/projects/uv/scripts/workspaces/albatross-virtual-workspace/packages/seeds
Built 3 editables in 173ms
Resolved 7 packages in 6ms
Installed 7 packages in 1ms
 + albatross==0.1.0 (from file:///home/konsti/projects/uv/scripts/workspaces/albatross-virtual-workspace/packages/albatross)
 + anyio==4.4.0
 + bird-feeder==1.0.0 (from file:///home/konsti/projects/uv/scripts/workspaces/albatross-virtual-workspace/packages/bird-feeder)
 + idna==3.6
 + seeds==1.0.0 (from file:///home/konsti/projects/uv/scripts/workspaces/albatross-virtual-workspace/packages/seeds)
 + sniffio==1.3.1
 + tqdm==4.66.4
```

In albatross-root-workspace:

```console
$ uv venv
$ uv run --preview --package bird-feeder python -c "import albatross"
  Using Python 3.12.3 interpreter at: /home/konsti/.local/bin/python3
  Creating virtualenv at: .venv
  Activate with: source .venv/bin/activate
      Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.10s
       Running `/home/konsti/projects/uv/target/debug/uv run --preview --package bird-feeder python -c 'import albatross'`
     Built file:///home/konsti/projects/uv/scripts/workspaces/albatross-root-workspace/packages/bird-feeder
     Built file:///home/konsti/projects/uv/scripts/workspaces/albatross-root-workspace/packages/seeds                                              Built 2 editables in 161ms
  Resolved 5 packages in 4ms
  Installed 5 packages in 1ms
   + anyio==4.4.0
   + bird-feeder==1.0.0 (from file:///home/konsti/projects/uv/scripts/workspaces/albatross-root-workspace/packages/bird-feeder)
   + idna==3.6
   + seeds==1.0.0 (from file:///home/konsti/projects/uv/scripts/workspaces/albatross-root-workspace/packages/seeds)
   + sniffio==1.3.1
  Traceback (most recent call last):
    File "<string>", line 1, in <module>
  ModuleNotFoundError: No module named 'albatross'
$ uv venv
$ cargo run run --preview --package albatross python -c "import albatross"
Using Python 3.12.3 interpreter at: /home/konsti/.local/bin/python3
Creating virtualenv at: .venv
Activate with: source .venv/bin/activate
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.13s
     Running `/home/konsti/projects/uv/target/debug/uv run --preview --package albatross python -c 'import albatross'`
   Built file:///home/konsti/projects/uv/scripts/workspaces/albatross-root-workspace
   Built file:///home/konsti/projects/uv/scripts/workspaces/albatross-root-workspace/packages/bird-feeder
   Built file:///home/konsti/projects/uv/scripts/workspaces/albatross-root-workspace/packages/seeds
Built 3 editables in 168ms
Resolved 7 packages in 5ms
Installed 7 packages in 1ms
 + albatross==0.1.0 (from file:///home/konsti/projects/uv/scripts/workspaces/albatross-root-workspace)
 + anyio==4.4.0
 + bird-feeder==1.0.0 (from file:///home/konsti/projects/uv/scripts/workspaces/albatross-root-workspace/packages/bird-feeder)
 + idna==3.6
 + seeds==1.0.0 (from file:///home/konsti/projects/uv/scripts/workspaces/albatross-root-workspace/packages/seeds)
 + sniffio==1.3.1
 + tqdm==4.66.4
```
2024-06-02 21:42:14 +00:00
Matthieu Darbois 0d0308c531
fix: add missing ppc64le alias for powerpc64le (#3963)
## Summary

Same as #3899 but for ppc64le, there were no tests added there so I
wouldn't know where to begin to do so.

Using image docker image `quay.io/pypa/manylinux2014_ppc64le` (uv 0.2.4)

```
[root@e3ff544d1337 ~]# python3.12 -V
Python 3.12.3
[root@e3ff544d1337 ~]# RUST_LOG="trace" uv venv py312 --python python3.12
DEBUG Searching for Python 3.12 in search path
TRACE Searching PATH for executables: python3.12, python3, python
TRACE Checking `PATH` directory for interpreters: /opt/rh/devtoolset-10/root/usr/bin
TRACE Checking `PATH` directory for interpreters: /usr/local/sbin
TRACE Checking `PATH` directory for interpreters: /usr/local/bin
TRACE Found possible Python executable: /usr/local/bin/python3.12
TRACE Querying interpreter executable at /usr/local/bin/python3.12
TRACE Querying Python at `/usr/local/bin/python3.12` did not return the expected data
unknown variant `ppc64le`, expected one of `aarch64`, `armv6l`, `armv7l`, `powerpc64le`, `powerpc64`, `x86`, `x86_64`, `s390x`
--- stdout:
{"result": "success", "markers": {"implementation_name": "cpython", "implementation_version": "3.12.3", "os_name": "posix", "platform_machine": "ppc64le", "platform_python_implementation": "CPython", "platform_release": "6.6.26-linuxkit", "platform_system": "Linux", "platform_version": "#1 SMP Sat Apr 27 04:13:19 UTC 2024", "python_full_version": "3.12.3", "python_version": "3.12", "sys_platform": "linux"}, "base_prefix": "/opt/_internal/cpython-3.12.3", "base_exec_prefix": "/opt/_internal/cpython-3.12.3", "prefix": "/opt/_internal/cpython-3.12.3", "base_executable": "/usr/local/bin/python3.12", "sys_executable": "/usr/local/bin/python3.12", "sys_path": ["/root/.cache/uv/.tmpBnM4PN", "/opt/_internal/cpython-3.12.3/lib/python312.zip", "/opt/_internal/cpython-3.12.3/lib/python3.12", "/opt/_internal/cpython-3.12.3/lib/python3.12/lib-dynload", "/opt/_internal/cpython-3.12.3/lib/python3.12/site-packages"], "stdlib": "/opt/_internal/cpython-3.12.3/lib/python3.12", "scheme": {"platlib": "/opt/_internal/cpython-3.12.3/lib/python3.12/site-packages", "purelib": "/opt/_internal/cpython-3.12.3/lib/python3.12/site-packages", "include": "/opt/_internal/cpython-3.12.3/include/python3.12", "scripts": "/opt/_internal/cpython-3.12.3/bin", "data": "/opt/_internal/cpython-3.12.3"}, "virtualenv": {"purelib": "lib/python3.12/site-packages", "platlib": "lib/python3.12/site-packages", "include": "include/site/python3.12", "scripts": "bin", "data": ""}, "platform": {"os": {"name": "manylinux", "major": 2, "minor": 17}, "arch": "ppc64le"}, "gil_disabled": false, "pointer_size": "64"}
--- stderr:

---
TRACE Skipping bad interpreter at /usr/local/bin/python3.12
TRACE Checking `PATH` directory for interpreters: /usr/sbin
TRACE Checking `PATH` directory for interpreters: /usr/bin
TRACE Found possible Python executable: /usr/bin/python
TRACE Querying interpreter executable at /usr/bin/python
TRACE Can't use Python at `/usr/bin/python`
TRACE Skipping bad interpreter at /usr/bin/python
TRACE Checking `PATH` directory for interpreters: /sbin
TRACE Checking `PATH` directory for interpreters: /bin
TRACE Found possible Python executable: /bin/python
TRACE Querying interpreter executable at /bin/python
TRACE Can't use Python at `/bin/python`
TRACE Skipping bad interpreter at /bin/python
  × No interpreter found for Python 3.12 in search path
```

---------

Co-authored-by: Charlie Marsh <crmarsh416@gmail.com>
2024-06-02 13:15:24 -04:00
Charlie Marsh 11324646cb
Remove some `anyhow` usages (#3962) 2024-06-01 20:11:23 +00:00
Charlie Marsh a70e33d947
Move reference check into `uv-git` (#3961) 2024-06-01 16:02:25 -04:00
Charlie Marsh c04a95e037
Respect resolved Git SHAs in `uv lock` (#3956)
## Summary

This PR ensures that if a lockfile already contains a resolved reference
(e.g., you locked with `main` previously, and it locked to a specific
commit), and you run `uv lock`, we use the same SHA, even if it's not
the latest SHA for that tag. This avoids upgrading Git dependencies
without `--upgrade`.

Closes #3920.
2024-06-01 12:40:11 +00:00
Charlie Marsh b7d77c04cc
Add Git resolver in lieu of static hash map (#3954)
## Summary

This PR removes the static resolver map:

```rust
static RESOLVED_GIT_REFS: Lazy<Mutex<FxHashMap<RepositoryReference, GitSha>>> =
    Lazy::new(Mutex::default);
```

With a `GitResolver` struct that we now pass around on the
`BuildContext`. There should be no behavior changes here; it's purely an
internal refactor with an eye towards making it cleaner for us to
"pre-populate" the list of resolved SHAs.
2024-05-31 22:44:42 -04:00
Charlie Marsh a0652921fc
Don't enforce that requirements files are "files" (#3947)
## Summary

This was just an opportunistic guard but it broke some use-cases.

Closes #3944.
2024-05-31 21:32:36 +00:00
Charlie Marsh 7b7da803bb
Unify editable and unnamed URL parsing (#3946)
## Summary

This will help prevent bugs like #3934 by unifying the implementations
for editables and non-editable unnamed requirements. Specifically, both
of these now go through the same parsing paths and use the same struct
representations (with the exception that the editable flag is flipped in
the first case):

```
-e ./foo/bar
./foo/bar
```

We also now support PEP 508 in editable URLs. It turns out this is just
a limitation in pip, so it's correct to support it. For example, this
now works:

```
-e black[d] @ file://${PROJECT_ROOT}/scripts/packages/black_editable
```

Closes #3941.

Closes #3942.
2024-05-31 21:08:00 +00:00
Charlie Marsh 8c11f99fdf
Discard fragments when parsing unnamed URLs (#3940)
## Summary

Closes https://github.com/astral-sh/uv/issues/3934.
2024-05-31 13:54:15 +00:00
konsti 72b1642232
Move metadata into its own file (#3939)
Move `Metadata`, `MetadataLoweringError` and `ArchiveMetadata` into
their own file `metadata.rs` in `uv-distribution`, moving it out from
`lib.rs`. No functional changes.
2024-05-31 15:24:10 +02:00
konsti 3c074142f5
Re-add lowering unit tests (#3935)
Re-add the lowering unit tests removed in #3904. This also adds a
`stop_discovery_at` feature to avoid running actual workspace discovery.
2024-05-31 12:17:49 +00:00
konsti 9bb0679618
Fix nightly cfg checker warnings (#3932)
Fixes these two warnings on nightly:

```
warning: unexpected `cfg` condition name: `codspeed`
 --> crates/bench/src/lib.rs:5:15
  |
5 |     #[cfg(not(codspeed))]
  |               ^^^^^^^^ help: found config with similar value: `feature = "codspeed"`
  |
  = help: expected names are: `clippy`, `debug_assertions`, `doc`, `docsrs`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `rustfmt`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, and `windows`
  = help: consider using a Cargo feature instead
  = help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:
           [lints.rust]
           unexpected_cfgs = { level = "warn", check-cfg = ['cfg(codspeed)'] }
  = help: or consider adding `println!("cargo::rustc-check-cfg=cfg(codspeed)");` to the top of the `build.rs`
  = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
  = note: `#[warn(unexpected_cfgs)]` on by default

warning: unexpected `cfg` condition name: `codspeed`
 --> crates/bench/src/lib.rs:8:11
  |
8 |     #[cfg(codspeed)]
  |           ^^^^^^^^ help: found config with similar value: `feature = "codspeed"`
  |
  = help: consider using a Cargo feature instead
  = help: or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:
           [lints.rust]
           unexpected_cfgs = { level = "warn", check-cfg = ['cfg(codspeed)'] }
  = help: or consider adding `println!("cargo::rustc-check-cfg=cfg(codspeed)");` to the top of the `build.rs`
  = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
```

```
warning: unexpected `cfg` condition value: `unix`
 --> crates/uv-extract/src/tar.rs:6:16
  |
6 | #[cfg_attr(not(target_os = "unix"), allow(dead_code))]
  |                ^^^^^^^^^^^^^^^^^^
  |
  = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, and `windows` and 2 more
  = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
  = note: requested on the command line with `-W unexpected-cfgs`
```

<!--
Thank you for contributing to uv! To help us out with reviewing, please
consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->
2024-05-31 09:35:52 +00:00
konsti 081f20c53e
Add support for `tool.uv` into distribution building (#3904)
With the change, we remove the special casing of workspace dependencies
and resolve `tool.uv` for all git and directory distributions. This
gives us support for non-editable workspace dependencies and path
dependencies in other workspaces. It removes a lot of special casing
around workspaces. These changes are the groundwork for supporting
`tool.uv` with dynamic metadata.

The basis for this change is moving `Requirement` from
`distribution-types` to `pypi-types` and the lowering logic from
`uv-requirements` to `uv-distribution`. This changes should be split out
in separate PRs.

I've included an example workspace `albatross-root-workspace2` where
`bird-feeder` depends on `a` from another workspace `ab`. There's a
bunch of failing tests and regressed error messages that still need
fixing. It does fix the audited package count for the workspace tests.
2024-05-31 02:42:03 +00:00
Charlie Marsh 09f55482a0
Remove some unused `pub use` exports (#3930) 2024-05-30 22:26:52 -04:00
Charlie Marsh a14fe2f6c7
Avoid filtering preferences by `--reinstall` (#3929)
## Summary

In general, it's not quite right to filter preferences by `--reinstall`
-- we still want to respect existing versions, we just don't want to
respect _installed_ versions. But now that the installed versions and
preferences are decoupled, we can remove this (`--reinstall` is enforced
on the installed versions via the `Exclusions` struct that we pass to
the resolver).

While I was here, I also cleaned up the lockfile preference code to
better match the structure for `requirements.txt`.
2024-05-30 20:19:08 +00:00
Charlie Marsh 438b5c61d0
Remove installed packages from preferences (#3928)
## Summary

I believe that this is not necessary, as the installer packages are
already considered in `CandidateSelector::get_preferred`.

Firstly, note that we never pass both non-empty installed packages _and_
non-empty preferences (the installer routines pass site packages and no
preferences; the resolver routines pass no site packages but lockfile
preferences).

However, in general, if you look at `CandidateSelector::get_preferred`,
and consider what's changing, we now skip the `if let Some(version) =
preferences.version(package_name)` case for installed packages. But we
then check installed packages within that `if`, and in the `else`. So it
seems like we'll still return them in either case?

The only behavior change is in the case that you have multiple versions
of a package installed. Previously, we'd respect one of them, because
`Preferences` takes the last winner (it's a hash map, so we just replace
the package key with the last version we see); but in installed
packages, we always ignore distributions with multiple versions, since
it's indicative of a broken environment. That's a fine change IMO. We
could change `CandidateSelector::get_preferred` to support this if we
wanted to.
2024-05-30 20:09:31 +00:00
Ibraheem Ahmed 261aa2c70a
Port all git functionality to use git CLI (#3833)
## Summary

We currently rely on libgit2 for most git-related functionality.
However, libgit2 has long-standing performance issues, as well as lags
significantly behind git in terms of new features. For these reasons we
now use the git CLI by default for fetching repositories
(https://github.com/astral-sh/uv/pull/1781). This PR completely drops
libgit2 in favor of the git CLI for all git-related functionality, which
should allow us to use features such as partial clones and sparse
checkouts in the future for performance.

There is also a lot of technical debt in the current git code as it's
mostly taken from Cargo. Switching to the git CLI *vastly* simplifies
the `uv-git` codebase.

Eventually we might want to look into switching to
[`gitoxide`](https://github.com/Byron/gitoxide), but it's currently too
immature for our use case.
2024-05-30 15:28:48 -04:00
Ibraheem Ahmed 85183c1c36
Custom lock-file serialization (#3909)
## Summary

This PR changes the lock-file format to use inline tables for wheels and
source distributions, which currently use separate tables that make the
file harder to follow.

```diff
[[distribution]]
name = "typing-extensions"
version = "4.10.0"
source = "registry+https://pypi.org/simple"

- [distribution.sdist]
- url = "0d26ce356c7c323176620b7b483e44/typing_extensions-4.10.0.tar.gz"
- hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"
- size = 77558
-
- [[distribution.wheel]]
- url = "dc04a3ea60b9bc8074b5d6b7ab90bb/typing_extensions-4.10.0-py3-none-any.whl"
- hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"
- size = 33926

+ sdist = { url = "0d26ce356c7c323176620b7b483e44/typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb", size = 77558 }
+ wheel = [{ url = "dc04a3ea60b9bc8074b5d6b7ab90bb/typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475", size = 33926 }]
```

The downside is that the inline-tables end up quite long and TOML
doesn't support line breaks in inline tables, yet.

Part of https://github.com/astral-sh/uv/issues/3611.
2024-05-30 19:08:29 +00:00
Andrew Gallant d3b7d800ea uv-resolver: fix perf regression
We significantly regressed performance in some cases because we were
cloning the resolver state one more time than we needed to. That doesn't
sound like a lot, but in the case where there are no forks, it implies
we were cloning the state for every `get_dependencies` called when we
shouldn't have been cloning it at all.

Avoiding the clone results in somewhat tortured code. This can probably
be refactored by moving bits out to a helper routine, but that also
seemed non-trivial. So we let this suffice for now.
2024-05-30 14:23:14 -04:00
Andrew Gallant 17c043536b uv-resolver: thread markers through the resolver and into the lock file
This addresses the lack of marker support in prior commits.
Specifically, we add them as a new field to `AnnotatedDist`, and from
there, they get added to a `Distribution` in a `Lock`.
2024-05-30 14:23:14 -04:00
Andrew Gallant f865406ab4 uv-resolver: implement merging of forked resolutions
This commit is a pretty invasive change that implements the merging
of resolutions created by each fork of the resolver.

The main idea here is that each `SolveState` is converted into a
`Resolution` (a new type) and stored on the heap after its fork
completes. When all forks complete, they are all merged into a single
`Resolution`. This `Resolution` is then used to build a `ResolutionGraph`.

Construction of `ResolutionGraph` mostly stays the same (despite the
gnarly diff due to an indent change) with one exception: the code to
extract dependency edges out of PubGrub's state has been moved to
`SolveState::into_resolution`. The idea here is that once a fork
completes, we extract what we need from the PubGrub state and then
throw it away. We store these edges in our own intermediate type which
is then converted into petgraph edges in the `ResolutionGraph`
constructor.

One interesting change we make here is that our edge
data is now a `Version` instead of a `Range<Version>`. I don't think
`Range<Version>` was actually being used anywhere, so this seems okay?
In any case, I think `Version` here is correct because a resolution
corresponds to specific dependencies of each package. Moreover, I didn't
see an easy way to make things work with `Range<Version>`. Notably,
since we no longer have the guarantee that there is only one version of
each package, we need to use `(PackageName, Version)` instead of just
`PackageName` for inverted lookups in `ResolutionGraph::from_state`.

Finally, the main resolver loop itself is changed a bit to track all
forked resolutions and then merge them at the end.

Note that we don't really have any dealings with markers in this commit.
We'll get to that in a subsequent commit.
2024-05-30 14:23:14 -04:00
Andrew Gallant 9e977aa1be uv-resolver: slightly simplify ResolutionGraph::from_state
This changes the constructor to just take an `InMemoryIndex`
directly instead of the constituent parts. No real reason other
than it seems a little simpler.
2024-05-30 14:23:14 -04:00
Andrew Gallant 6f76a66510 uv-resolver: implement basic resolver forking
There are still some TODOs/FIXMEs here, but this makes represents a
chunk of the resolver refactoring to enable forking. We don't do any
merging of resolutions yet, so crucially, this code is broken when no
marker environment is provided. But when a marker environment is
provided, this should behave the same as a non-forking resolver. In
particular, `get_dependencies_forking` is just `get_dependencies`
whenever there's a marker environment.
2024-05-30 14:23:14 -04:00
Andrew Gallant f5f330627b pep508: make 'simplify_extras' more flexible
This makes it so we can pass any function to determine whether an extra
is always true or not.

For example, `markers.simplify_extras_with(|_| true)` will remove all
extras in any marker expression. This wasn't possible to express
(without knowing all of the marker names) using the old API, but becomes
trivial to express with a predicate function.
2024-05-30 14:23:14 -04:00
Andrew Gallant a74c2c6792 pep508: add `and` and `or` mutators to `MarkerTree`
While this could be done by callers since the representation
of `MarkerTree` is public, they are just annoying enough to do
that I think it makes sense to provide them on `MarkerTree`
itself.

These could also be improved in the future to do even more
flattening of conjunctions/disjunctions (or perhaps even
more robust simplification). But for now, some basic flattening
is good enough.

These routines will be used to combine marker expressions when
merging forked resolutions.
2024-05-30 14:23:14 -04:00
Charlie Marsh 144566907e
Use lockfile versions as resolution preferences (#3921)
## Summary

Ensures that we avoid upgrading packages unless `--upgrade` or similar
is passed.

For now, the resolver only respects these for registry distributions.

Closes https://github.com/astral-sh/uv/issues/3918.
2024-05-30 17:59:53 +00:00
Charlie Marsh 502e04200d
Remove `from_registry_built_dist2` (#3922)
## Summary

I think this was left over from a prior refactor. (The existing
`from_registry_built_dist` was unused.)
2024-05-30 01:57:19 +00:00
Charlie Marsh a1a5155d34
Move preference behavior out of resolve (#3919)
## Summary

Decoupling this behavior to give more control to clients. No change in
behavior.
2024-05-30 01:16:53 +00:00
Charlie Marsh 4859a27948
Add extra dependency annotations to lockfile and sync commands (#3913)
## Summary

This PR adds extras to the lockfile, and enables users to selectively
sync extras in `uv sync` and `uv run`. The end result here was fairly
simple, though it required a few refactors to get here. The basic idea
is that `DistributionId` now includes `extra: Option<ExtraName>`, so we
effectively treat extras as separate packages. Generating the lockfile,
and generating the resolution from the lockfile, fall out of this
naturally with no special-casing or additional changes.

The main downside here is that it bloats the lockfile significantly.
Specifically:

- We include _all_ distribution URLs and hashes for _every_ extra
variant.
- We include all dependencies for the extra variant, even though that
are dependencies of the base package.

We could normalize this representation by changing each distribution
have an `optional-dependencies` hash map that keys on extras, but we
actually don't have the information we need to create that right now
(specifically, we can't differentiate between dependencies that
_require_ the extra and dependencies on the base package).

Closes #3700.
2024-05-29 19:25:58 +00:00
Charlie Marsh 1bd5d8bc34
Include all extras when generating lockfile (#3912)
## Summary

This PR just ensures that when running `uv lock` (or `uv run`), we lock
with all extras. When we later install, we'll also _install_ with all
extras, but that will be changed in a future PR.
2024-05-29 15:08:20 -04:00
Charlie Marsh fb0dfef671
Migrate lockfile tests to `uv lock` and `uv sync` (#3914) 2024-05-29 18:00:37 +00:00
Charlie Marsh ed7f55606d
Split `requirements.txt`-style resolution distribution into its own type (#3911) 2024-05-29 16:48:28 +00:00
konsti af06544347
Remove dead code from distribution-types (#3910)
Remove some dead code. Split out from #3904
2024-05-29 12:02:42 -04:00
Charlie Marsh 19c91e7dac
Create distinct graph nodes for each package extra (#3908)
## Summary

Today, we represent each package as a single node in the graph, and
combine all the extras. This is helpful for the `requirements.txt`-style
resolution, in which we want to show each a single line for each package
with the extras combined into a single array.

This PR modifies the representation to instead use a separate node for
each (package, extra) pair. We then reduce into the previous format when
printing in the `requirements.txt`-style format, so there shouldn't be
any user-facing changes here.
2024-05-29 15:42:49 +00:00
konsti 0edb660205
Add missing i686 alias for x86 (#3899)
This alias is required for the 32-bit x86 manylinux builder.

I've also changed the reporting level for unusable python interpreter
errors to debug so it shows up with `-v`, otherwise we can't see what's
broken:

```console
# uv venv py312 --python python3.12 -vv
    0.000461s DEBUG uv_interpreter::discovery Searching for Python 3.12 in search path
  × No interpreter found for Python 3.12 in search path
```

Reproduction:

```console
$ docker run --rm -it quay.io/pypa/manylinux2014_i686
# curl -LsSf https://astral.sh/uv/install.sh | s
# source $HOME/.cargo/env
# RUST_LOG=trace uv venv py312 --python python3.12
DEBUG Searching for Python 3.12 in search path
TRACE Searching PATH for executables: python3.12, python3, python
TRACE Checking `PATH` directory for interpreters: /root/.cargo/bin
TRACE Checking `PATH` directory for interpreters: /opt/rh/devtoolset-10/root/usr/bin
TRACE Checking `PATH` directory for interpreters: /usr/local/sbin
TRACE Checking `PATH` directory for interpreters: /usr/local/bin
TRACE Found possible Python executable: /usr/local/bin/python3.12
TRACE Querying interpreter executable at /usr/local/bin/python3.12
TRACE Querying Python at `/usr/local/bin/python3.12` did not return the expected data
unknown variant `i686`, expected one of `aarch64`, `armv6l`, `armv7l`, `powerpc64le`, `powerpc64`, `x86`, `x86_64`, `s390x`
--- stdout:
{"result": "success", "markers": {"implementation_name": "cpython", "implementation_version": "3.12.3", "os_name": "posix", "platform_machine": "i686", "platform_python_implementation": "CPython", "platform_release": "6.1.0-10-amd64", "platform_system": "Linux", "platform_version": "#1 SMP PREEMPT_DYNAMIC Debian 6.1.37-1 (2023-07-03)", "python_full_version": "3.12.3", "python_version": "3.12", "sys_platform": "linux"}, "base_prefix": "/opt/_internal/cpython-3.12.3", "base_exec_prefix": "/opt/_internal/cpython-3.12.3", "prefix": "/opt/_internal/cpython-3.12.3", "base_executable": "/usr/local/bin/python3.12", "sys_executable": "/usr/local/bin/python3.12", "sys_path": ["/root/.cache/uv/.tmp7k64ZY", "/opt/_internal/cpython-3.12.3/lib/python312.zip", "/opt/_internal/cpython-3.12.3/lib/python3.12", "/opt/_internal/cpython-3.12.3/lib/python3.12/lib-dynload", "/opt/_internal/cpython-3.12.3/lib/python3.12/site-packages"], "stdlib": "/opt/_internal/cpython-3.12.3/lib/python3.12", "scheme": {"platlib": "/opt/_internal/cpython-3.12.3/lib/python3.12/site-packages", "purelib": "/opt/_internal/cpython-3.12.3/lib/python3.12/site-packages", "include": "/opt/_internal/cpython-3.12.3/include/python3.12", "scripts": "/opt/_internal/cpython-3.12.3/bin", "data": "/opt/_internal/cpython-3.12.3"}, "virtualenv": {"purelib": "lib/python3.12/site-packages", "platlib": "lib/python3.12/site-packages", "include": "include/site/python3.12", "scripts": "bin", "data": ""}, "platform": {"os": {"name": "manylinux", "major": 2, "minor": 17}, "arch": "i686"}, "gil_disabled": false, "pointer_size": "32"}
--- stderr:

---
TRACE Skipping bad interpreter at /usr/local/bin/python3.12
TRACE Checking `PATH` directory for interpreters: /usr/sbin
TRACE Checking `PATH` directory for interpreters: /usr/bin
TRACE Found possible Python executable: /usr/bin/python
TRACE Querying interpreter executable at /usr/bin/python
TRACE Can't use Python at `/usr/bin/python`
TRACE Skipping bad interpreter at /usr/bin/python
TRACE Checking `PATH` directory for interpreters: /sbin
TRACE Checking `PATH` directory for interpreters: /bin
TRACE Found possible Python executable: /bin/python
TRACE Querying interpreter executable at /bin/python
TRACE Can't use Python at `/bin/python`
TRACE Skipping bad interpreter at /bin/python
```
2024-05-29 11:31:39 -04:00
Ahmed Ilyas 1a9aa35eae
Fix workspace settings - remove deny unknown fields (#3907)
## Summary

This PR addresses an issue where `tool.uv` settings are not read if
`tool.uv.sources` or `tool.uv.workspaces` are present in the TOML file.

## Test Plan

Tested locally.
2024-05-29 11:31:07 -04:00
Charlie Marsh 42b1ba04ec
Remove unused `PetGraph` weight (#3906) 2024-05-29 15:16:25 +00:00
Charlie Marsh 2301e00863
Use lockfile in `uv run` (#3894)
## Summary

Modifies `uv run` to write and read from the lockfile, rather than
resolving the project requirements as-is on each invocation.

Closes https://github.com/astral-sh/uv/issues/3891.
2024-05-29 13:28:21 +00:00
Ibraheem Ahmed 9658485f06
Initialize multi-progress state before individual bars (#3901)
## Summary

Resolves https://github.com/astral-sh/uv/issues/3896. Adding progress
bars to the `MultiProgress` after configuring them seems to not
synchronize the required state fully.

## Test Plan

The repeated output is gone when testing locally.
2024-05-29 09:23:40 -04:00
konsti 1e1f49bfe5
Remove unnecessary `pub` in uv-build (#3900)
Expose only `SourceBuild` and the error type from `uv-build`, all other
types are internal.
2024-05-29 09:30:21 +00:00
Charlie Marsh 3461c8b585
Move extra specification into `uv-configuration` (#3897)
## Summary

I need to use this in the resolver (and it's at-home with other, similar
configuration options).
2024-05-29 04:49:57 +00:00
Charlie Marsh 2b6c24ed2d
Rename project API error (#3893) 2024-05-28 21:59:24 -04:00
Ibraheem Ahmed 038af6e658
Disable concurrent progress bars in Jupyter Notebooks (#3890)
## Summary

Resolves https://github.com/astral-sh/uv/issues/3887 by disabling the
new progress output when the `JPY_SESSION_NAME` environment variable is
detected.
2024-05-28 17:05:11 -04:00
Charlie Marsh 47db418ba2
Bump version to v0.2.5 (#3885) 2024-05-28 18:05:32 +00:00
Charlie Marsh 78c43c6a7a
Move editable discovery behind `--preview` for now (#3884)
## Summary

Just reduces the risk of shipping stable regressions for now.
2024-05-28 17:54:25 +00:00
konsti f92447772e
Support x86 windows (#3873)
Add trampolines for x86 windows.

Closes https://github.com/astral-sh/uv/issues/3660.
2024-05-28 16:07:39 +00:00
Charlie Marsh cedd18e4c6
Remove some unused `pub` functions (#3872)
## Summary

I wrote a bad Python script to find these.
2024-05-28 15:58:13 +00:00
Charlie Marsh 1fc6a59707
Remove special-casing for editable requirements (#3869)
## Summary

There are a few behavior changes in here:

- We now enforce `--require-hashes` for editables, like pip. So if you
use `--require-hashes` with an editable requirement, we'll reject it. I
could change this if it seems off.
- We now treat source tree requirements, editable or not (e.g., both `-e
./black` and `./black`) as if `--refresh` is always enabled. This
doesn't mean that we _always_ rebuild them; but if you pass
`--reinstall`, then yes, we always rebuild them. I think this is an
improvement and is close to how editables work today.

Closes #3844.

Closes #2695.
2024-05-28 15:49:34 +00:00
konsti 063a0a4384
Add context to failed `uv tool run` (#3882)
These are not covered by `fs_err` and a missing binary otherwise only
give a generic "file not found" error.
2024-05-28 14:48:54 +00:00
Tim de Jager b12b25db10
fix: remove unused `Result` in uv-cache (#3875)
## Summary

<!-- What's the purpose of the change? What does it do, and why? -->
It removes the unused result when creating the Cache with the
`from_path` constructor. I don't believe it does any io operations any
more at least.
2024-05-28 09:19:08 +00:00
konsti a89e146107
Initial workspace support (#3705)
Add workspace support when using `-r <path>/pyproject.toml` or `-e
<path>` in the pip interface. It is limited to all-editable
static-metadata workspaces, and tests only include a single main
workspace, ignoring path dependencies in another workspace. This can be
considered the MVP for workspace support: You can create a workspace,
you can install from it, but some options and conveniences are still
missing. I'll file follow-up tickets (support in lockfiles, support path
deps in other workspace, #3625)

There is also support in `uv run`, but we need
https://github.com/astral-sh/uv/issues/3700 first to properly support
using different current projects in the bluejay interface, currently the
resolution and therefore the lockfile depends on the current project.
I'd do this change first (it's big enough already), then #3700, and then
add workspace support properly to bluejay.

Fixes #3404
2024-05-28 07:41:53 +00:00
Charlie Marsh 89cfecea77
Add support for `prepare_metadata_for_build_editable` hook (#3870)
## Summary

See:
https://peps.python.org/pep-0660/#prepare-metadata-for-build-editable
2024-05-27 23:21:45 +00:00
Charlie Marsh 22dbc79994
Use consistent argument ordering for `Dist` conversions (#3868) 2024-05-27 19:48:58 +00:00
Charlie Marsh 3c61eabd9d
Remove unnecessary `::try_from` (#3867)
## Summary

I didn't realize this even worked? We only define a `From` for this
conversion.
2024-05-27 15:18:20 -04:00
Tim de Jager 65b17f6e81
feat: bump pep580 and pep440 types (#3860)
This bumps the versions of pep580 and pep440 to coincide with the
crates.io versions. While not strictly the same, the new types in uv us
an `Inner` struct. Practically I've found I'm still able to use the
patched versions, as can seen from the open PR here:
https://github.com/prefix-dev/pixi/pull/1436.

Would be great if this bump can be done so we can keep combining the
types :)
2024-05-27 09:38:39 +02:00
Zanie Blue 66eb642938
Add test context utility to `uv-interpreter` (#3832)
Follow-up to https://github.com/astral-sh/uv/pull/3797 to clean up the
test isolation in `uv-interpreter`.

I still want to expose a CLI at some point like `uv python <...>` for
discovery and test from there, hopefully this will make that transition
simpler.
2024-05-27 04:17:49 +00:00
Charlie Marsh 14fa49b7ba
Move availability enums into their own module (#3858) 2024-05-27 00:12:53 -04:00
Zanie Blue 31b0ff6373
Gate discovery of managed toolchains with preview (#3835)
Prepares for merge of https://github.com/astral-sh/uv/pull/3797, gating
managed toolchain discovery with the preview flag to lower risk of
releasing.

e.g.

```
❯ cargo dev -q fetch-python         
❯ cargo run -q -- venv --python 3.11
Using Python 3.11.9 interpreter at: /opt/homebrew/opt/python@3.11/bin/python3.11
Creating virtualenv at: .venv
Activate with: source .venv/bin/activate
❯ cargo run -q -- venv --preview --python 3.11
Using Python 3.11.7 interpreter at: /Users/zb/Library/Application Support/uv/toolchains/cpython-3.11.7-macos-aarch64-none/install/bin/python3
Creating virtualenv at: .venv
Activate with: source .venv/bin/activate
```

We'll add automatic fetching of managed interpreters later.
2024-05-27 04:05:19 +00:00
Zanie Blue 30e780e1dd
Add persistent storage of installed toolchains (#3797)
Extends #3726 

Moves toolchain storage out of `UV_BOOTSTRAP_DIR` (`./bin`) into the
proper user data directory as defined by #3726.

Replaces `UV_BOOTSTRAP_DIR` with `UV_TOOLCHAIN_DIR` for customization.
Installed toolchains will be discovered without opt-in, but the idea is
still that these are not yet user-facing.
2024-05-27 03:54:49 +00:00
Charlie Marsh 4191c331a7
Update bundled Python URLs and add `"arm"` architecture variant (#3855)
## Summary

This also adds filtering for the ARM Pythons, since that needs some libc
changes; and it closes https://github.com/astral-sh/uv/issues/3854 by
way of adding an "arm" branch.
2024-05-26 23:33:08 -04:00
Charlie Marsh 61ed0c82ed
Remove unused `Platform` enum (#3856) 2024-05-26 23:21:56 -04:00
Ibraheem Ahmed 7dc322665c
Concurrent progress bars (#3252)
## Summary

Implements concurrent progress bars. Resolves
https://github.com/astral-sh/uv/issues/1209.

## Test Plan

https://github.com/astral-sh/uv/assets/34988408/b21bdfbb-8817-4873-a65c-16c9e8c7c460
2024-05-27 01:21:07 +00:00
Charlie Marsh 70cbc32565
Remove `tracing::log` usage (#3853) 2024-05-27 01:03:28 +00:00
Charlie Marsh 34e1cc8dd4
Use `--exclude-newer` in some `pip sync` tests (#3846)
## Summary

Saw a bunch of failures in
https://github.com/astral-sh/uv/actions/runs/9247239042/job/25435791135?pr=3252
due to `anyio` publishing v0.4.4.
2024-05-27 00:41:18 +00:00
Zanie Blue 98652e3954
Bump version to 0.2.4 (#3840) 2024-05-26 12:11:15 -05:00
konsti f4533c3a85
Ignore libc on other platforms (#3825)
Libc variants are only relevant on linux, we can ignore it on non
{linux, windows, mac}, e.g. BSDs.

Closes #3824
2024-05-25 10:05:10 +00:00
Charlie Marsh c2931e806d
Remove `discovery` group from CLI (#3830)
## Summary

Allows, e.g., `UV_SYSTEM_PYTHON=false uv pip install --python
.venv/bin/python`.

This was intended to work after fixing
https://github.com/astral-sh/uv/issues/3000, but I think I misdiagnosed
the scope when closing that issue, and the linked PR there only fixed
some _other_ problems around index URLs.

The only thing we really lose here is we no longer error when
`--break-system-packages` is provided without `--system`, but we can
enforce that elsewhere if we want.

Closes https://github.com/astral-sh/uv/issues/3829.
2024-05-24 19:03:44 +00:00
Charlie Marsh 6682765630
Require pinned version in `Preference` type (#3828)
## Summary

This PR makes a variety of invalid states unrepresentable by changing
`Preference` to require a `PackageName` and `Version`, rather than
accepting a generic `Requirement`. There should be no meaningful
behavior changes.
2024-05-24 18:48:36 +00:00
Zanie Blue ce4d862b06
Bump version to 0.2.3 (#3827) 2024-05-24 13:19:28 -05:00
Charlie Marsh 688f4f43d4
Ignore unnamed requirements in preferences (#3826)
## Summary

We actually _already_ ignore these (preferences only apply to versions,
not URLs), it just happens later on. This PR thus just avoids crashing.
The behavior is unchanged.

Closes #3822.
2024-05-24 17:32:20 +00:00
Zanie Blue 674d167a50
Fix interpreter cache collisions for relative virtualenv paths (#3823)
Closes #3784

The cache did not use an absolute path. I'm not sure this is actually a
new bug, as this code wasn't touched in #3266 but perhaps there was a
slight difference in the paths we were passing around. Note, just
canonicalizing the path as soon as we see it doesn't work because then
we jump out of the virtual environmnent into the system interpreter.

## Test plan

```
❯ uv venv
Using Python 3.12.3 interpreter at: /opt/homebrew/opt/python@3.12/bin/python3.12
Creating virtualenv at: .venv
Activate with: source .venv/bin/activate
❯ uv pip install anyio
Resolved 3 packages in 81ms
Installed 3 packages in 4ms
 + anyio==4.3.0
 + idna==3.7
 + sniffio==1.3.1
❯ mkdir uv-issue-3784 && cd uv-issue-3784
❯ uv venv
Using Python 3.12.3 interpreter at: /opt/homebrew/opt/python@3.12/bin/python3.12
Creating virtualenv at: .venv
Activate with: source .venv/bin/activate

❯ gcm
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
❯ cargo run -q -- pip list -v -p .venv
DEBUG Checking for Python interpreter in directory `.venv`
TRACE Cached interpreter info for Python 3.12.3, skipping probing: .venv/bin/python3
DEBUG Using Python 3.12.3 environment at .venv/bin/python3
Package Version
------- -------
anyio   4.3.0
idna    3.7
sniffio 1.3.1
❯ cd uv-issue-3784
❯ cargo run -q -- pip list -v -p .venv
DEBUG Checking for Python interpreter in directory `.venv`
TRACE Cached interpreter info for Python 3.12.3, skipping probing: .venv/bin/python3
DEBUG Using Python 3.12.3 environment at /Users/zb/workspace/uv/.venv/bin/python3
Package Version
------- -------
anyio   4.3.0
idna    3.7
sniffio 1.3.1

❯ cd ..
❯ gco zb/fix-relative-venv
Switched to branch 'zb/fix-relative-venv'
❯ cargo run -q -- pip list -v -p .venv
DEBUG Checking for Python interpreter in directory `.venv`
TRACE Cached interpreter info for Python 3.12.3, skipping probing: .venv/bin/python3
DEBUG Using Python 3.12.3 environment at .venv/bin/python3
Package Version
------- -------
anyio   4.3.0
idna    3.7
sniffio 1.3.1
❯ cd uv-issue-3784
❯ cargo run -q -- pip list -v -p .venv
DEBUG Checking for Python interpreter in directory `.venv`
TRACE Cached interpreter info for Python 3.12.3, skipping probing: .venv/bin/python3
DEBUG Using Python 3.12.3 environment at .venv/bin/python3
```
2024-05-24 11:18:49 -05:00
Charlie Marsh 999d072ae9
Always include package names for Git and HTTPS dependencies (#3821)
## Summary

Related to https://github.com/astral-sh/uv/issues/3818. We should
_always_ include the package name if we know it's not a file path, even
if it starts with an environment variable.
2024-05-24 14:01:38 +00:00
Charlie Marsh 73f67089e1
Add JSON alias for `unsafe-any-match` (#3820)
Closes https://github.com/astral-sh/uv/issues/3819.
2024-05-24 13:31:46 +00:00
Charlie Marsh 8d566e553d
Use a cross-platform representation for relative paths in `pip compile` (#3804)
## Summary

I haven't tested on Windows yet, but the idea here is that we should use
a portable representation when printing paths.

I decided to limit the scope here to paths that we write to output
files.

Closes https://github.com/astral-sh/uv/issues/3800.
2024-05-24 03:02:42 +00:00
Charlie Marsh a7d486bc71
Move `render-benchmarks` under a Cargo feature (#3815)
## Summary

Avoid compiling these large dependencies when we typically don't need
them.
2024-05-24 03:00:53 +00:00
Charlie Marsh ce38fccdc9
Remove `tracing-indicatif` dependency (#3816)
## Summary

It's only used in `uv-dev`; can restore later if important.
2024-05-24 02:59:26 +00:00
Charlie Marsh dd27f2f710
Make anyhow a dev dependency in `uv-configuration` (#3814) 2024-05-24 02:49:31 +00:00
Charlie Marsh e8e826949d
Remove WerkZeug source builds from tests (#3813) 2024-05-24 02:16:34 +00:00
Charlie Marsh c25a6f08cd
Remove `anyio` source builds from hash tests (#3812) 2024-05-24 01:51:59 +00:00
Charlie Marsh c7b9823b64
Remove `ujson` test (#3811)
## Summary

I believe this is tested by the following test
(`install_build_system_no_backend`), which seems to have identical
constraints.

Closes #3743.
2024-05-24 01:40:30 +00:00
Charlie Marsh 6860b04f28
Remove `anyio` Git builds from tests (#3810) 2024-05-24 01:33:24 +00:00
Charlie Marsh e654c62e2e
Remove `bz2` builds from tests (#3809) 2024-05-23 21:26:41 -04:00
Charlie Marsh 585146391a
Remove `tqdm` builds from tests (#3808) 2024-05-24 01:17:45 +00:00
Charlie Marsh a02e225eec
Remove werkzeug Git builds from tests (#3806) 2024-05-23 21:17:07 -04:00
Charlie Marsh 710c11c6ad
Remove `future` builds from tests (#3807) 2024-05-24 01:09:39 +00:00
Zanie Blue 99b8633ce3
Search for `python3` in unix virtual environments (#3798) 2024-05-23 19:33:34 -05:00
Zanie Blue 73b6a80f23
Remove extra details from interpreter query traces (#3803)
Cherry-picked from
8f135c26f4
2024-05-23 18:18:05 -05:00
Charlie Marsh a9d9a6c13f
Incorporate build tag into wheel prioritization (#3781)
## Summary

It turns out that in the
[spec](https://packaging.python.org/en/latest/specifications/binary-distribution-format/#file-name-convention),
if a wheel filename includes a build tag, then we need to use it to
break ties. This PR implements that behavior. (Previously, we dropped
the build tag entirely.)

Closes #3779.

## Test Plan

Run: `cargo run pip install -i https://pypi.anaconda.org/intel/simple
mkl_fft==1.3.8 --python-platform linux --python-version 3.10`. This now
resolves without error. Previously, we selected build tag 63 of
`mkl_fft==1.3.8`, which led to an incompatibility with NumPy. Now, we
select build tag 70.
2024-05-23 21:12:53 +00:00
Charlie Marsh 5bebaddc24
Make `anyhow` a dev dependency in `pypi-types` (#3801) 2024-05-23 16:58:22 -04:00
konsti 4db468e27f
Use `VerbatimParsedUrl` in `pep508_rs` (#3758)
When parsing requirements from any source, directly parse the url parts
(and reject unsupported urls) instead of parsing url parts at a later
stage. This removes a bunch of error branches and concludes the work
parsing url parts once and passing them around everywhere.

Many usages of the assembled `VerbatimUrl` remain, but these can be
removed incrementally.

Please review commit-by-commit.
2024-05-23 19:52:47 +00:00
Ibraheem Ahmed 0d2f3fc4e4
Add airflow benchmark (#3643)
## Summary

This seems to be one of the most consistent benchmark cases we have in
terms of standard deviation:
```
➜  hyperfine "target/profiling/main pip compile scripts/requirements/airflow.in" --runs 200
Benchmark 1: target/profiling/main pip compile scripts/requirements/airflow.in
  Time (mean ± σ):     292.6 ms ±   6.6 ms    [User: 414.1 ms, System: 194.2 ms]
  Range (min … max):   282.7 ms … 320.1 ms    200 runs
```

For smaller benchmarks, scispacy and dtlssocket seem to be a bit more
consistent than our current jupyter benchmark, but it hasn't given us
any problems so I'll leave it for now.
2024-05-23 13:25:54 -04:00
Zanie Blue 8f0f4d2e0c
Improve logging during interpreter discovery (#3790) 2024-05-23 10:25:22 -05:00
Zanie Blue d2a9192e39
Avoid displaying log for satisfied editables if none are requested (#3795)
e.g. in `uv pip install anyio -v` this message is just noise

```
DEBUG Requirement satisfied: anyio
DEBUG Requirement satisfied: idna>=2.8
DEBUG Requirement satisfied: sniffio>=1.1
DEBUG All editables satisfied: 
```
2024-05-23 15:07:35 +00:00
Zanie Blue 306a4d7ce3
Improve logging of interpreter implementation (#3791)
```
Found Python interpreter CPython 3.12.3 at...
```

instead of

```
Found Python interpreter cpython 3.12.3 at
```
2024-05-23 10:00:45 -05:00
Zanie Blue 81eff0ecc8
Improve logging for environment locking (#3792)
```
DEBUG Acquired lock for `.venv`
```

instead of

```
DEBUG Trying to lock if free: .venv/.lock
```

At trace level, this includes the pre-lock message as well

```
TRACE Checking lock for `.venv`
DEBUG Acquired lock for `.venv`
```

We'll still display the lock file path when something goes wrong
2024-05-23 09:27:07 -05:00
Zanie Blue ddfbee1cb6
Add `InterpreterRequest::Any` instead of using `VersionRequest::Any` (#3789)
A follow-up to #3266 addressing some awkwardness where there was no
"empty" or default interpreter request kind.
2024-05-23 13:22:34 +00:00
konsti 91ed1c6c7c
Fix interpreter discovery for tests (#3785)
The venv subcommand requires a system interpreter. The tests python path
discovery would previously allow a venv interpreter, failing the venv
tests that don't have system interpreter anymore.

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2024-05-23 12:56:19 +00:00
konsti 2a17309782
Use colon more consistently in error messages (#3788)
Make the error messages more consistent with the format use elsewhere.
Split out from https://github.com/astral-sh/uv/pull/3705
2024-05-23 14:33:21 +02:00
Zanie Blue 9b870f20f1
Allow specification of additional requirements in `uv tool run` (#3678)
Allows requesting additional transitive dependencies when running a
tool.

e.g. `uv tool run -v --with anyio ruff check example.py` (Why would you
want anyio with ruff? Who knows 😄)

The motivation for doing this now is that I think the first
implementation of `uv tool install` might just shim into `uv tool run`
with pinned dependencies? Regardless this is something we need in the
long run and is a trivial addition right now.
2024-05-22 20:59:04 -05:00
Charlie Marsh 79fecdf251
Add a diagnostic trait (#3777) 2024-05-22 19:44:37 -04:00
Charlie Marsh 9db6852f64
Initialize cache in `tool run` (#3776)
## Summary

Closes https://github.com/astral-sh/uv/issues/3775.
2024-05-22 22:59:35 +00:00
Zanie Blue e52ae0e2bc
Bump version to 0.2.2 (#3774) 2024-05-22 21:45:00 +00:00
Zanie Blue a6043553c8
Improve error message when default Python is not found (#3770) 2024-05-22 16:28:52 -05:00
Zanie Blue 87b73ef7a9
Do not treat interpereters discovered via `CONDA_PREFIX` as system interpreters (#3771)
Closes https://github.com/astral-sh/uv/issues/3769
2024-05-22 16:27:33 -05:00
Charlie Marsh 74c494d7dd
Report yanks for cached and resolved packages (#3772)
## Summary

We now show yanks as part of the resolution diagnostics, so they now
appear for `sync`, `install`, `compile`, and any other operations.
Further, they'll also appear for cached packages (but not packages that
are _already_ installed).

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

Closes #3766.
2024-05-22 21:21:37 +00:00
Charlie Marsh 1fc71ea736
Bump version to v0.2.1 (#3763) 2024-05-22 20:05:17 +00:00
Zanie Blue d66d326954
Allow users to specify a custom source package to `uv tool run` (#3677)
We usually infer the package the tool is pulled from to be the same name
as the tool itself, but that's not always the case. This allows users to
provide a custom package.
2024-05-22 14:48:54 -05:00
Charlie Marsh 0efc5d0cab
Reuse reporting operation in `venv` (#3755) 2024-05-22 15:43:20 -04:00
Charlie Marsh 3a75b50d5b
Use pip "operations" API in project commands (#3759)
## Summary

This PR removes most of the code in `project/mod.rs` in favor of the
routines exposed in `pip/operations.rs`.

I think we can do a lot more to add more abstraction here and reduce the
verbosity, but for now it deduplicates a _ton_ of logic. The remaining
logic is just instantiating settings etc.
2024-05-22 15:43:12 -04:00
Charlie Marsh fe28b2c278
Remove unused methods from `Resolution` (#3754) 2024-05-22 18:48:44 +00:00
Nyakku Shigure 0a87391d5d
Capture clang and msvc missing header error (#3753)
## Summary

Fixes #3732

The full log for MSVC and clang is as follows:

Clang (on macOS):

```
pip install pygraphviz
Collecting pygraphviz
  Downloading pygraphviz-1.13.tar.gz (104 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 104.6/104.6 kB 964.1 kB/s eta 0:00:00
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Installing backend dependencies ... done
  Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: pygraphviz
  Building wheel for pygraphviz (pyproject.toml) ... error
  error: subprocess-exited-with-error

  × Building wheel for pygraphviz (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [63 lines of output]
      running bdist_wheel
      running build
      running build_py
      creating build
      creating build/lib.macosx-14.0-arm64-cpython-311
      creating build/lib.macosx-14.0-arm64-cpython-311/pygraphviz
      copying pygraphviz/scraper.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz
      copying pygraphviz/graphviz.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz
      copying pygraphviz/__init__.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz
      copying pygraphviz/agraph.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz
      copying pygraphviz/testing.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz
      creating build/lib.macosx-14.0-arm64-cpython-311/pygraphviz/tests
      copying pygraphviz/tests/test_unicode.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz/tests
      copying pygraphviz/tests/test_scraper.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz/tests
      copying pygraphviz/tests/test_readwrite.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz/tests
      copying pygraphviz/tests/test_string.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz/tests
      copying pygraphviz/tests/__init__.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz/tests
      copying pygraphviz/tests/test_html.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz/tests
      copying pygraphviz/tests/test_node_attributes.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz/tests
      copying pygraphviz/tests/test_drawing.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz/tests
      copying pygraphviz/tests/test_repr_mimebundle.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz/tests
      copying pygraphviz/tests/test_subgraph.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz/tests
      copying pygraphviz/tests/test_close.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz/tests
      copying pygraphviz/tests/test_edge_attributes.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz/tests
      copying pygraphviz/tests/test_clear.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz/tests
      copying pygraphviz/tests/test_layout.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz/tests
      copying pygraphviz/tests/test_attribute_defaults.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz/tests
      copying pygraphviz/tests/test_graph.py -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz/tests
      running egg_info
      writing pygraphviz.egg-info/PKG-INFO
      writing dependency_links to pygraphviz.egg-info/dependency_links.txt
      writing top-level names to pygraphviz.egg-info/top_level.txt
      reading manifest file 'pygraphviz.egg-info/SOURCES.txt'
      reading manifest template 'MANIFEST.in'
      warning: no files found matching '*.swg'
      warning: no files found matching '*.png' under directory 'doc'
      warning: no files found matching '*.html' under directory 'doc'
      warning: no files found matching '*.txt' under directory 'doc'
      warning: no files found matching '*.css' under directory 'doc'
      warning: no previously-included files matching '*~' found anywhere in distribution
      warning: no previously-included files matching '*.pyc' found anywhere in distribution
      warning: no previously-included files matching '.svn' found anywhere in distribution
      no previously-included directories found matching 'doc/build'
      adding license file 'LICENSE'
      writing manifest file 'pygraphviz.egg-info/SOURCES.txt'
      copying pygraphviz/graphviz.i -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz
      copying pygraphviz/graphviz_wrap.c -> build/lib.macosx-14.0-arm64-cpython-311/pygraphviz
      running build_ext
      building 'pygraphviz._graphviz' extension
      creating build/temp.macosx-14.0-arm64-cpython-311
      creating build/temp.macosx-14.0-arm64-cpython-311/pygraphviz
      clang -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk -I/opt/homebrew/opt/openssl@3.0/include -DSWIG_PYTHON_STRICT_BYTE_CHAR -I/Users/nyakku/Projects/yutto/.venv/include -I/opt/homebrew/opt/python@3.11/Frameworks/Python.framework/Versions/3.11/include/python3.11 -c pygraphviz/graphviz_wrap.c -o build/temp.macosx-14.0-arm64-cpython-311/pygraphviz/graphviz_wrap.o
      pygraphviz/graphviz_wrap.c:9:9: warning: 'SWIG_PYTHON_STRICT_BYTE_CHAR' macro redefined [-Wmacro-redefined]
          9 | #define SWIG_PYTHON_STRICT_BYTE_CHAR
            |         ^
      <command line>:2:9: note: previous definition is here
          2 | #define SWIG_PYTHON_STRICT_BYTE_CHAR 1
            |         ^
      pygraphviz/graphviz_wrap.c:3023:10: fatal error: 'graphviz/cgraph.h' file not found
       3023 | #include "graphviz/cgraph.h"
            |          ^~~~~~~~~~~~~~~~~~~
      1 warning and 1 error generated.
      error: command '/opt/homebrew/opt/llvm/bin/clang' failed with exit code 1
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for pygraphviz
Failed to build pygraphviz
ERROR: Could not build wheels for pygraphviz, which is required to install pyproject.toml-based projects

[notice] A new release of pip is available: 23.3.1 -> 24.0
[notice] To update, run: pip install --upgrade pip
```

MSVC (on Windows):

```
pip install pygraphviz
Collecting pygraphviz
  Downloading pygraphviz-1.13.tar.gz (104 kB)
     |████████████████████████████████| 104 kB 595 kB/s
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Installing backend dependencies ... done
    Preparing wheel metadata ... done
Building wheels for collected packages: pygraphviz
  Building wheel for pygraphviz (PEP 517) ... error
  ERROR: Command errored out with exit status 1:
   command: 'C:\Python310\python.exe' 'C:\Python310\lib\site-packages\pip\_vendor\pep517\in_process\_in_process.py' build_wheel 'C:\Users\PADDLE~2\AppData\Local\Temp\tmpbl6h1qvd'
       cwd: C:\Users\paddle_dev2\AppData\Local\Temp\pip-install-2e4v3xju\pygraphviz_034fe74e775e43e3935b6a88e2cd4761
  Complete output (58 lines):
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build\lib.win-amd64-cpython-310
  creating build\lib.win-amd64-cpython-310\pygraphviz
  copying pygraphviz\agraph.py -> build\lib.win-amd64-cpython-310\pygraphviz
  copying pygraphviz\graphviz.py -> build\lib.win-amd64-cpython-310\pygraphviz
  copying pygraphviz\scraper.py -> build\lib.win-amd64-cpython-310\pygraphviz
  copying pygraphviz\testing.py -> build\lib.win-amd64-cpython-310\pygraphviz
  copying pygraphviz\__init__.py -> build\lib.win-amd64-cpython-310\pygraphviz
  creating build\lib.win-amd64-cpython-310\pygraphviz\tests
  copying pygraphviz\tests\test_attribute_defaults.py -> build\lib.win-amd64-cpython-310\pygraphviz\tests
  copying pygraphviz\tests\test_clear.py -> build\lib.win-amd64-cpython-310\pygraphviz\tests
  copying pygraphviz\tests\test_close.py -> build\lib.win-amd64-cpython-310\pygraphviz\tests
  copying pygraphviz\tests\test_drawing.py -> build\lib.win-amd64-cpython-310\pygraphviz\tests
  copying pygraphviz\tests\test_edge_attributes.py -> build\lib.win-amd64-cpython-310\pygraphviz\tests
  copying pygraphviz\tests\test_graph.py -> build\lib.win-amd64-cpython-310\pygraphviz\tests
  copying pygraphviz\tests\test_html.py -> build\lib.win-amd64-cpython-310\pygraphviz\tests
  copying pygraphviz\tests\test_layout.py -> build\lib.win-amd64-cpython-310\pygraphviz\tests
  copying pygraphviz\tests\test_node_attributes.py -> build\lib.win-amd64-cpython-310\pygraphviz\tests
  copying pygraphviz\tests\test_readwrite.py -> build\lib.win-amd64-cpython-310\pygraphviz\tests
  copying pygraphviz\tests\test_repr_mimebundle.py -> build\lib.win-amd64-cpython-310\pygraphviz\tests
  copying pygraphviz\tests\test_scraper.py -> build\lib.win-amd64-cpython-310\pygraphviz\tests
  copying pygraphviz\tests\test_string.py -> build\lib.win-amd64-cpython-310\pygraphviz\tests
  copying pygraphviz\tests\test_subgraph.py -> build\lib.win-amd64-cpython-310\pygraphviz\tests
  copying pygraphviz\tests\test_unicode.py -> build\lib.win-amd64-cpython-310\pygraphviz\tests
  copying pygraphviz\tests\__init__.py -> build\lib.win-amd64-cpython-310\pygraphviz\tests
  running egg_info
  writing pygraphviz.egg-info\PKG-INFO
  writing dependency_links to pygraphviz.egg-info\dependency_links.txt
  writing top-level names to pygraphviz.egg-info\top_level.txt
  reading manifest file 'pygraphviz.egg-info\SOURCES.txt'
  reading manifest template 'MANIFEST.in'
  warning: no files found matching '*.swg'
  warning: no files found matching '*.png' under directory 'doc'
  warning: no files found matching '*.html' under directory 'doc'
  warning: no files found matching '*.txt' under directory 'doc'
  warning: no files found matching '*.css' under directory 'doc'
  warning: no previously-included files matching '*~' found anywhere in distribution
  warning: no previously-included files matching '*.pyc' found anywhere in distribution
  warning: no previously-included files matching '.svn' found anywhere in distribution
  no previously-included directories found matching 'doc\build'
  adding license file 'LICENSE'
  writing manifest file 'pygraphviz.egg-info\SOURCES.txt'
  copying pygraphviz\graphviz.i -> build\lib.win-amd64-cpython-310\pygraphviz
  copying pygraphviz\graphviz_wrap.c -> build\lib.win-amd64-cpython-310\pygraphviz
  running build_ext
  building 'pygraphviz._graphviz' extension
  creating build\temp.win-amd64-cpython-310
  creating build\temp.win-amd64-cpython-310\Release
  creating build\temp.win-amd64-cpython-310\Release\pygraphviz
  "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\HostX86\x64\cl.exe" /c /nologo /O2 /W3 /GL /DNDEBUG /MD -DSWIG_PYTHON_STRICT_BYTE_CHAR -DGVDLL -IC:\Python310\include -IC:\Python310\Include "-IC:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\ATLMFC\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\include" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\winrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\cppwinrt" "-IC:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\ATLMFC\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\include" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\winrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\cppwinrt" /Tcpygraphviz/graphviz_wrap.c /Fobuild\temp.win-amd64-cpython-310\Release\pygraphviz/graphviz_wrap.obj
  graphviz_wrap.c
  pygraphviz/graphviz_wrap.c(9): warning C4005: 'SWIG_PYTHON_STRICT_BYTE_CHAR': macro redefinition
  pygraphviz/graphviz_wrap.c: note: see previous definition of 'SWIG_PYTHON_STRICT_BYTE_CHAR'
  pygraphviz/graphviz_wrap.c(3023): fatal error C1083: Cannot open include file: 'graphviz/cgraph.h': No such file or directory
  error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\bin\\HostX86\\x64\\cl.exe' failed with exit code 2
  ----------------------------------------
  ERROR: Failed building wheel for pygraphviz
Failed to build pygraphviz
ERROR: Could not build wheels for pygraphviz which use PEP 517 and cannot be installed directly
WARNING: You are using pip version 21.2.3; however, version 24.0 is available.
You should consider upgrading via the 'C:\Python310\python.exe -m pip install --upgrade pip' command.
```

## Test Plan

Running `cargo run -- pip install pygraphviz` and expecting to get
`Caused by: This error likely indicates that you need to install a
library that provides "graphviz/cgraph.h" for pygraphviz==1.13`
2024-05-22 14:40:49 -04:00
Charlie Marsh e6cdf36cff
Move modification reporting into a helper method (#3752) 2024-05-22 18:40:07 +00:00
Zanie Blue 1dd6b89be8
Bump version to 0.2.0 (#3745) 2024-05-22 13:39:34 -05:00
Zanie Blue 0e75eb8d78
Improve display of selected interpreter sources (#3748)
e.g. this error message is not great

```
❯ uv venv --python 3.12.2
  × No interpreter found for Python 3.12.2 in provided path, search path, managed toolchains, or parent interpreter
```
2024-05-22 13:39:22 -05:00
Zanie Blue 6962147831
Add display of interpreter request (#3751)
e.g. 

```
❯ echo "anyio" | cargo run -q -- pip compile - --python 3.9 -v
DEBUG Searching for interpreter that fulfills Python @ 3.9
DEBUG Found a virtual environment at: /Users/zb/workspace/uv/.venv
DEBUG Using Python 3.9.18 interpreter at bin/cpython-3.9.18-macos-aarch64-none/install/bin/python3 for builds
```
2024-05-22 18:26:35 +00:00
Zanie Blue d5ac2f53d3
Improve display of interpreter implementation names (#3749)
e.g. instead of

```
❯ uv venv --python pypy@3.10
  × No interpreter found for pypy 3.10 in search path
```

we say

```
❯ uv venv --python pypy@3.10
  × No interpreter found for PyPy 3.10 in search path
```
2024-05-22 18:22:09 +00:00
Zanie Blue 845d788c91
Drop Python patch test flag from default features (#3746) 2024-05-22 17:19:25 +00:00
Charlie Marsh 7585250107
Report yanked distributions in `--dry-run` (#3740)
## Summary

Closes #3703.
2024-05-22 16:37:11 +00:00
Zanie Blue 5fe891082d
Discover and prefer the parent interpreter when invoked with `python -m uv` (#3736)
Closes #2222
Closes https://github.com/astral-sh/uv/issues/2058
Replaces https://github.com/astral-sh/uv/pull/2338
See also https://github.com/astral-sh/uv/issues/2649

We use an environment variable (`UV_INTERNAL__PARENT_INTERPRETER`) to
track the invoking interpreter when `python -m uv` is used. The parent
interpreter is preferred over all other sources (though it will be
skipped if it does not meet a `--python` request or if `--system` is
used and it belongs to a virtual environment). We warn if `--system` is
not provided and this interpreter would mutate system packages, but
allow it.
2024-05-22 11:34:24 -05:00
Charlie Marsh b92321bd2d
Allow `--constraint` files in `pip sync` (#3741)
## Summary

Trivial now that this follows the same strategy and internals as `pip
install`.

Closes https://github.com/astral-sh/uv/issues/3438.
2024-05-22 16:30:54 +00:00
Zanie Blue 7afc3f6eb0
Filter discovered Python interpreters by system preference (#3739)
Previously, we enforced `SystemPython` outside of the interpreter
discovery exclusively with source selection. Now, we perform additional
filtering of interpreters depending on if they are a virtual
environment. This should not change any existing behavior, but will make
it much easier to have consistent behavior in ambiguous cases like
https://github.com/astral-sh/uv/pull/3736#discussion_r1610072262 where a
source could provide either a system interpreter or virtual environment
interpreter.
2024-05-22 11:22:09 -05:00
Charlie Marsh 0313e7d78b
Use common routines for `pip install` and `pip sync` (#3737)
## Summary

This PR takes the functions used in `pip install`, moves them into a
common module, and then replaces all the `pip sync` logic with calls
into those functions. The net effect is that `pip install` and `pip
sync` share far more code and demonstrate much more consistent behavior.

Closes https://github.com/astral-sh/uv/issues/3555.
2024-05-22 12:15:17 -04:00
Zanie Blue b8ef436c42
Do not display "py launcher" source in error messages on Unix (#3738) 2024-05-22 15:22:15 +00:00
Charlie Marsh e398444f2f
Track editable requirements in lockfile (#3725)
## Summary

This PR adds editables using a new source type (`editable+...`), and
then extracts the editables from the lockfile in `uv sync`.

Closes https://github.com/astral-sh/uv/issues/3695.
2024-05-22 09:06:18 -04:00
Charlie Marsh d912c37539
Add instructions for building and updating uv-trampolines (#3731) 2024-05-21 22:49:14 -04:00
Ofek Lev 82820d0f4c
Allow relative Python executable paths in Windows trampoline (#3717)
## Summary

This is a prerequisite for https://github.com/astral-sh/uv/issues/3669

## Test Plan

Download one of the standalone distributions on Windows then use its
Python to run the following script and then run the scripts it creates
(only pip):

```python
from __future__ import annotations

import sys
import sysconfig
from contextlib import closing
from importlib.metadata import entry_points
from io import BytesIO
from os.path import relpath
from pathlib import Path
from tempfile import TemporaryDirectory
from zipfile import ZIP_DEFLATED, ZipFile, ZipInfo

# Change this line to your real path
LAUNCHERS_DIR = Path('C:\\Users\\ofek\\Desktop\\code\\uv\\crates\\uv-trampoline\\target\\x86_64-pc-windows-msvc\\release')
SCRIPT_TEMPLATE = """\
#!{executable}
# -*- coding: utf-8 -*-
import re
import sys
from {module} import {import_name}
if __name__ == "__main__":
    sys.argv[0] = re.sub(r"(-script\\.pyw|\\.exe)?$", "", sys.argv[0])
    sys.exit({function}())
"""


def select_entry_points(ep, group):
    return ep.select(group=group) if sys.version_info[:2] >= (3, 10) else ep.get(group, [])


def main():
    interpreters_dir = Path(sys.executable).parent
    scripts_dir = Path(sysconfig.get_path('scripts'))

    ep = entry_points()
    for group, interpreter_name, launcher_name in (
        ('console_scripts', 'python.exe', 'uv-trampoline-console.exe'),
        ('gui_scripts', 'pythonw.exe', 'uv-trampoline-gui.exe'),
    ):
        interpreter = interpreters_dir / interpreter_name
        relative_interpreter_path = relpath(interpreter, scripts_dir)
        launcher_data = (LAUNCHERS_DIR / launcher_name).read_bytes()

        for script in select_entry_points(ep, group):
            # https://github.com/astral-sh/uv/tree/main/crates/uv-trampoline#how-do-you-use-it
            with closing(BytesIO()) as buf:
                # Launcher
                buf.write(launcher_data)

                # Zipped script
                with TemporaryDirectory() as td:
                    zip_path = Path(td) / 'script.zip'
                    with ZipFile(zip_path, 'w') as zf:
                        # Ensure reproducibility
                        zip_info = ZipInfo('__main__.py', (2020, 2, 2, 0, 0, 0))
                        zip_info.external_attr = (0o644 & 0xFFFF) << 16

                        module, _, attrs = script.value.partition(':')
                        contents = SCRIPT_TEMPLATE.format(
                            executable=relative_interpreter_path,
                            module=module,
                            import_name=attrs.split('.')[0],
                            function=attrs
                        )
                        zf.writestr(zip_info, contents, compress_type=ZIP_DEFLATED)

                    buf.write(zip_path.read_bytes())

                # Interpreter path
                interpreter_path = relative_interpreter_path.encode('utf-8')
                buf.write(interpreter_path)

                # Interpreter path length
                interpreter_path_length = len(interpreter_path).to_bytes(4, 'little')
                buf.write(interpreter_path_length)

                # Magic number
                buf.write(b'UVUV')

                script_data = buf.getvalue()

            script_path = scripts_dir / f'{script.name}.exe'
            script_path.write_bytes(script_data)


if __name__ == '__main__':
    main()
```
2024-05-21 21:53:15 -04:00
Zanie Blue becdc64d3e
Do not discover virtual environment interpreters in `uv venv --python ...` (#3728)
Otherwise `uv venv --python 3.12` can prefer `.venv/bin/python` over the
system Python (which is always used if you don't provide a `--python`
flag). I would find this confusing as a user.
2024-05-21 20:00:21 -05:00
Charlie Marsh e71ce53983
Allow `--config-file` to be passed before or after command name (#3730) 2024-05-22 00:12:10 +00:00
Charlie Marsh d33577fc16
Make `--offline` a global argument (#3729) 2024-05-22 00:09:05 +00:00
Charlie Marsh 285adaed64
Remove some dependencies on `EditableRequirement` (#3727)
## Summary

Use `LocalEditable` instead throughout the `ResolvedEditable` pipeline.
2024-05-21 23:36:53 +00:00
Zanie Blue 1379fb7dcd
Add support for requesting `pypy` interpreters by implementation name (#3706)
Updates our executable name searches to support implementation names
i.e. `cpython` and `pypy` and adds support for PyPy.

We might want to _not_ support searching for `cpython` because that's
non-standard?
2024-05-21 16:48:43 -05:00
Zanie Blue 84afca2696
Add offline support to `uv tool run` and `uv run` (#3676)
Adds `--offline` support to `uv tool run` and `uv run` because I needed
it on the airplane today.

I think we should move `--offline` to the global settings like
`--native-tls`.
2024-05-21 15:58:15 -05:00
Charlie Marsh e0b639828d
Revert "Support editables in `uv sync` (#3692)" (#3696) (#3722)
## Summary

This is just a re-apply of #3696, which @konstin accidentally reverted
in #3585.

Co-authored-by: konsti <konstin@mailbox.org>
2024-05-21 16:41:15 -04:00
Zanie Blue 92c70134d1
Fix `uv tool run` interpreter lookup (#3721) 2024-05-21 16:33:39 -04:00
Charlie Marsh 558f628ef1
Propagate URL errors in verbatim parsing (#3720)
## Summary

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

## Test Plan

```
❯ echo "/../test" | cargo run pip compile -
error: Couldn't parse requirement in `-` at position 0
  Caused by: path could not be normalized: /../test
/../test
^^^^^^^^

❯ echo "-e /../test" | cargo run pip compile -
error: Invalid URL in `-`: `/../test`
  Caused by: path could not be normalized: /../test
  Caused by: cannot normalize a relative path beyond the base directory
```
2024-05-21 19:58:59 +00:00
Zanie Blue 19df1a4372
Rename all instances of `Cpython` to `CPython` (#3702) 2024-05-21 14:52:31 -05:00
Zanie Blue d313d9b1fa
Add initial implementation of `uv tool run` (#3657)
This is mostly a shorter version of `uv run` that infers a requirement
name from the command. The main goal here is to do the smallest amount
of work necessary to get #3560 started.

Closes #3613 

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

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

Some noteworthy implementation changes:

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

Remaining work:

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

Refactors split into:

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

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

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

we'll say

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

Closes #3710 

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

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

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

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

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

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

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

## Test Plan

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

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

## Benchmarks

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

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

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

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

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

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

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

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

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

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

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

<!--
Thank you for contributing to uv! To help us out with reviewing, please
consider the following:

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

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

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

Any other form will fail.

Meanwhile, _all_ of these work:

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

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

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

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

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

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

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

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

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

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

## Test Plan

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

## Test Plan

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

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

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

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

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

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

## Test Plan

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

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

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

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

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

## Test Plan

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

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

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

### Problem

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

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

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

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

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

```

## Test Plan

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

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

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

For example, given:

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

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

This logic also extends to extras. So given:

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

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

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

(I.e., remove the space.)

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

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

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

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

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

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

With this PR, wheels are now correctly plumbed through:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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