mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 21:35:00 +00:00

This is an attempt to solve https://github.com/astral-sh/uv/issues/ by applying the extra marker of the requirement to overrides and constraints. Say in `a` we have a requirements ``` b==1; python_version < "3.10" c==1; extra == "feature" ``` and overrides ``` b==2; python_version < "3.10" b==3; python_version >= "3.10" c==2; python_version < "3.10" c==3; python_version >= "3.10" ``` Our current strategy is to discard the markers in the original requirements. This means that on 3.12 for `a` we install `b==3`, but it also means that we add `c` to `a` without `a[feature]`, causing #4826. With this PR, the new requirement become, ``` b==2; python_version < "3.10" b==3; python_version >= "3.10" c==2; python_version < "3.10" and extra == "feature" c==3; python_version >= "3.10" and extra == "feature" ``` allowing to override markers while preserving optional dependencies as such. Fixes #4826
54 lines
1.9 KiB
Rust
54 lines
1.9 KiB
Rust
use rustc_hash::FxHashSet;
|
|
|
|
use pep508_rs::MarkerEnvironment;
|
|
use uv_normalize::PackageName;
|
|
|
|
use crate::{DependencyMode, Manifest};
|
|
|
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, serde::Deserialize)]
|
|
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
|
|
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
|
|
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
|
pub enum ResolutionMode {
|
|
/// Resolve the highest compatible version of each package.
|
|
#[default]
|
|
Highest,
|
|
/// Resolve the lowest compatible version of each package.
|
|
Lowest,
|
|
/// Resolve the lowest compatible version of any direct dependencies, and the highest
|
|
/// compatible version of any transitive dependencies.
|
|
LowestDirect,
|
|
}
|
|
|
|
/// Like [`ResolutionMode`], but with any additional information required to select a candidate,
|
|
/// like the set of direct dependencies.
|
|
#[derive(Debug, Clone)]
|
|
pub(crate) enum ResolutionStrategy {
|
|
/// Resolve the highest compatible version of each package.
|
|
Highest,
|
|
/// Resolve the lowest compatible version of each package.
|
|
Lowest,
|
|
/// Resolve the lowest compatible version of any direct dependencies, and the highest
|
|
/// compatible version of any transitive dependencies.
|
|
LowestDirect(FxHashSet<PackageName>),
|
|
}
|
|
|
|
impl ResolutionStrategy {
|
|
pub(crate) fn from_mode(
|
|
mode: ResolutionMode,
|
|
manifest: &Manifest,
|
|
markers: Option<&MarkerEnvironment>,
|
|
dependencies: DependencyMode,
|
|
) -> Self {
|
|
match mode {
|
|
ResolutionMode::Highest => Self::Highest,
|
|
ResolutionMode::Lowest => Self::Lowest,
|
|
ResolutionMode::LowestDirect => Self::LowestDirect(
|
|
manifest
|
|
.user_requirements(markers, dependencies)
|
|
.map(|requirement| (*requirement).clone())
|
|
.collect(),
|
|
),
|
|
}
|
|
}
|
|
}
|