Document why we do lower bounds (#6516)

Document in the resolution concept documentation why we add lower bounds

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
This commit is contained in:
konsti 2024-08-23 22:28:39 +02:00 committed by GitHub
parent be1599ebf6
commit 4e82db093a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 23 additions and 2 deletions

View File

@ -144,8 +144,8 @@ is requested or an upgrade is explicitly requested with `--upgrade`.
By default, uv tries to use the latest version of each package. For example,
`uv pip install flask>=2.0.0` will install the latest version of Flask, e.g., 3.0.0. If
`flask>=2.0.0` is a dependency of the project, only `flask` 3.0.0 will be used. This is important,
for example, because running tests will not check that the the project is actually compatible with
its stated lower bound of `flask` 2.0.0.
for example, because running tests will not check that the project is actually compatible with its
stated lower bound of `flask` 2.0.0.
With `--resolution lowest`, uv will install the lowest possible version for all dependencies, both
direct and indirect (transitive). Alternatively, `--resolution lowest-direct` will use the lowest
@ -258,6 +258,27 @@ If multiple overrides are provided for the same package, they must be differenti
[markers](#platform-markers). If a package has a dependency with a marker, it is replaced
unconditionally when using overrides — it does not matter if the marker evaluates to true or false.
## Lower bounds
By default, `uv add` adds lower bounds to dependencies and, when using uv to manage projects, uv
will warn if direct dependencies don't have lower bound.
Lower bounds are not critical in the "happy path", but they are important for cases where there are
dependency conflicts. For example, consider a project that requires two packages and those packages
have conflicting dependencies. The resolver needs to check all combinations of all versions within
the constraints for the two packages — if all of them conflict, an error is reported because the
dependencies are not satisfiable. If there are no lower bounds, the resolver can (and often will)
backtrack down to the oldest version of a package. This isn't only problematic because it's slow,
the old version of the package often fails to build, or the resolver can end up picking a version
that's old enough that it doesn't depend on the conflicting package, but also doesn't work with your
code.
Lower bounds are particularly critical when writing a library. It's important to declare the lowest
version for each dependency that your library works with, and to validate that the bounds are
correct — testing with [`--resolution lowest` or `resolution lowest-direct`](#resolution-strategy).
Otherwise, a user may receive an old, incompatible version of one of your library's dependencies and
the library will fail with an unexpected error.
## Reproducible resolutions
uv supports an `--exclude-newer` option to limit resolution to distributions published before a