mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-20 03:49:54 +00:00
Enable first-class dependency exclusions (#16528)
## Summary This PR adds an `exclude-dependencies` setting that allows users to omit a dependency during resolution. It's effectively a formalized version of the `flask ; python_version < '0'` hack that we've suggested to users in various issues. Closes #12616.
This commit is contained in:
parent
7978122837
commit
5c71b5c124
42 changed files with 711 additions and 21 deletions
|
|
@ -1163,6 +1163,23 @@ impl Lock {
|
|||
manifest_table.insert("overrides", value(overrides));
|
||||
}
|
||||
|
||||
if !self.manifest.excludes.is_empty() {
|
||||
let excludes = self
|
||||
.manifest
|
||||
.excludes
|
||||
.iter()
|
||||
.map(|name| {
|
||||
serde::Serialize::serialize(&name, toml_edit::ser::ValueSerializer::new())
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
let excludes = match excludes.as_slice() {
|
||||
[] => Array::new(),
|
||||
[name] => Array::from_iter([name]),
|
||||
excludes => each_element_on_its_line_array(excludes.iter()),
|
||||
};
|
||||
manifest_table.insert("excludes", value(excludes));
|
||||
}
|
||||
|
||||
if !self.manifest.build_constraints.is_empty() {
|
||||
let build_constraints = self
|
||||
.manifest
|
||||
|
|
@ -1447,6 +1464,7 @@ impl Lock {
|
|||
requirements: &[Requirement],
|
||||
constraints: &[Requirement],
|
||||
overrides: &[Requirement],
|
||||
excludes: &[PackageName],
|
||||
build_constraints: &[Requirement],
|
||||
dependency_groups: &BTreeMap<GroupName, Vec<Requirement>>,
|
||||
dependency_metadata: &DependencyMetadata,
|
||||
|
|
@ -1563,6 +1581,15 @@ impl Lock {
|
|||
}
|
||||
}
|
||||
|
||||
// Validate that the lockfile was generated with the same excludes.
|
||||
{
|
||||
let expected: BTreeSet<_> = excludes.iter().cloned().collect();
|
||||
let actual: BTreeSet<_> = self.manifest.excludes.iter().cloned().collect();
|
||||
if expected != actual {
|
||||
return Ok(SatisfiesResult::MismatchedExcludes(expected, actual));
|
||||
}
|
||||
}
|
||||
|
||||
// Validate that the lockfile was generated with the same build constraints.
|
||||
{
|
||||
let expected: BTreeSet<_> = build_constraints
|
||||
|
|
@ -2049,6 +2076,8 @@ pub enum SatisfiesResult<'lock> {
|
|||
MismatchedConstraints(BTreeSet<Requirement>, BTreeSet<Requirement>),
|
||||
/// The lockfile uses a different set of overrides.
|
||||
MismatchedOverrides(BTreeSet<Requirement>, BTreeSet<Requirement>),
|
||||
/// The lockfile uses a different set of excludes.
|
||||
MismatchedExcludes(BTreeSet<PackageName>, BTreeSet<PackageName>),
|
||||
/// The lockfile uses a different set of build constraints.
|
||||
MismatchedBuildConstraints(BTreeSet<Requirement>, BTreeSet<Requirement>),
|
||||
/// The lockfile uses a different set of dependency groups.
|
||||
|
|
@ -2148,6 +2177,9 @@ pub struct ResolverManifest {
|
|||
/// The overrides provided to the resolver.
|
||||
#[serde(default)]
|
||||
overrides: BTreeSet<Requirement>,
|
||||
/// The excludes provided to the resolver.
|
||||
#[serde(default)]
|
||||
excludes: BTreeSet<PackageName>,
|
||||
/// The build constraints provided to the resolver.
|
||||
#[serde(default)]
|
||||
build_constraints: BTreeSet<Requirement>,
|
||||
|
|
@ -2164,6 +2196,7 @@ impl ResolverManifest {
|
|||
requirements: impl IntoIterator<Item = Requirement>,
|
||||
constraints: impl IntoIterator<Item = Requirement>,
|
||||
overrides: impl IntoIterator<Item = Requirement>,
|
||||
excludes: impl IntoIterator<Item = PackageName>,
|
||||
build_constraints: impl IntoIterator<Item = Requirement>,
|
||||
dependency_groups: impl IntoIterator<Item = (GroupName, Vec<Requirement>)>,
|
||||
dependency_metadata: impl IntoIterator<Item = StaticMetadata>,
|
||||
|
|
@ -2173,6 +2206,7 @@ impl ResolverManifest {
|
|||
requirements: requirements.into_iter().collect(),
|
||||
constraints: constraints.into_iter().collect(),
|
||||
overrides: overrides.into_iter().collect(),
|
||||
excludes: excludes.into_iter().collect(),
|
||||
build_constraints: build_constraints.into_iter().collect(),
|
||||
dependency_groups: dependency_groups
|
||||
.into_iter()
|
||||
|
|
@ -2201,6 +2235,7 @@ impl ResolverManifest {
|
|||
.into_iter()
|
||||
.map(|requirement| requirement.relative_to(root))
|
||||
.collect::<Result<BTreeSet<_>, _>>()?,
|
||||
excludes: self.excludes,
|
||||
build_constraints: self
|
||||
.build_constraints
|
||||
.into_iter()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue