mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 19:08:04 +00:00
Apply extra to overrides and constraints (#4829)
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
This commit is contained in:
parent
0a04108a15
commit
53db63f6dd
8 changed files with 159 additions and 30 deletions
|
@ -1,4 +1,5 @@
|
|||
use either::Either;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use pep508_rs::MarkerEnvironment;
|
||||
use pypi_types::Requirement;
|
||||
|
@ -97,7 +98,7 @@ impl Manifest {
|
|||
&'a self,
|
||||
markers: Option<&'a MarkerEnvironment>,
|
||||
mode: DependencyMode,
|
||||
) -> impl Iterator<Item = &Requirement> + 'a {
|
||||
) -> impl Iterator<Item = Cow<'a, Requirement>> + 'a {
|
||||
self.requirements_no_overrides(markers, mode)
|
||||
.chain(self.overrides(markers, mode))
|
||||
}
|
||||
|
@ -107,7 +108,7 @@ impl Manifest {
|
|||
&'a self,
|
||||
markers: Option<&'a MarkerEnvironment>,
|
||||
mode: DependencyMode,
|
||||
) -> impl Iterator<Item = &Requirement> + 'a {
|
||||
) -> impl Iterator<Item = Cow<'a, Requirement>> + 'a {
|
||||
match mode {
|
||||
// Include all direct and transitive requirements, with constraints and overrides applied.
|
||||
DependencyMode::Transitive => Either::Left(
|
||||
|
@ -128,14 +129,15 @@ impl Manifest {
|
|||
.chain(
|
||||
self.constraints
|
||||
.requirements()
|
||||
.filter(move |requirement| requirement.evaluate_markers(markers, &[])),
|
||||
.filter(move |requirement| requirement.evaluate_markers(markers, &[]))
|
||||
.map(Cow::Borrowed),
|
||||
),
|
||||
),
|
||||
// Include direct requirements, with constraints and overrides applied.
|
||||
DependencyMode::Direct => Either::Right(
|
||||
self.overrides
|
||||
.apply(&self.requirements)
|
||||
.chain(self.constraints.requirements())
|
||||
.chain(self.constraints.requirements().map(Cow::Borrowed))
|
||||
.filter(move |requirement| requirement.evaluate_markers(markers, &[])),
|
||||
),
|
||||
}
|
||||
|
@ -146,19 +148,21 @@ impl Manifest {
|
|||
&'a self,
|
||||
markers: Option<&'a MarkerEnvironment>,
|
||||
mode: DependencyMode,
|
||||
) -> impl Iterator<Item = &Requirement> + 'a {
|
||||
) -> impl Iterator<Item = Cow<'a, Requirement>> + 'a {
|
||||
match mode {
|
||||
// Include all direct and transitive requirements, with constraints and overrides applied.
|
||||
DependencyMode::Transitive => Either::Left(
|
||||
self.overrides
|
||||
.requirements()
|
||||
.filter(move |requirement| requirement.evaluate_markers(markers, &[])),
|
||||
.filter(move |requirement| requirement.evaluate_markers(markers, &[]))
|
||||
.map(Cow::Borrowed),
|
||||
),
|
||||
// Include direct requirements, with constraints and overrides applied.
|
||||
DependencyMode::Direct => Either::Right(
|
||||
self.overrides
|
||||
.requirements()
|
||||
.filter(move |requirement| requirement.evaluate_markers(markers, &[])),
|
||||
.filter(move |requirement| requirement.evaluate_markers(markers, &[]))
|
||||
.map(Cow::Borrowed),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +181,7 @@ impl Manifest {
|
|||
&'a self,
|
||||
markers: Option<&'a MarkerEnvironment>,
|
||||
mode: DependencyMode,
|
||||
) -> impl Iterator<Item = &PackageName> + 'a {
|
||||
) -> impl Iterator<Item = Cow<'a, PackageName>> + 'a {
|
||||
match mode {
|
||||
// Include direct requirements, dependencies of editables, and transitive dependencies
|
||||
// of local packages.
|
||||
|
@ -197,7 +201,10 @@ impl Manifest {
|
|||
.apply(&self.requirements)
|
||||
.filter(move |requirement| requirement.evaluate_markers(markers, &[])),
|
||||
)
|
||||
.map(|requirement| &requirement.name),
|
||||
.map(|requirement| match requirement {
|
||||
Cow::Borrowed(requirement) => Cow::Borrowed(&requirement.name),
|
||||
Cow::Owned(requirement) => Cow::Owned(requirement.name),
|
||||
}),
|
||||
),
|
||||
|
||||
// Restrict to the direct requirements.
|
||||
|
@ -205,7 +212,10 @@ impl Manifest {
|
|||
self.overrides
|
||||
.apply(self.requirements.iter())
|
||||
.filter(move |requirement| requirement.evaluate_markers(markers, &[]))
|
||||
.map(|requirement| &requirement.name),
|
||||
.map(|requirement| match requirement {
|
||||
Cow::Borrowed(requirement) => Cow::Borrowed(&requirement.name),
|
||||
Cow::Owned(requirement) => Cow::Owned(requirement.name),
|
||||
}),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -217,7 +227,7 @@ impl Manifest {
|
|||
pub fn apply<'a>(
|
||||
&'a self,
|
||||
requirements: impl IntoIterator<Item = &'a Requirement>,
|
||||
) -> impl Iterator<Item = &Requirement> {
|
||||
) -> impl Iterator<Item = Cow<'a, Requirement>> {
|
||||
self.constraints.apply(self.overrides.apply(requirements))
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ impl ResolutionStrategy {
|
|||
ResolutionMode::LowestDirect => Self::LowestDirect(
|
||||
manifest
|
||||
.user_requirements(markers, dependencies)
|
||||
.cloned()
|
||||
.map(|requirement| (*requirement).clone())
|
||||
.collect(),
|
||||
),
|
||||
}
|
||||
|
|
|
@ -1477,7 +1477,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
|||
true
|
||||
})
|
||||
.flat_map(move |requirement| {
|
||||
iter::once(Cow::Borrowed(requirement)).chain(
|
||||
iter::once(requirement.clone()).chain(
|
||||
self.constraints
|
||||
.get(&requirement.name)
|
||||
.into_iter()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue