Commit graph

923 commits

Author SHA1 Message Date
Charlie Marsh
6a8da7dff8
Compare virtual members when invalidating lockfile (#6754)
## Summary

Whether a package is itself virtual isn't captured in the package
metadata, so we have to compare the sources.

Closes https://github.com/astral-sh/uv/issues/6749.
2024-08-28 15:11:16 +00:00
Charlie Marsh
53ef633c6d
Do not require workspace members to sync with --frozen (#6737)
## Summary

Closes https://github.com/astral-sh/uv/issues/6685.
2024-08-28 07:58:50 -04:00
Charlie Marsh
56cc0c9b3c
Avoid using editable tag in lockfile for non-package dependencies (#6728)
## Summary

Use a dedicated source type for non-package requirements. Also enables
us to support non-package `path` dependencies _and_ removes the need to
have the member `pyproject.toml` files available when we sync _and_
makes it explicit which dependencies are virtual vs. not (as evidenced
by the snapshot changes). All good things!
2024-08-28 01:19:05 +00:00
Charlie Marsh
3ee6ca31f4
Rename virtual workspace roots to non-project workspace roots (#6717)
## Summary

Closes https://github.com/astral-sh/uv/issues/6709.
2024-08-27 21:36:40 +00:00
Charlie Marsh
a7850d2a1c
Use separate types to represent raw vs. resolver markers (#6646)
## Summary

This is similar to https://github.com/astral-sh/uv/pull/6171 but more
expansive... _Anywhere_ that we test requirements for platform
compatibility, we _need_ to respect the resolver-friendly markers. In
fixing the motivating issue (#6621), I also realized that we had a bunch
of bugs here around `pip install` with `--python-platform` and
`--python-version`, because we always performed our `satisfy` and `Plan`
operations on the interpreter's markers, not the adjusted markers!

Closes https://github.com/astral-sh/uv/issues/6621.
2024-08-26 18:00:21 +00:00
Charlie Marsh
2ec7c69861
Respect extras and markers on virtual dev dependencies (#6620)
## Summary

Closes https://github.com/astral-sh/uv/issues/6617.
2024-08-26 00:31:42 +00:00
Charlie Marsh
7fa265a11b
Use relative paths for --find-links and local registries (#6566)
## Summary

See: https://github.com/astral-sh/uv/issues/6458
2024-08-25 02:41:47 +00:00
Charlie Marsh
1eb97c91fd
Remove FileLocation::Path variant (#6577)
## Summary

This is redundant now that we support `file://` URLs.
2024-08-24 07:52:43 -04:00
Charlie Marsh
f7835243c5
Only use relative paths in lockfile (#6490)
For users who were using absolute paths in the `pyproject.toml`
previously, this is a behavior change: We now convert all absolute paths
in `path` entries to relative paths. Since i assume that no-one relies
on absolute path in their lockfiles - they are intended to be portable -
I'm tagging this as a bugfix.

Closes https://github.com/astral-sh/uv/pull/6438
Fixes https://github.com/astral-sh/uv/issues/6371
2024-08-23 22:19:10 -04:00
Charlie Marsh
19a7f3ec07
Collapse extras on dev dependencies (#6383)
## Summary

It turns out we weren't applying the collapse logic here, so dev deps
with extras were repeated. This was generally ok... unless we ended up
_dropping_ an extra, in which case, you now have a duplicate.

Closes https://github.com/astral-sh/uv/issues/6380.
2024-08-21 22:36:51 +00:00
Charlie Marsh
c485727e00
Remove duplicated lockfile invalidation logs (#6340)
## Summary

These got moved to the caller, so they're all duplicated right now.
2024-08-21 15:29:33 +00:00
Charlie Marsh
d627dea51e
Preserve Git username for SSH dependencies (#6335)
## Summary

We're gonna work on a more comprehensive review of whether we should
preserve the username here, but for now, `git@` is effectively a
convention for GitHub and GitLab etc.

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

## Test Plan

I guess we don't have infrastructure for testing SSH private keys right
now, but...

```
❯ cargo run init foo
❯ cd foo
❯ cargo run add git+ssh://git@github.com/astral-sh/mkdocs-material-insiders.git
```
2024-08-21 11:22:45 -04:00
Charlie Marsh
2e02d579a0
Invalidate uv.lock when virtual dev-dependencies change (#6291)
## Summary

For non-virtual workspaces, these are covered by the _members_. But for
virtual workspaces, they aren't captured anywhere else in the lock. So,
we weren't invalidating `uv.lock` when the dev dependencies changed,
which led to a panic.

Closes https://github.com/astral-sh/uv/issues/6288
2024-08-21 01:25:38 +00:00
Andrew Gallant
33480d61eb switch to jiff from chrono (#6205)
This PR migrates uv's use of `chrono` to `jiff`.

I did most of this work a while back as one of my tests to ensure Jiff
could actually be used in a real world project. I decided to revive
this because I noticed that `reqwest-retry` dropped its Chrono
dependency,
which is I believe the only other thing requiring Chrono in uv.
(Although, we use a fork of `reqwest-middleware` at present, and that
hasn't been updated to latest upstream yet. I wasn't quite sure of the
process we have for that.)

In course of doing this, I actually made two changes to uv:

First is that the lock file now writes an RFC 3339 timestamp for
`exclude-newer`. Previously, we were using Chrono's `Display`
implementation for this which is a non-standard but "human readable"
format. I think the right thing to do here is an RFC 3339 timestamp.

Second is that, in addition to an RFC 3339 timestamp, `--exclude-newer`
used to accept a "UTC date." But this PR changes it to a "local date."
That is, a date in the user's system configured time zone. I think
this makes more sense than a UTC date, but one alternative is to drop
support for a date and just rely on an RFC 3339 timestamp. The main
motivation here is that automatically assuming UTC is often somewhat
confusing, since just writing an unqualified date like `2024-08-19` is
often assumed to be interpreted relative to the writer's "local" time.
2024-08-20 11:31:46 -05:00
Charlie Marsh
3395d24959
Allow user to constrain supported lock environments (#6210)
## Summary

The strategy here is: if the user provides supported environments, we
use those as the initial forks when resolving. As a result, we never add
or explore branches that are disjoint with the supported environments.
(If the supported environments change, we ignore the lockfile entirely,
so we don't have to worry about any interactions between supported
environments and the preference forks.)

Closes https://github.com/astral-sh/uv/issues/6184.
2024-08-20 13:28:04 +00:00
Charlie Marsh
d02c202eb2
Rename environment-markers to resolution-markers (#6240)
## Summary

I probably won't land https://github.com/astral-sh/uv/pull/6210 for the
release, but I do want to make one breaking change to prep for it:
renaming `environment-markers` to `resolution-markers` (or
`solution-markers`?) so that it's delineated from the user-defined
markers in that PR.
2024-08-20 09:14:55 -04:00
Andrew Gallant
c14e30ad09 pep508: fix doc test
Indented blocks in Markdown are treated as code blocks, and rustdoc
treats all unadorned code blocks as Rust doctests. Since this wasn't
intended as a doctest and isn't valid Rust, it makes `cargo test --doc`
fail. We fix this by using an explicit code block labeled as `text`.
2024-08-19 16:29:20 -07:00
Zanie Blue
5c2781c42a
Fix messages for unavailable packages when range is plural (#6221)
Not in love with the implementation, but it seems like the easiest path
forward for now.
2024-08-19 19:07:07 +00:00
Zanie Blue
6500f7110a
Change "any of" to "all of" in error messages (#6222) 2024-08-19 18:43:07 +00:00
Zanie Blue
f6f2c5b79e
Collapse redundant dependency clauses enumerating available versions (#6160)
In https://github.com/astral-sh/uv/issues/5046, we show the tautological
proof:

```
  ╰─▶ Because colabfold[alphafold]==1.5.5 depends on jax>=0.4.20 and only the following versions of jax are available:
          jax<=0.4.20
          jax==0.4.21
          jax==0.4.22
          jax==0.4.23
          jax==0.4.24
          jax==0.4.25
          jax==0.4.26
          jax==0.4.27
          jax==0.4.28
          jax==0.4.29
          jax==0.4.30
          jax==0.4.31
      we can conclude that colabfold[alphafold]==1.5.5 depends on jax>=0.4.20.
      And because jax>=0.4.20 depends on numpy>=1.26.0, we can conclude that colabfold[alphafold]==1.5.5 depends on numpy>=1.26.0.
      (1)
```

This is a part of the error tree because the statement
`colabfold[alphafold]==1.5.5 depends on jax>=0.4.20` is actually a
simplification of `colabfold[alphafold]==1.5.5 depends on
jax>=0.4.20,<0.5.0` and the no versions clause is a proof of that
simplification.

Without simplification, the clause looks like:

```
  ╰─▶ Because colabfold[alphafold]==1.5.5 depends on jax>=0.4.20,<0.5.0 and only the following versions of jax are available:
          jax<=0.4.20
          jax==0.4.21
          jax==0.4.22
          jax==0.4.23
          jax==0.4.24
          jax==0.4.25
          jax==0.4.26
          jax==0.4.27
          jax==0.4.28
          jax==0.4.29
          jax==0.4.30
          jax==0.4.31
      we can conclude that colabfold[alphafold]==1.5.5 depends on one of:
          jax==0.4.20
          jax==0.4.21
          jax==0.4.22
          jax==0.4.23
          jax==0.4.24
          jax==0.4.25
          jax==0.4.26
          jax==0.4.27
          jax==0.4.28
          jax==0.4.29
          jax==0.4.30
          jax==0.4.31
      And because jax>=0.4.20 depends on numpy>=1.26.0, we can conclude that colabfold[alphafold]==1.5.5 depends on numpy>=1.26.0.
```

I don't think we have a great way to avoid performing the simplification
of the range conditionally and it makes the error simpler to just jump
straight to `colabfold[alphafold]==1.5.5 depends on jax>=0.4.20`.

The derivation for this clause looks like:

```
          jax==0.4.20 | ==0.4.21 | ==0.4.22 | ==0.4.23 | ==0.4.24 | ==0.4.25 | ==0.4.26 | ==0.4.27 | ==0.4.28 | ==0.4.29 | ==0.4.30 | ==0.4.31 depends on numpy>=1.26.0
            no versions of jax>0.4.20, <0.4.21 | >0.4.21, <0.4.22 | >0.4.22, <0.4.23 | >0.4.23, <0.4.24 | >0.4.24, <0.4.25 | >0.4.25, <0.4.26 | >0.4.26, <0.4.27 | >0.4.27, <0.4.28 | >0.4.28, <0.4.29 | >0.4.29, <0.4.30 | >0.4.30, <0.4.31 | >0.4.31, <0.5.0
            colabfold[alphafold]==1.5.5 depends on jax>=0.4.20, <0.5.0
```

So it looks like we can take trees of this form and drop the "no
versions" clause _if_ the ranges are compatible[*]. See [this
comment](https://github.com/astral-sh/uv/pull/6160#discussion_r1720280922)
for a simpler explanation.

With this pull request, the clause simplifies to

```
╰─▶ Because colabfold[alphafold]==1.5.5 depends on jax>=0.4.20 and jax>=0.4.20 depends on numpy>=1.26.0,
     we can conclude that colabfold[alphafold]==1.5.5 depends on numpy>=1.26.0. (1)
```

Unfortunately, this doesn't change any snapshots in our test suite so
I'm uncertain if the strategy generalizes. In some incorrect iterations
of this logic, the snapshots did reveal my mistakes.

[*] "if the ranges are compatible" includes a bit of hand-waving. I'm
not 100% sure if I've chosen the correct range heuristic here.
2024-08-19 18:02:02 +00:00
Zanie Blue
baf17bee86
Avoid panicking when the resolver thread encounters a closed channel (#6182)
Closes https://github.com/astral-sh/uv/issues/6167

We've been seeing intermittent failures in CI, which we thought were
unexpected HTTP 401s but it actually looks like a panic when handling an
expected HTTP error. I believe the problem is that an early client error
can cause the channel to close and we crash when we unwrap the `send`.
2024-08-18 21:04:05 +00:00
Charlie Marsh
5ac0b98e00
Respect release-only semantics of python_full_version when constructing markers (#6171)
## Summary

In the resolver, we use release-only semantics to normalize
`python_full_version`. So, if we see `python_full_version < '3.13'`, we
treat that as `(Unbounded, Exclude(3.13))`. `3.13b0` evaluates as `true`
to that range, so we were accepting pre-releases for these markers.

Instead, we need to exclude pre-release segments when performing these
evaluations.

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

## Test Plan

Hard to write a test for this because you need a pre-release Python
locally... so:

`echo "sqlalchemy==2.0.32" | cargo run pip compile - --python 3.13 -n`
2024-08-17 19:29:57 +00:00
Zanie Blue
e1a8beb64b
Simplify version ranges reported for unavailable packages (#6155)
Now that these incompatibilities are collected into a single range
(https://github.com/astral-sh/uv/pull/6154), we can simplify the range
using the known available versions to reduce verbosity.
2024-08-16 20:56:45 +00:00
Zanie Blue
92ff120983
Improve resolver error messages when --offline is used (#6156) 2024-08-16 20:28:35 +00:00
Zanie Blue
ea636bbe61
Simplify available package version ranges when the name includes markers or extras (#6162)
There were different `PubGrubPackage` types so they never matched the
available versions set! Luckily, the available versions are agnostic to
the markers and optional dependencies so we can just broaden to using
`PackageName` as a lookup key.

Addresses yet another complaint in
https://github.com/astral-sh/uv/issues/5046
2024-08-16 15:21:49 -05:00
Zanie Blue
05cceee523
Collapse unavailable packages in resolver errors (#6154)
Uses my expanding tree reduction knowledge from #6092 to improve the
long-standing issue of verbose messages for unavailable packages.

Implements https://github.com/pubgrub-rs/pubgrub/issues/232, but
post-resolution instead of during resolution.

Partially addresses https://github.com/astral-sh/uv/issues/5046
Closes https://github.com/astral-sh/uv/issues/2519
2024-08-16 15:19:59 -05:00
Charlie Marsh
d643e92d66
Avoid using workspace lock_path as relative root (#6157)
## Summary

I've also made it such that these won't panic, and we gracefully
continue if we fail to validate a lockfile.

Closes https://github.com/astral-sh/uv/issues/6142.
2024-08-16 17:24:27 +00:00
Charlie Marsh
91fba4e1e6
Use FxHash in uv-auth (#6149) 2024-08-16 13:14:51 -04:00
Zanie Blue
d7abe827d6
Allow displaying the derivation tree (#6124)
I need this for debugging error messages.

I used an environment variable instead of a trace log so you can do
`UV_INTERNAL__SHOW_DERIVATION_TREE=1` and run a test to see the tree in
the test snapshot without further changes.

e.g.

```rust
    // Resolving should fail.
    uv_snapshot!(context.filters(), context.lock().arg("--preview").current_dir(&workspace), @r###"
    success: false
    exit_code: 1
    ----- stdout -----
    UV_INTERNAL__SHOW_DERIVATION_TREE
      root==0a0.dev0 depends on foo*
        root==0a0.dev0 depends on bar[some-extra]*
          foo==0.1.0 depends on anyio==4.1.0
            bar[some-extra]==0.1.0 depends on anyio==4.2.0
            no versions of bar[some-extra]<0.1.0 | >0.1.0

    ----- stderr -----
    Using Python 3.12.[X] interpreter at: [PYTHON-3.12]
      × No solution found when resolving dependencies:
      ╰─▶ Because only bar[some-extra]==0.1.0 is available and bar[some-extra] depends on anyio==4.2.0, we can conclude that all versions of bar[some-extra] depend on anyio==4.2.0.
          And because foo depends on anyio==4.1.0, we can conclude that foo and all versions of bar[some-extra] are incompatible.
          And because your workspace requires bar[some-extra] and foo, we can conclude that your workspace's requirements are unsatisfiable.
    "###
    );
```
2024-08-16 14:25:26 +00:00
Zanie Blue
89efe2491b
Improve display of resolution errors for workspace member conflicts with optional dependencies (#6123)
We have bad error messages for optional (extra) dependencies and
development dependencies in workspaces:

1. We weren't showing the full package, so we'd drop `:dev` and
`[extra]` by accident
2. We didn't include derived packages, e.g., `member[extra]` in tree
processing collapse operation, so we'd include extra clauses like the
ones we removed in #6092

Also

- Reverts
f0de4f71f2
— it turns out it wasn't quite correct and it didn't seem worth using
the custom incompatibility anymore.
- Fixes a bug in the display of `package:dev` which was not showing
`:dev` for some variants (see 94d8020b58)
2024-08-15 20:50:43 -05:00
Ibraheem Ahmed
e6ddce0246
Normalize python_version markers to python_full_version (#6126)
## Summary

Normalize all `python_version` markers to their equivalent
`python_full_version` form. This avoids false positives in forking
because we currently cannot detect any relationships between the two
forms. It also avoids subtle bugs due to the truncating semantics of
`python_version`. For example, given `requires-python = ">3.12"`, we
currently simplify the marker `python_version <= 3.12` to `false`.
However, the version `3.12.1` will be truncated to `3.12` for
`python_version` comparisons, and thus it satisfies the python
requirement and evaluates to `true`.

It is possible to simplify back to `python_version` when writing markers
to the lockfile. However, the equivalent `python_full_version` markers
are often clearer and easier to simplify, so I lean towards leaving them
as `python_full_version`.

There are *a lot* of snapshot updates from this change. I'd like more
eyes on the transformation logic in `python_version_to_full_version` to
ensure that they are all correct.

Resolves https://github.com/astral-sh/uv/issues/6125.
2024-08-15 21:42:15 -04:00
Zanie Blue
fb6b3ff410
Use the proper singular form for workspace member dependencies in resolver errors (#6128) 2024-08-15 21:08:41 +00:00
Zanie Blue
0efdbcc95b
Improve display of available package ranges (#6118)
Includes the changes from https://github.com/astral-sh/uv/pull/6071 but
takes them way further.

When we have the set of available versions for a package, we can do a
much better job displaying an error.

For example:

```
❯ uv add 'httpx>999,<9999'
  × No solution found when resolving dependencies:
  ╰─▶ Because only the following versions of httpx are available:
          httpx<=999
          httpx>=9999
      and example==0.1.0 depends on httpx>999,<9999, we can conclude that example==0.1.0 cannot be used.
      And because only example==0.1.0 is available and you require example, we can conclude that the requirements are unsatisfiable.
```

The resolver has demonstrated that the requested range cannot be used
because there are only versions in ranges _outside_ the requested range.
However, the display of the range of available versions is pretty bad!
We say there are versions of httpx available in ranges that definitely
have no versions available.

With this pull request, the error becomes:

```
❯ uv add 'httpx>999,<9999'
  × No solution found when resolving dependencies:
  ╰─▶ Because only httpx<=1.0.0b0 is available and example depends on httpx>999,<9999, we can conclude that example's
      requirements are unsatisfiable.
      And because your workspace requires example, we can conclude that your workspace's requirements are unsatisfiable.
```

We achieve this by:

1. Dropping ranges disjoint with the range of available versions, e.g.,
this removes `httpx>=9999`
2. Replacing ranges that capture the _entire_ range of available
versions with the smaller range, e.g., this replaces `httpx<=999` with
`<=1.0.0b0`.

~Note that when we perform (2), we may include an additional bound that
is not relevant, e.g., we include the lower bound of `>=0.6.7`. This is
a bit extraneous, but I don't think it's confusing. We can consider some
advanced logic to avoid that later.~ (edit: I did this, it wasn't hard)

We also improve error messages when there is _only_ one version
available by showing that version instead of a range.
2024-08-15 17:28:45 +00:00
Charlie Marsh
9d514cbbe0
Return a structured result from Lock::satisfies (#6119)
## Summary

Gives the caller control over how messages are reported back to the
user. Also merges the index-location validation into the lock, since
we're already iterating over the packages.
2024-08-15 13:19:40 -04:00
Charlie Marsh
592af438b8
Remove requires-python application in lock deserialization (#6115)
## Summary

This is no longer required since we no longer implement `Eq` on `Lock`.
It will also sometimes be "wrong" as of #6076, since we now apply
different `requires-python` filtering to different parts of the tree
during resolution.
2024-08-15 12:54:06 -04:00
Charlie Marsh
3ee865831f
Change debug! back to trace! in filtering (#6117)
## Summary

I changed this for debugging and forgot to revert. Not awful but
probably a little much for `debug!`.
2024-08-15 16:07:02 +00:00
Charlie Marsh
4d13b525ef
Avoid cloning requirement for unchanged markers (#6116)
## Summary

Small optimization.
2024-08-15 15:58:20 +00:00
Charlie Marsh
fe0b873352
Always narrow markers by Python version (#6076)
## Summary

Using https://github.com/astral-sh/uv/issues/6064 as a motivating
example: at present, on main, we're not properly propagating the
`Requires-Python` simplifications. In that case, for example, we end up
solving for a branch with `python_version < 3.11`, and a branch `>=
3.11`, even though `Requires-Python` is `>=3.11`. Later, when we get to
the graph, we apply version simplification based on `Requires-Python`,
which causes us to _remove_ the `python_version < 3.11` markers
entirely, leaving us with duplicate dependencies for `pylint`.

This PR instead tries to ensure that we always apply this narrowing to
requirements and forks, so that we don't need to apply the same
simplification when constructing the graph at all.

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

Closes #6059.
2024-08-15 11:50:00 -04:00
Zanie Blue
f988e43ebd
Use "your requirements" consistently in resolver error messages (#6113)
Follow-up to
https://github.com/astral-sh/uv/pull/6092#discussion_r1717648821
2024-08-15 10:26:30 -05:00
Charlie Marsh
7dbed4bb2d
Treat Git sources as immutable in lockfile (#6109)
## Summary

We don't need to write metadata for Git sources, since we lock a
specific SHA (and so the metadata is immutable).
2024-08-15 09:26:47 -04:00
Charlie Marsh
29179570a1
Use sets rather than vectors for lockfile requirements (#6107)
## Summary

Ensures that `--locked` is robust to reordering and duplicates.
2024-08-15 13:00:35 +00:00
Charlie Marsh
fd0daae969
Add immutable definition to Source struct (#6108)
## Summary

Centralizes the definition of an "immutable" source.
2024-08-15 12:51:41 +00:00
Andrew Gallant
3187dc1a2f uv-resolver: remove code that was intended to be removed
In particular, I added this as a hack to avoid a kinda of
instability that was caused by our marker code not correctly
detecting markers that were always false. But that has since
been fixed.

Removing this code doesn't change any tests. Arguably it
should be possible to come up with a test that failed with
this hack inserted but succeeded without it. In particular,
with this hack, new forks were being prevented from being
added even when they ought to be added, e.g., when preferences
get updated.
2024-08-15 05:25:55 -07:00
Charlie Marsh
6333823236
Change the definition of --locked to require satisfaction check (#6102)
## Summary

This PR changes the definition of `--locked` from:

> Produces the same `Lock`

To:

> Passes `Lock::satisfies`

This is a subtle but important difference. Previous, if
`Lock::satisfies` failed, we would run a resolution, then do
`existing_lock == lock`. If the two weren't equal, and `--locked` was
specified, we'd throw an error.

The equality check is hard to get right. For example, it means that we
can't ship #6076 without changing our marker representation, since the
deserialized lockfile "loses" some of the internal marker state that
gets accumulated during resolution.

The downside of this change is that there could be scenarios in which
`uv lock --locked` fails even though the lockfile would actually work
and the exact TOML would be unchanged. But... I think it's ok if
`--locked` fails after the user modifies something?
2024-08-15 08:17:28 -04: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
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
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