mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 19:08:04 +00:00
Clarify requires-python
requirement for dependencies (#8619)
## Summary Closes https://github.com/astral-sh/uv/issues/8597.
This commit is contained in:
parent
001d00ba26
commit
988ac749f4
1 changed files with 29 additions and 25 deletions
|
@ -7,10 +7,10 @@ requirements of the requested packages are compatible.
|
|||
|
||||
## Dependencies
|
||||
|
||||
Most projects and packages have dependencies. Dependencies are other packages that are needed in
|
||||
Most projects and packages have dependencies. Dependencies are other packages that are necessary in
|
||||
order for the current package to work. A package defines its dependencies as _requirements_, roughly
|
||||
a combination of a package name and acceptable versions. The dependencies defined by the current
|
||||
project are called _direct dependencies_. The requirements added by each dependency of the current
|
||||
project are called _direct dependencies_. The dependencies added by each dependency of the current
|
||||
project are called _indirect_ or _transitive dependencies_.
|
||||
|
||||
!!! note
|
||||
|
@ -34,10 +34,10 @@ To help demonstrate the resolution process, consider the following dependencies:
|
|||
In this example, the resolver must find a set of package versions which satisfies the project
|
||||
requirements. Since there is only one version of both `foo` and `bar`, those will be used. The
|
||||
resolution must also include the transitive dependencies, so a version of `lib` must be chosen.
|
||||
`foo 1.0.0` allows all of the available versions of `lib`, but `bar 1.0.0` requires `lib>=2.0.0` so
|
||||
`foo 1.0.0` allows all available versions of `lib`, but `bar 1.0.0` requires `lib>=2.0.0` so
|
||||
`lib 2.0.0` must be used.
|
||||
|
||||
In some resolutions, there is more than one solution. Consider the following dependencies:
|
||||
In some resolutions, there may be more than one valid solution. Consider the following dependencies:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
- The project depends on `foo` and `bar`.
|
||||
|
@ -49,21 +49,21 @@ In some resolutions, there is more than one solution. Consider the following dep
|
|||
- `bar 2.0.0` depends on `lib==1.0.0`
|
||||
- `lib` has two versions, 1.0.0 and 2.0.0. Both versions have no dependencies.
|
||||
|
||||
In this example, some version of both `foo` and `bar` must be picked, however, determining which
|
||||
In this example, some version of both `foo` and `bar` must be selected; however, determining which
|
||||
version requires considering the dependencies of each version of `foo` and `bar`. `foo 2.0.0` and
|
||||
`bar 2.0.0` cannot be installed together because they conflict on their required version of `lib`,
|
||||
so the resolver must select either `foo 1.0.0` or `bar 1.0.0`. Both are valid solutions, and
|
||||
different resolution algorithms may give either result.
|
||||
`bar 2.0.0` cannot be installed together as they conflict on their required version of `lib`, so the
|
||||
resolver must select either `foo 1.0.0` (along with `bar 2.0.0`) or `bar 1.0.0` (along with
|
||||
`foo 1.0.0`). Both are valid solutions, and different resolution algorithms may yield either result.
|
||||
|
||||
## Platform markers
|
||||
|
||||
Markers allow attaching an expression to requirements that indicate when the dependency should be
|
||||
used. For example `bar; python_version<"3.9"` can be used to only require `bar` on Python 3.8 and
|
||||
older.
|
||||
used. For example `bar ; python_version < "3.9"` indicates that `bar` should only be installed on
|
||||
Python 3.8 and earlier.
|
||||
|
||||
Markers are used to adjust a package's dependencies depending on the current environment or
|
||||
platform. For example, markers can be used to change dependencies based on the operating system, the
|
||||
CPU architecture, the Python version, the Python implementation, and more.
|
||||
Markers are used to adjust a package's dependencies based on the current environment or platform.
|
||||
For example, markers can be used to modify dependencies by operating system, CPU architecture,
|
||||
Python version, Python implementation, and more.
|
||||
|
||||
!!! note
|
||||
|
||||
|
@ -98,16 +98,20 @@ be used. A universal resolution is often more constrained than a platform-specif
|
|||
we need to take the requirements for all markers into account.
|
||||
|
||||
During universal resolution, a minimum Python version must be specified. Project commands read the
|
||||
minimum required version from `project.requires-python` in the `pyproject.toml`. When using the pip
|
||||
interface, provide a value with the `--python-version` option, otherwise the current Python version
|
||||
will be treated as a lower bound. For example, `--universal --python-version 3.9` writes a universal
|
||||
resolution for Python 3.9 and later.
|
||||
minimum required version from `project.requires-python` in the `pyproject.toml`. When using uv's pip
|
||||
interface, provide a value with the `--python-version` option; otherwise, the current Python version
|
||||
will be treated as a lower bound. For example, `--universal --python-version 3.9` performs a
|
||||
universal resolution for Python 3.9 and later.
|
||||
|
||||
Setting the minimum Python version is important because all package versions we select have to be
|
||||
compatible with the Python version range. For example, a universal resolution of `numpy<2` with
|
||||
`--python-version 3.8` resolves to `numpy==1.24.4`, while `--python-version 3.9` resolves to
|
||||
`numpy==1.26.4`, as `numpy` releases after 1.26.4 require at Python 3.9+. Note that we only consider
|
||||
the lower bound of any Python requirement, upper bounds are always ignored.
|
||||
During universal resolution, all selected dependency versions must be compatible with the _entire_
|
||||
`requires-python` range declared in the `pyproject.toml`. For example, if a project's
|
||||
`requires-python` is `>=3.8`, then uv will not allow _any_ dependency versions that are limited to,
|
||||
e.g., Python 3.9 and later, as they are not compatible with Python 3.8, the lower bound of the
|
||||
project's supported range. In other words, the project's `requires-python` must be a subset of the
|
||||
`requires-python` of all its dependencies.
|
||||
|
||||
When evaluating `requires-python` ranges for dependencies, uv only considers lower bounds and
|
||||
ignores upper bounds entirely. For example, `>=3.8, <4` is treated as `>=3.8`.
|
||||
|
||||
## Platform-specific resolution
|
||||
|
||||
|
@ -237,9 +241,9 @@ resolved versions, regardless of which packages are overlapping between the two.
|
|||
|
||||
## Dependency overrides
|
||||
|
||||
Dependency overrides allow bypassing failing or undesirable resolutions by overriding a package's
|
||||
declared dependencies. Overrides are a useful last resort for cases in which you _know_ that a
|
||||
dependency is compatible with a certain version of a package, despite the metadata indicating
|
||||
Dependency overrides allow bypassing unsuccessful or undesirable resolutions by overriding a
|
||||
package's declared dependencies. Overrides are a useful last resort for cases in which you _know_
|
||||
that a dependency is compatible with a certain version of a package, despite the metadata indicating
|
||||
otherwise.
|
||||
|
||||
For example, if a transitive dependency declares the requirement `pydantic>=1.0,<2.0`, but _does_
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue