Commit graph

2258 commits

Author SHA1 Message Date
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