Commit Graph

3783 Commits

Author SHA1 Message Date
Charlie Marsh b37170df94
Rename `ResolutionGraph` to `ResolverOutput` (#9103)
## Summary

As discussed in Discord... This struct has evolved to include a lot of
information apart from the `petgraph::Graph`. And I want to add a graph
to the simplified `Resolution` type. So I think this name makes more
sense.
2024-11-14 14:51:11 +00:00
konsti 02a7bb43d9
Minimal wheel settings (#9085)
A small refactoring and minimal wheel settings. source tree -> source
dist -> wheel is working, which we'll add tests for in the next PR.
2024-11-14 13:40:09 +00:00
konsti 4ac78f673b
Build backend: Switch to custom glob-walkdir implementation (#9013)
When doing a directory traversal for source dist inclusion, we want to
offer the user include and exclude options, and we want to avoid
traversing irrelevant directories. The latter is important for
performance, especially on network file systems, but also with large
data directories, or (not-included) directories with other permissions.
To support this, we introduce `GlobDirFilter`, which uses a DFA from
regex_automata to determine whether any children of a directory can be
included and skips the directory if not.

The globs are based on PEP 639. The syntax is more restricted than glob
or globset, but it's standardized. I chose it over glob or globset
because we're already using this syntax for `project.license-files` a
required by PEP 639, so it makes sense to use the same globs for all
includes (see e.g.
4f52a3bb62/pyproject.toml (L36-L48)
for example with same semantics for include and exclude)

### Semantics

Glob semantics are complex due to mixing directories and files,
expectations around simplicity and our need to exclude most of the tree
in the project from traversal. The current draft uses a syntax that
optimizes for simple default use cases for the start.

#### includes

Glob expressions which files and directories to include in the source
distribution.

Includes are anchored, which means that `pyproject.toml` includes only
`<project root>/pyproject.toml`. Use for example `assets/**/sample.csv`
to include for all
`sample.csv` files in `<project root>/assets` or any child directory. To
recursively include
all files under a directory, use a `/**` suffix, e.g. `src/**`. For
performance and
reproducibility, avoid unanchored matches such as `**/sample.csv`.

The glob syntax is the reduced portable glob from
[PEP 639](https://peps.python.org/pep-0639/#add-license-FILES-key).

#### excludes

Glob expressions which files and directories to exclude from the
previous source
distribution includes.

Excludes are not, which means that `__pycache__` excludes all
directories named
`__pycache__` and it's children anywhere. To anchor a directory, use a
`/` prefix, e.g.,
`/dist` will exclude only `<project root>/dist`.

The glob syntax is the reduced portable glob from
[PEP 639](https://peps.python.org/pep-0639/#add-license-FILES-key).
2024-11-14 13:14:58 +00:00
Andrew Gallant e310dcc7c1 doc: tweak docs a bit
We also update the docs for flags like `--extra` to note that they may
result in an error if they try to enable extras that are conflicting.
2024-11-14 08:02:46 -05:00
Andrew Gallant c68e0d624e uv: expose `conflicts` in `tool.uv` in `pyproject.toml` 2024-11-14 08:02:46 -05:00
Andrew Gallant c0440e93cf uv/tests: add a few tests for conflicting groups
This includes a test where we define a conflict between an extra and a
group.
2024-11-14 08:02:46 -05:00
Andrew Gallant 277e7f8dd0 uv-resolver: support conflicting groups
Surprisingly, this seems to be all that's necessary.

Previously, we were only extracting an extra from a
PubGrubPackage to test for conflicts. But now we extract
either an extra or a group. The surrounding code all
remains the same.

We do need to add some extra checking for groups
specifically, but I believe that's it.
2024-11-14 08:02:46 -05:00
Andrew Gallant 3f483d5911 uv-pypi-types: make 'contains' methods generic
This lets us ask whether an `&ExtraName` or a `&GroupName` is contained
in a particular conflict set.
2024-11-14 08:02:46 -05:00
Andrew Gallant 06943ca870 uv-pypi-types: make room for group names in addition to extras
This adds support for providing conflicting group names in addition to
extra names to `Conflicts`.

This merely makes "room" for it in the types while keeping everything
working. We'll add proper support for it in the next commit.

Note that one interesting trick we do here is depend directly on
`hashbrown` so that we can make use of its `Equivalent` trait. This in
turn lets us use things like `ConflictItemRef` as a lookup key for a
hashset that contains `ConflictItem`. This mirrors using a `&str` as a
lookup key for a hashset that contains `String`, but works for arbitrary
types. `std` doesn't support this, but `hashbrown` does. This trick in
turn lets us simplify some of our data structures.

This also rejiggers some of the serde-interaction with the conflicting
types. We now use a wire type to represent our conflicting items for
more flexibility. i.e., Support `extra` XOR `group` fields.
2024-11-14 08:02:46 -05:00
Andrew Gallant cda8b3276a uv-resolver: add to `diverging_packages` when forking based on conflicts
This addresses Konsti's comment about it being empty:
https://github.com/astral-sh/uv/pull/8976#discussion_r1837951568
2024-11-14 08:02:46 -05:00
Andrew Gallant c2c9bd9557 uv/tests: adds a test with mutually exclusive extras across a workspace
This tests comes from here:
https://github.com/astral-sh/uv/pull/8976#issuecomment-2473672199

And it was originally thought of by Konsti.

This test case is the motivation for making `package` optional in
`conflicts` instead of forbidding it entirely.
2024-11-14 08:02:46 -05:00
Andrew Gallant bb78e00a87 *: update "conflicting groups" terminology everywhere else 2024-11-14 08:02:46 -05:00
Andrew Gallant 19a044d4db uv-pypi-types: rename "conflicting group" types to more generic "conflicts"
Since this is intended to support _both_ groups and extras, it doesn't
make sense to just name it for groups. And since there isn't really a
word that encapsulates both "extra" and "group," we just fall back to
the super general "conflicts."

We'll rename the variables and other things in the next commit.
2024-11-14 08:02:46 -05:00
Andrew Gallant 84d50ce81a uv-pypi-types: rename conflicting_groups module to conflicts
We'll do the rest of the renaming in the next commit.
2024-11-14 08:02:46 -05:00
Charlie Marsh 2e73f47453
Avoid duplicating first-entry comments in `uv add` (#9109)
## Summary

Closes https://github.com/astral-sh/uv/issues/9105.
2024-11-14 02:13:59 +00:00
Charlie Marsh 8c663d2a3f
Convert to `RequirementSource` rather than `Requirement` (#9107)
## Summary

This seems like a vestige left over from a refactor.
2024-11-13 20:00:13 -05:00
Charlie Marsh 9339e55a11
Add `version` to `ResolvedDist` (#9102)
## Summary

I need this for the derivation chain work
(https://github.com/astral-sh/uv/issues/8962), but it just seems
generally useful. You can't always get a version from a `Dist` (it could
be URL-based!), but when we create a `ResolvedDist`, we _do_ know the
version (and not just the URL). This PR preserves it.
2024-11-13 19:06:16 -05:00
Charlie Marsh 17181d9e59
Add missing `Download` variants to diagnostics (#9101) 2024-11-13 17:36:54 -05:00
Charlie Marsh 415e3dcd24
Remove unnecessary descriptions from test suite (#9100) 2024-11-13 21:00:14 +00:00
Charlie Marsh 35549de62d
Defer reporting of build failures in resolver (#9098)
## Summary

In https://github.com/astral-sh/uv/issues/9078, resolution fails because
we fail to build `jsmin`. However... if you look at what's actually
happening, `jsmin` fails to build during _prefetching_. And we never
actually attempt to access its metadata later on.

This PR modifies the metadata result handling such that we don't raise
these errors until the resolver actually asks for the metadata, so
https://github.com/astral-sh/uv/issues/9078 now succeeds.

I actually had to make this change anyway in pursuing
https://github.com/astral-sh/uv/issues/8962, so I've decided to carve it
out here.

Closes https://github.com/astral-sh/uv/issues/9078.
2024-11-13 15:49:08 -05:00
Charlie Marsh b0e7476008
Sort by name, then specifiers in `uv add` (#9097)
## Summary

This PR ensures that `pylint>=3.2.6` followed by
`pylint-module-boundaries>=1.3.1` is considered sorted, despite the fact
that `>` is later in the alphabetic than `-`. By purely comparing
strings, they would _not_ be sorted; but by considering the name, then
the specifiers, they are.

Closes https://github.com/astral-sh/uv/issues/9076.
2024-11-13 15:47:57 -05:00
Zanie Blue 61569d0d9d
Remove duplicate log when searching for interpreters (#9092)
e.g., as seen in https://github.com/astral-sh/uv/issues/9088
2024-11-13 11:25:42 -06:00
Charlie Marsh 709e45f34b
Split after specifiers in `--with` requirements (#9089)
## Summary

Part of me wants to revert support for `--with "flask, requests"`, but
the multiple specifiers case actually isn't ambiguous, and handling it
is better than shipping a breaking change in a patch release.

Closes https://github.com/astral-sh/uv/issues/9081.
2024-11-13 16:20:41 +00:00
Owen Brooks 2ea81b3b55
Make Python and PyPy install mirrors configurable in uv.toml (#8695)
<!--
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.)
-->

## Summary

Adds python-install-mirror and pypy-install-mirror as keys for uv.toml,
and cli args for `uv python install`.

Could leave the cli args out if we think the env vars and configs are
sufficient.

Fixes #8186 

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

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2024-11-13 16:08:55 +00:00
Zanie Blue 2966471db2
Prefer Python executable names that match the request over default names (#9066)
This restores behavior previously removed in
https://github.com/astral-sh/uv/pull/7649.

I thought it'd be clearer (and simpler) to have a consistent Python
executable name ordering. However, we've seen some cases where this can
be surprising and, in combination with #8481, can result in incorrect
behavior. For example, see https://github.com/astral-sh/uv/issues/9046
where we prefer `python3` over `python3.12` in the same directory even
though `python3.12` was requested. While `python3` and `python3.12` both
point to valid Python 3.12 environments there, the expectation is that
when `python3.12` is requested that the `python3.12` executable is
preferred. This expectation may be less obvious if the user requests
`python@3.12`, but uv does not distinguish between these request forms.
Similarly, this may be surprising as by default uv prefers `python` over
`python3` but when requesting `python3.12` the preference will be
swapped.
2024-11-13 10:00:23 -06:00
Andrew Gallant 15ef807c80
add support for specifying conflicting extras (#8976)
This PR adds support for conflicting extras. For example, consider
some optional dependencies like this:

```toml
[project.optional-dependencies]
project1 = ["numpy==1.26.3"]
project2 = ["numpy==1.26.4"]
```

These dependency specifications are not compatible with one another.
And if you ask uv to lock these, you'll get an unresolvable error.

With this PR, you can now add this to your `pyproject.toml` to get
around this:

```toml
[tool.uv]
conflicting-groups = [
    [
      { package = "project", extra = "project1" },
      { package = "project", extra = "project2" },
    ],
]
```

This will make the universal resolver create additional forks
internally that keep the dependencies from the `project1` and
`project2` extras separate. And we make all of this work by reporting
an error at **install** time if one tries to install with two or more
extras that have been declared as conflicting. (If we didn't do this,
it would be possible to try and install two different versions of the
same package into the same environment.)

This PR does *not* add support for conflicting **groups**, but it is
intended to add support in a follow-up PR.

Closes #6981

Fixes #8024

Ref #6729, Ref #6830

This should also hopefully unblock
https://github.com/dagster-io/dagster/pull/23814, but in my testing, I
did run into other problems (specifically, with `pywin`). But it does
resolve the problem with incompatible dependencies in two different
extras once you declare `test-airflow-1` and `test-airflow-2` as
conflicting for `dagster-airflow`.

NOTE: This PR doesn't make `conflicting-groups` public yet. And in a
follow-up PR, I plan to switch the name to `conflicts` instead of
`conflicting-groups`, since it will be able to accept conflicting extras
_and_ conflicting groups.
2024-11-13 09:52:28 -05:00
konsti 926660aea0
Publish: Ignore non-matching files (#8986)
Fixes #8944
2024-11-13 12:58:28 +01:00
Zanie Blue cb430b8d44
Ignore virtual environments in parent directories when choosing Python version for new projects (#9075)
`uv init` shouldn't have been using `EnvironmentPreference::Any` for
discovery of a Python interpreter, it seems like an oversight that it
was reading from virtual environments. I changed it to
`EnvironmentPreference::OnlySystem` so we'll use the first Python on the
`PATH` instead. However, I think we actually do want to respect a
virtual environment's Python version if it's in the target project
directory already, so I've implemented that as well.

Closes https://github.com/astral-sh/uv/issues/9072
Closes https://github.com/astral-sh/uv/issues/8092
2024-11-12 21:53:57 -06:00
Charlie Marsh b780155400
Make diagnostic methods dynamic on error (#9037)
## Summary

I need these to accept "any error".
2024-11-12 15:01:38 +00:00
Charlie Marsh e0f657ed37
DRY up diagnostic reporting for resolution failures (#9044)
## Summary

Not thrilled with this but helps for now. I feel like this
error-handling should happen at the top-level, rather than on all these
individual commands. But we don't have a unified result type at the
top-level of the CLI -- all these commands return `anyhow::Result`.
2024-11-12 14:46:03 +00:00
konsti 5248dff2dc
Typo fixes (#9057) 2024-11-12 13:45:22 +00:00
Charlie Marsh c5caf92edf
Use rich diagnostic formatting for install failures (#9043)
## Summary

Shows similar diagnostics for failures that happen at install time,
rather than resolve time. This will ultimately feed into
https://github.com/astral-sh/uv/issues/8962 since we'll now have
consolidated handling for these kinds of failures.
2024-11-11 22:54:30 -05:00
Charlie Marsh 00bf69be28
Revert `uv.lock` changes when `uv add` fails (#9030)
## Summary

If a `uv add` fails at the sync stage, we need to clean up the changes
to the `uv.lock`, since it might've been edited during in the lock stage
(which, by necessity, succeeded). As-is, we revert the `pyproject.toml`
but not the `uv.lock`, so the two are out-of-sync.

Closes https://github.com/astral-sh/uv/issues/9028.
Closes https://github.com/astral-sh/uv/issues/7992.
2024-11-12 03:38:05 +00:00
Charlie Marsh de9dc398a8
Rename `fetch_and_build` to `download_and_build` (#9042) 2024-11-12 03:23:29 +00:00
Charlie Marsh a147ed0b55
Use rich diagnostic formatting for early build failures (#9041)
## Summary

This addresses cases like URL distributions, which are built before we
get to the resolver.
2024-11-12 03:12:38 +00:00
Shane Kennedy 052b4e77a6
Handle sigterm calls, fixes #6724 (#8933)
<!--
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

This PR builds off of https://github.com/astral-sh/uv/pull/6738 to fix
#6724 (sorry for the new PR @charliermarsh I didn't want to push to your
branch, not even sure if I could). The reason the original PR doesn't
fix the issue described in #6724 is because the fastapi is ran in the
project context (as I assume a lot of use cases are). This PR adds an
extra commit to handle the signals in the project/run.rs file

~It also addresses the comment
[here](https://github.com/astral-sh/uv/pull/6738/files#r1734757548) to
not use the tokio ctrl-c method since we are now handling SIGINT
ourselves~ update, tokio handles SIGINT in a platform agnostic way,
intercepting this ouselves makes the logic more complicated with
windows, decided to leave the tokio ctrl-c handler

~[This
comment](https://github.com/astral-sh/uv/pull/6738/files#r1743510140)
remains unaddressed, however, the Child process does not have any other
methods besides kill() so I don't see how we can "preserve" the
interrupt call :/ I tried looking around but no luck.~ updated, this PR
is reduced to only handling SIGTERM propagation on unix machines, and
the sigterm call to the child is preserved by making use of the nix
package, instead of relying on tokio which only allowed for `kill()` on
a child process

## Test Plan

I tested this by building the docker container locally with these
changes and tagging it "myuv", and then using that as the base image in
uv-docker-example, (and ofc following the rest of the repro issues in
#6724. In my tests I see that ctrl-c in the docker-compose up command
exits the process almost immediately 👍

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2024-11-11 20:48:21 -06:00
Charlie Marsh 5187f330c1
Hide `--no-system` from `uv pip tree` CLI (#9040)
## Summary

This is hidden from all other commands, so it looks like an oversight.

Closes #9035.
2024-11-12 02:32:31 +00:00
Charlie Marsh b3c660c58a
Rename `Fetch` to `Download` in build errors (#9039)
## Summary

We're inconsistent with these -- sometimes it's `Error::Fetch` and
sometimes it's `Error::Download`. The message says download, so let's
just use that?
2024-11-12 02:30:20 +00:00
Charlie Marsh e059c25bd6
Consistently box distributions in fetch and build errors (#9038)
## Summary

This is useful for pattern-matching.
2024-11-12 02:19:38 +00:00
Charlie Marsh 59f3ec2b6c
Remove duplicate `Lock::to_resolution` (#9029)
## Summary

This got moved to `InstallTarget`! Must've been an oversight not to
delete. I verified that no code was changed here since the date that we
moved it to `InstallTarget`.
2024-11-11 20:30:00 +00:00
Charlie Marsh dd4b27bfbd
Allow `--no-build` to validate lock (#9024)
## Summary

Just as we don't enforce tag compliance, we shouldn't enforce
`--no-build` when validating the lockfile. If we end up building from
source, the distribution database will correctly error.

Closes https://github.com/astral-sh/uv/issues/9016.
2024-11-11 14:02:37 -05:00
Charlie Marsh a3c2a36422
Add an error case for `--no-binary` sync failures (#9025) 2024-11-11 18:52:22 +00:00
Zanie Blue 58bc604b6e
Update format of environment variable reference (#9018)
- Sorts the variables
- Separates `UV_` variables from others
- Uses headings so the toc is available
2024-11-11 12:41:33 -06:00
Charlie Marsh 769afa96a4
Avoid retraversing filesystem when testing exact glob matches (#9022)
## Summary

When testing for exact inclusion, we can just test the glob directly.
There's no need to re-traverse the filesystem to find it.
2024-11-11 12:54:35 -05:00
konsti 760cf82ee3
Use Python syntax for `value_type` consistently (#9017)
Spotted that when looking though `value_type =` declarations.
2024-11-11 17:38:47 +00:00
renovate[bot] 9368268e49
Update Rust crate url to v2.5.3 (#9002) 2024-11-11 14:49:31 +00:00
renovate[bot] ce14207e2e
Update Rust crate anyhow to v1.0.93 (#8996) 2024-11-11 02:13:34 +00:00
Charlie Marsh f52bb1b25d
Consistent colon usage in build failure errors (#8994) 2024-11-11 02:00:03 +00:00
Charlie Marsh ac9ce853cf
Remove some unused public methods (#8993)
## Summary

Notice these in an unrelated refactor.
2024-11-10 22:55:22 +00:00
Charlie Marsh 744a9091a2
Allow default indexes to be marked as explicit (#8990)
## Summary

Closes https://github.com/astral-sh/uv/issues/8985.
2024-11-10 18:05:39 +00:00