diff --git a/crates/uv-cli/src/lib.rs b/crates/uv-cli/src/lib.rs index 9f7309bbd..d9006956e 100644 --- a/crates/uv-cli/src/lib.rs +++ b/crates/uv-cli/src/lib.rs @@ -4052,9 +4052,9 @@ pub struct ToolUpgradeArgs { /// supported Python version (`requires-python`), while minimizing the number of selected /// versions across platforms. /// - /// Under `fewest`, uv will minimize the number of - /// selected versions for each package, preferring older versions that are compatible with a - /// wider range of supported Python versions or platforms. + /// Under `fewest`, uv will minimize the number of selected versions for each package, + /// preferring older versions that are compatible with a wider range of supported Python + /// versions or platforms. #[arg( long, value_enum, @@ -4859,9 +4859,9 @@ pub struct ResolverArgs { /// supported Python version (`requires-python`), while minimizing the number of selected /// versions across platforms. /// - /// Under `fewest`, uv will minimize the number of - /// selected versions for each package, preferring older versions that are compatible with a - /// wider range of supported Python versions or platforms. + /// Under `fewest`, uv will minimize the number of selected versions for each package, + /// preferring older versions that are compatible with a wider range of supported Python + /// versions or platforms. #[arg( long, value_enum, @@ -5049,9 +5049,9 @@ pub struct ResolverInstallerArgs { /// supported Python version (`requires-python`), while minimizing the number of selected /// versions across platforms. /// - /// Under `fewest`, uv will minimize the number of - /// selected versions for each package, preferring older versions that are compatible with a - /// wider range of supported Python versions or platforms. + /// Under `fewest`, uv will minimize the number of selected versions for each package, + /// preferring older versions that are compatible with a wider range of supported Python + /// versions or platforms. #[arg( long, value_enum, diff --git a/crates/uv-settings/src/settings.rs b/crates/uv-settings/src/settings.rs index ccc7a6b64..350e32d5d 100644 --- a/crates/uv-settings/src/settings.rs +++ b/crates/uv-settings/src/settings.rs @@ -493,9 +493,9 @@ pub struct ResolverInstallerOptions { /// supported Python version (`requires-python`), while minimizing the number of selected /// versions across platforms. /// - /// Under `fewest`, uv will minimize the number of - /// selected versions for each package, preferring older versions that are compatible with a - /// wider range of supported Python versions or platforms. + /// Under `fewest`, uv will minimize the number of selected versions for each package, + /// preferring older versions that are compatible with a wider range of supported Python + /// versions or platforms. #[option( default = "\"fewest\"", value_type = "str", @@ -1095,9 +1095,9 @@ pub struct PipOptions { /// supported Python version (`requires-python`), while minimizing the number of selected /// versions across platforms. /// - /// Under `fewest`, uv will minimize the number of - /// selected versions for each package, preferring older versions that are compatible with a - /// wider range of supported Python versions or platforms. + /// Under `fewest`, uv will minimize the number of selected versions for each package, + /// preferring older versions that are compatible with a wider range of supported Python + /// versions or platforms. #[option( default = "\"fewest\"", value_type = "str", diff --git a/docs/concepts/resolution.md b/docs/concepts/resolution.md index 55c1f156e..51955f8ed 100644 --- a/docs/concepts/resolution.md +++ b/docs/concepts/resolution.md @@ -88,7 +88,7 @@ This ensures that dependencies are locked for everyone working on the project, r operating system, architecture, and Python version. The uv lockfile is created and modified by [project](../concepts/projects/index.md) commands such as `uv lock`, `uv sync`, and `uv add`. -universal resolution is also available in uv's pip interface, i.e., +Universal resolution is also available in uv's pip interface, i.e., [`uv pip compile`](../pip/compile.md), with the `--universal` flag. The resulting requirements file will contain markers to indicate which platform each dependency is relevant for. @@ -97,12 +97,6 @@ if different versions are needed for different platforms — the markers determi be used. A universal resolution is often more constrained than a platform-specific resolution, since 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 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. - 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, @@ -229,6 +223,40 @@ _intentionally_ limited and requires user opt-in for pre-releases to ensure corr For more details, see [Pre-release compatibility](../pip/compatibility.md#pre-release-compatibility). +## Multi-version resolution + +During universal resolution, a package may be listed multiple times with different versions or URLs +within the same lockfile, since different versions may be needed for different platforms or Python +versions. + +The `--fork-strategy` setting can be used to control how uv trades off between (1) minimizing the +number of selected versions and (2) selecting the latest-possible version for each platform. The +former leads to greater consistency across platforms, while the latter leads to use of newer package +versions where possible. + +By default (`--fork-strategy requires-python`), uv will optimize for selecting the latest version of +each package for each supported Python version, while minimizing the number of selected versions +across platforms. + +For example, when resolving `numpy` with a Python requirement of `>=3.8`, uv would select the +following versions: + +```txt +numpy==1.24.4 ; python_version == "3.8" +numpy==2.0.2 ; python_version == "3.9" +numpy==2.2.0 ; python_version >= "3.10" +``` + +This resolution reflects the fact that NumPy 2.2.0 and later require at least Python 3.10, while +earlier versions are compatible with Python 3.8 and 3.9. + +Under `--fork-strategy fewest`, uv will instead minimize the number of selected versions for each +package, preferring older versions that are compatible with a wider range of supported Python +versions or platforms. + +For example, when in the scenario above, uv would select `numpy==1.24.4` for all Python versions, +rather than upgrading to `numpy==2.0.2` for Python 3.9 and `numpy==2.2.0` for Python 3.10 and later. + ## Dependency constraints Like pip, uv supports constraint files (`--constraint constraints.txt`) which narrow the set of diff --git a/docs/reference/settings.md b/docs/reference/settings.md index 237880f1d..59b486599 100644 --- a/docs/reference/settings.md +++ b/docs/reference/settings.md @@ -773,9 +773,9 @@ By default, uv will optimize for selecting the latest version of each package fo supported Python version (`requires-python`), while minimizing the number of selected versions across platforms. -Under `fewest`, uv will minimize the number of -selected versions for each package, preferring older versions that are compatible with a -wider range of supported Python versions or platforms. +Under `fewest`, uv will minimize the number of selected versions for each package, +preferring older versions that are compatible with a wider range of supported Python +versions or platforms. **Default value**: `"fewest"` @@ -2154,9 +2154,9 @@ By default, uv will optimize for selecting the latest version of each package fo supported Python version (`requires-python`), while minimizing the number of selected versions across platforms. -Under `fewest`, uv will minimize the number of -selected versions for each package, preferring older versions that are compatible with a -wider range of supported Python versions or platforms. +Under `fewest`, uv will minimize the number of selected versions for each package, +preferring older versions that are compatible with a wider range of supported Python +versions or platforms. **Default value**: `"fewest"`