mirror of
https://github.com/astral-sh/uv.git
synced 2025-09-26 20:19:08 +00:00
*: update "conflicting groups" terminology everywhere else
This commit is contained in:
parent
19a044d4db
commit
bb78e00a87
28 changed files with 134 additions and 142 deletions
|
@ -163,7 +163,7 @@ mod resolver {
|
||||||
let options = OptionsBuilder::new().exclude_newer(exclude_newer).build();
|
let options = OptionsBuilder::new().exclude_newer(exclude_newer).build();
|
||||||
let sources = SourceStrategy::default();
|
let sources = SourceStrategy::default();
|
||||||
let dependency_metadata = DependencyMetadata::default();
|
let dependency_metadata = DependencyMetadata::default();
|
||||||
let conflicting_groups = Conflicts::empty();
|
let conflicts = Conflicts::empty();
|
||||||
|
|
||||||
let python_requirement = if universal {
|
let python_requirement = if universal {
|
||||||
PythonRequirement::from_requires_python(
|
PythonRequirement::from_requires_python(
|
||||||
|
@ -209,7 +209,7 @@ mod resolver {
|
||||||
options,
|
options,
|
||||||
&python_requirement,
|
&python_requirement,
|
||||||
markers,
|
markers,
|
||||||
conflicting_groups,
|
conflicts,
|
||||||
Some(&TAGS),
|
Some(&TAGS),
|
||||||
&flat_index,
|
&flat_index,
|
||||||
&index,
|
&index,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use uv_normalize::{ExtraName, PackageName};
|
use uv_normalize::{ExtraName, PackageName};
|
||||||
|
|
||||||
/// A list of conflicting groups pre-defined by an end user.
|
/// A list of conflicting sets of extras/groups pre-defined by an end user.
|
||||||
///
|
///
|
||||||
/// This is useful to force the resolver to fork according to extras that have
|
/// This is useful to force the resolver to fork according to extras that have
|
||||||
/// unavoidable conflicts with each other. (The alternative is that resolution
|
/// unavoidable conflicts with each other. (The alternative is that resolution
|
||||||
|
@ -11,7 +11,7 @@ use uv_normalize::{ExtraName, PackageName};
|
||||||
pub struct Conflicts(Vec<ConflictSet>);
|
pub struct Conflicts(Vec<ConflictSet>);
|
||||||
|
|
||||||
impl Conflicts {
|
impl Conflicts {
|
||||||
/// Returns no conflicting groups.
|
/// Returns no conflicts.
|
||||||
///
|
///
|
||||||
/// This results in no effect on resolution.
|
/// This results in no effect on resolution.
|
||||||
pub fn empty() -> Conflicts {
|
pub fn empty() -> Conflicts {
|
||||||
|
@ -31,7 +31,7 @@ impl Conflicts {
|
||||||
/// Returns true if these conflicts contain any set that contains the given
|
/// Returns true if these conflicts contain any set that contains the given
|
||||||
/// package and extra name pair.
|
/// package and extra name pair.
|
||||||
pub fn contains(&self, package: &PackageName, extra: &ExtraName) -> bool {
|
pub fn contains(&self, package: &PackageName, extra: &ExtraName) -> bool {
|
||||||
self.iter().any(|groups| groups.contains(package, extra))
|
self.iter().any(|set| set.contains(package, extra))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if there are no conflicts.
|
/// Returns true if there are no conflicts.
|
||||||
|
@ -78,7 +78,7 @@ impl ConflictSet {
|
||||||
/// extra name pair.
|
/// extra name pair.
|
||||||
pub fn contains(&self, package: &PackageName, extra: &ExtraName) -> bool {
|
pub fn contains(&self, package: &PackageName, extra: &ExtraName) -> bool {
|
||||||
self.iter()
|
self.iter()
|
||||||
.any(|group| group.package() == package && group.extra() == extra)
|
.any(|set| set.package() == package && set.extra() == extra)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,8 +87,8 @@ impl<'de> serde::Deserialize<'de> for ConflictSet {
|
||||||
where
|
where
|
||||||
D: serde::Deserializer<'de>,
|
D: serde::Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let groups = Vec::<ConflictItem>::deserialize(deserializer)?;
|
let set = Vec::<ConflictItem>::deserialize(deserializer)?;
|
||||||
Self::try_from(groups).map_err(serde::de::Error::custom)
|
Self::try_from(set).map_err(serde::de::Error::custom)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,10 +193,10 @@ impl<'a> From<(&'a PackageName, &'a ExtraName)> for ConflictItemRef<'a> {
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum ConflictError {
|
pub enum ConflictError {
|
||||||
/// An error for when there are zero conflicting items.
|
/// An error for when there are zero conflicting items.
|
||||||
#[error("Each set of conflicting groups must have at least two entries, but found none")]
|
#[error("Each set of conflicts must have at least two entries, but found none")]
|
||||||
ZeroItems,
|
ZeroItems,
|
||||||
/// An error for when there is one conflicting items.
|
/// An error for when there is one conflicting items.
|
||||||
#[error("Each set of conflicting groups must have at least two entries, but found only one")]
|
#[error("Each set of conflicts must have at least two entries, but found only one")]
|
||||||
OneItem,
|
OneItem,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ impl SchemaConflicts {
|
||||||
/// If a conflict has an explicit package name (written by the end user),
|
/// If a conflict has an explicit package name (written by the end user),
|
||||||
/// then that takes precedence over the given package name, which is only
|
/// then that takes precedence over the given package name, which is only
|
||||||
/// used when there is no explicit package name written.
|
/// used when there is no explicit package name written.
|
||||||
pub fn to_conflicting_with_package_name(&self, package: &PackageName) -> Conflicts {
|
pub fn to_conflicts_with_package_name(&self, package: &PackageName) -> Conflicts {
|
||||||
let mut conflicting = Conflicts::empty();
|
let mut conflicting = Conflicts::empty();
|
||||||
for tool_uv_set in &self.0 {
|
for tool_uv_set in &self.0 {
|
||||||
let mut set = vec![];
|
let mut set = vec![];
|
||||||
|
|
|
@ -82,7 +82,7 @@ pub struct Lock {
|
||||||
/// forks in the lockfile so we can recreate them in subsequent resolutions.
|
/// forks in the lockfile so we can recreate them in subsequent resolutions.
|
||||||
fork_markers: Vec<MarkerTree>,
|
fork_markers: Vec<MarkerTree>,
|
||||||
/// The conflicting groups/extras specified by the user.
|
/// The conflicting groups/extras specified by the user.
|
||||||
conflicting_groups: Conflicts,
|
conflicts: Conflicts,
|
||||||
/// The list of supported environments specified by the user.
|
/// The list of supported environments specified by the user.
|
||||||
supported_environments: Vec<MarkerTree>,
|
supported_environments: Vec<MarkerTree>,
|
||||||
/// The range of supported Python versions.
|
/// The range of supported Python versions.
|
||||||
|
@ -315,7 +315,7 @@ impl Lock {
|
||||||
requires_python: RequiresPython,
|
requires_python: RequiresPython,
|
||||||
options: ResolverOptions,
|
options: ResolverOptions,
|
||||||
manifest: ResolverManifest,
|
manifest: ResolverManifest,
|
||||||
conflicting_groups: Conflicts,
|
conflicts: Conflicts,
|
||||||
supported_environments: Vec<MarkerTree>,
|
supported_environments: Vec<MarkerTree>,
|
||||||
fork_markers: Vec<MarkerTree>,
|
fork_markers: Vec<MarkerTree>,
|
||||||
) -> Result<Self, LockError> {
|
) -> Result<Self, LockError> {
|
||||||
|
@ -465,7 +465,7 @@ impl Lock {
|
||||||
let lock = Self {
|
let lock = Self {
|
||||||
version,
|
version,
|
||||||
fork_markers,
|
fork_markers,
|
||||||
conflicting_groups,
|
conflicts,
|
||||||
supported_environments,
|
supported_environments,
|
||||||
requires_python,
|
requires_python,
|
||||||
options,
|
options,
|
||||||
|
@ -485,8 +485,8 @@ impl Lock {
|
||||||
|
|
||||||
/// Record the conflicting groups that were used to generate this lock.
|
/// Record the conflicting groups that were used to generate this lock.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn with_conflicting_groups(mut self, conflicting_groups: Conflicts) -> Self {
|
pub fn with_conflicts(mut self, conflicts: Conflicts) -> Self {
|
||||||
self.conflicting_groups = conflicting_groups;
|
self.conflicts = conflicts;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -550,8 +550,8 @@ impl Lock {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the conflicting groups that were used to generate this lock.
|
/// Returns the conflicting groups that were used to generate this lock.
|
||||||
pub fn conflicting_groups(&self) -> &Conflicts {
|
pub fn conflicts(&self) -> &Conflicts {
|
||||||
&self.conflicting_groups
|
&self.conflicts
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the supported environments that were used to generate this lock.
|
/// Returns the supported environments that were used to generate this lock.
|
||||||
|
@ -632,9 +632,9 @@ impl Lock {
|
||||||
doc.insert("supported-markers", value(supported_environments));
|
doc.insert("supported-markers", value(supported_environments));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.conflicting_groups.is_empty() {
|
if !self.conflicts.is_empty() {
|
||||||
let mut list = Array::new();
|
let mut list = Array::new();
|
||||||
for groups in self.conflicting_groups.iter() {
|
for groups in self.conflicts.iter() {
|
||||||
list.push(each_element_on_its_line_array(groups.iter().map(|group| {
|
list.push(each_element_on_its_line_array(groups.iter().map(|group| {
|
||||||
let mut table = InlineTable::new();
|
let mut table = InlineTable::new();
|
||||||
table.insert("package", Value::from(group.package().to_string()));
|
table.insert("package", Value::from(group.package().to_string()));
|
||||||
|
@ -642,7 +642,7 @@ impl Lock {
|
||||||
table
|
table
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
doc.insert("conflicting-groups", value(list));
|
doc.insert("conflicts", value(list));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the settings that were used to generate the resolution.
|
// Write the settings that were used to generate the resolution.
|
||||||
|
@ -1383,8 +1383,8 @@ struct LockWire {
|
||||||
fork_markers: Vec<SimplifiedMarkerTree>,
|
fork_markers: Vec<SimplifiedMarkerTree>,
|
||||||
#[serde(rename = "supported-markers", default)]
|
#[serde(rename = "supported-markers", default)]
|
||||||
supported_environments: Vec<SimplifiedMarkerTree>,
|
supported_environments: Vec<SimplifiedMarkerTree>,
|
||||||
#[serde(rename = "conflicting-groups", default)]
|
#[serde(rename = "conflicts", default)]
|
||||||
conflicting_groups: Option<Conflicts>,
|
conflicts: Option<Conflicts>,
|
||||||
/// We discard the lockfile if these options match.
|
/// We discard the lockfile if these options match.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
options: ResolverOptions,
|
options: ResolverOptions,
|
||||||
|
@ -1436,7 +1436,7 @@ impl TryFrom<LockWire> for Lock {
|
||||||
wire.requires_python,
|
wire.requires_python,
|
||||||
wire.options,
|
wire.options,
|
||||||
wire.manifest,
|
wire.manifest,
|
||||||
wire.conflicting_groups.unwrap_or_else(Conflicts::empty),
|
wire.conflicts.unwrap_or_else(Conflicts::empty),
|
||||||
supported_environments,
|
supported_environments,
|
||||||
fork_markers,
|
fork_markers,
|
||||||
)?;
|
)?;
|
||||||
|
|
|
@ -6,7 +6,7 @@ Ok(
|
||||||
Lock {
|
Lock {
|
||||||
version: 1,
|
version: 1,
|
||||||
fork_markers: [],
|
fork_markers: [],
|
||||||
conflicting_groups: ConflictingGroupList(
|
conflicts: Conflicts(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
|
|
@ -6,7 +6,7 @@ Ok(
|
||||||
Lock {
|
Lock {
|
||||||
version: 1,
|
version: 1,
|
||||||
fork_markers: [],
|
fork_markers: [],
|
||||||
conflicting_groups: ConflictingGroupList(
|
conflicts: Conflicts(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
|
|
@ -6,7 +6,7 @@ Ok(
|
||||||
Lock {
|
Lock {
|
||||||
version: 1,
|
version: 1,
|
||||||
fork_markers: [],
|
fork_markers: [],
|
||||||
conflicting_groups: ConflictingGroupList(
|
conflicts: Conflicts(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
|
|
@ -6,7 +6,7 @@ Ok(
|
||||||
Lock {
|
Lock {
|
||||||
version: 1,
|
version: 1,
|
||||||
fork_markers: [],
|
fork_markers: [],
|
||||||
conflicting_groups: ConflictingGroupList(
|
conflicts: Conflicts(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
|
|
@ -6,7 +6,7 @@ Ok(
|
||||||
Lock {
|
Lock {
|
||||||
version: 1,
|
version: 1,
|
||||||
fork_markers: [],
|
fork_markers: [],
|
||||||
conflicting_groups: ConflictingGroupList(
|
conflicts: Conflicts(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
|
|
@ -6,7 +6,7 @@ Ok(
|
||||||
Lock {
|
Lock {
|
||||||
version: 1,
|
version: 1,
|
||||||
fork_markers: [],
|
fork_markers: [],
|
||||||
conflicting_groups: ConflictingGroupList(
|
conflicts: Conflicts(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
|
|
@ -6,7 +6,7 @@ Ok(
|
||||||
Lock {
|
Lock {
|
||||||
version: 1,
|
version: 1,
|
||||||
fork_markers: [],
|
fork_markers: [],
|
||||||
conflicting_groups: ConflictingGroupList(
|
conflicts: Conflicts(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
|
|
@ -6,7 +6,7 @@ Ok(
|
||||||
Lock {
|
Lock {
|
||||||
version: 1,
|
version: 1,
|
||||||
fork_markers: [],
|
fork_markers: [],
|
||||||
conflicting_groups: ConflictingGroupList(
|
conflicts: Conflicts(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
|
|
@ -6,7 +6,7 @@ Ok(
|
||||||
Lock {
|
Lock {
|
||||||
version: 1,
|
version: 1,
|
||||||
fork_markers: [],
|
fork_markers: [],
|
||||||
conflicting_groups: ConflictingGroupList(
|
conflicts: Conflicts(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
|
|
@ -6,7 +6,7 @@ Ok(
|
||||||
Lock {
|
Lock {
|
||||||
version: 1,
|
version: 1,
|
||||||
fork_markers: [],
|
fork_markers: [],
|
||||||
conflicting_groups: ConflictingGroupList(
|
conflicts: Conflicts(
|
||||||
[],
|
[],
|
||||||
),
|
),
|
||||||
supported_environments: [],
|
supported_environments: [],
|
||||||
|
|
|
@ -190,7 +190,7 @@ impl PubGrubPackage {
|
||||||
///
|
///
|
||||||
/// If this package can't possibly be classified as a conflicting group,
|
/// If this package can't possibly be classified as a conflicting group,
|
||||||
/// then this returns `None`.
|
/// then this returns `None`.
|
||||||
pub(crate) fn conflicting_group(&self) -> Option<ConflictItemRef<'_>> {
|
pub(crate) fn conflicting_item(&self) -> Option<ConflictItemRef<'_>> {
|
||||||
let package = self.name_no_root()?;
|
let package = self.name_no_root()?;
|
||||||
let extra = self.extra()?;
|
let extra = self.extra()?;
|
||||||
Some(ConflictItemRef::from((package, extra)))
|
Some(ConflictItemRef::from((package, extra)))
|
||||||
|
|
|
@ -103,7 +103,7 @@ impl ResolutionGraph {
|
||||||
index: &InMemoryIndex,
|
index: &InMemoryIndex,
|
||||||
git: &GitResolver,
|
git: &GitResolver,
|
||||||
python: &PythonRequirement,
|
python: &PythonRequirement,
|
||||||
conflicting_groups: &Conflicts,
|
conflicts: &Conflicts,
|
||||||
resolution_strategy: &ResolutionStrategy,
|
resolution_strategy: &ResolutionStrategy,
|
||||||
options: Options,
|
options: Options,
|
||||||
) -> Result<Self, ResolveError> {
|
) -> Result<Self, ResolveError> {
|
||||||
|
@ -251,7 +251,7 @@ impl ResolutionGraph {
|
||||||
// the same time. At which point, uv will report an error,
|
// the same time. At which point, uv will report an error,
|
||||||
// thereby sidestepping the possibility of installing different
|
// thereby sidestepping the possibility of installing different
|
||||||
// versions of the same package into the same virtualenv. ---AG
|
// versions of the same package into the same virtualenv. ---AG
|
||||||
if conflicting_groups.is_empty() {
|
if conflicts.is_empty() {
|
||||||
#[allow(unused_mut, reason = "Used in debug_assertions below")]
|
#[allow(unused_mut, reason = "Used in debug_assertions below")]
|
||||||
let mut conflicting = graph.find_conflicting_distributions();
|
let mut conflicting = graph.find_conflicting_distributions();
|
||||||
if !conflicting.is_empty() {
|
if !conflicting.is_empty() {
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::sync::Arc;
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use uv_normalize::{ExtraName, PackageName};
|
use uv_normalize::{ExtraName, PackageName};
|
||||||
use uv_pep508::{MarkerEnvironment, MarkerTree};
|
use uv_pep508::{MarkerEnvironment, MarkerTree};
|
||||||
use uv_pypi_types::{ConflictItem, ConflictItemRef, Conflicts, ResolverMarkerEnvironment};
|
use uv_pypi_types::{ConflictItem, ConflictItemRef, ResolverMarkerEnvironment};
|
||||||
|
|
||||||
use crate::pubgrub::{PubGrubDependency, PubGrubPackage};
|
use crate::pubgrub::{PubGrubDependency, PubGrubPackage};
|
||||||
use crate::requires_python::RequiresPythonRange;
|
use crate::requires_python::RequiresPythonRange;
|
||||||
|
@ -425,7 +425,6 @@ impl<'d> Forker<'d> {
|
||||||
pub(crate) fn fork(
|
pub(crate) fn fork(
|
||||||
&self,
|
&self,
|
||||||
env: &ResolverEnvironment,
|
env: &ResolverEnvironment,
|
||||||
_conflicting_groups: &Conflicts,
|
|
||||||
) -> Option<(Forker<'d>, Vec<ResolverEnvironment>)> {
|
) -> Option<(Forker<'d>, Vec<ResolverEnvironment>)> {
|
||||||
if !env.included_by_marker(&self.marker) {
|
if !env.included_by_marker(&self.marker) {
|
||||||
return None;
|
return None;
|
||||||
|
|
|
@ -109,7 +109,7 @@ struct ResolverState<InstalledPackages: InstalledPackagesProvider> {
|
||||||
hasher: HashStrategy,
|
hasher: HashStrategy,
|
||||||
env: ResolverEnvironment,
|
env: ResolverEnvironment,
|
||||||
python_requirement: PythonRequirement,
|
python_requirement: PythonRequirement,
|
||||||
conflicting_groups: Conflicts,
|
conflicts: Conflicts,
|
||||||
workspace_members: BTreeSet<PackageName>,
|
workspace_members: BTreeSet<PackageName>,
|
||||||
selector: CandidateSelector,
|
selector: CandidateSelector,
|
||||||
index: InMemoryIndex,
|
index: InMemoryIndex,
|
||||||
|
@ -150,7 +150,7 @@ impl<'a, Context: BuildContext, InstalledPackages: InstalledPackagesProvider>
|
||||||
options: Options,
|
options: Options,
|
||||||
python_requirement: &'a PythonRequirement,
|
python_requirement: &'a PythonRequirement,
|
||||||
env: ResolverEnvironment,
|
env: ResolverEnvironment,
|
||||||
conflicting_groups: Conflicts,
|
conflicts: Conflicts,
|
||||||
tags: Option<&'a Tags>,
|
tags: Option<&'a Tags>,
|
||||||
flat_index: &'a FlatIndex,
|
flat_index: &'a FlatIndex,
|
||||||
index: &'a InMemoryIndex,
|
index: &'a InMemoryIndex,
|
||||||
|
@ -177,7 +177,7 @@ impl<'a, Context: BuildContext, InstalledPackages: InstalledPackagesProvider>
|
||||||
hasher,
|
hasher,
|
||||||
env,
|
env,
|
||||||
python_requirement,
|
python_requirement,
|
||||||
conflicting_groups,
|
conflicts,
|
||||||
index,
|
index,
|
||||||
build_context.git(),
|
build_context.git(),
|
||||||
build_context.capabilities(),
|
build_context.capabilities(),
|
||||||
|
@ -198,7 +198,7 @@ impl<Provider: ResolverProvider, InstalledPackages: InstalledPackagesProvider>
|
||||||
hasher: &HashStrategy,
|
hasher: &HashStrategy,
|
||||||
env: ResolverEnvironment,
|
env: ResolverEnvironment,
|
||||||
python_requirement: &PythonRequirement,
|
python_requirement: &PythonRequirement,
|
||||||
conflicting_groups: Conflicts,
|
conflicts: Conflicts,
|
||||||
index: &InMemoryIndex,
|
index: &InMemoryIndex,
|
||||||
git: &GitResolver,
|
git: &GitResolver,
|
||||||
capabilities: &IndexCapabilities,
|
capabilities: &IndexCapabilities,
|
||||||
|
@ -226,7 +226,7 @@ impl<Provider: ResolverProvider, InstalledPackages: InstalledPackagesProvider>
|
||||||
locations: locations.clone(),
|
locations: locations.clone(),
|
||||||
env,
|
env,
|
||||||
python_requirement: python_requirement.clone(),
|
python_requirement: python_requirement.clone(),
|
||||||
conflicting_groups,
|
conflicts,
|
||||||
installed_packages,
|
installed_packages,
|
||||||
unavailable_packages: DashMap::default(),
|
unavailable_packages: DashMap::default(),
|
||||||
incomplete_packages: DashMap::default(),
|
incomplete_packages: DashMap::default(),
|
||||||
|
@ -607,7 +607,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
&self.index,
|
&self.index,
|
||||||
&self.git,
|
&self.git,
|
||||||
&self.python_requirement,
|
&self.python_requirement,
|
||||||
&self.conflicting_groups,
|
&self.conflicts,
|
||||||
self.selector.resolution_strategy(),
|
self.selector.resolution_strategy(),
|
||||||
self.options,
|
self.options,
|
||||||
)
|
)
|
||||||
|
@ -1207,7 +1207,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
Dependencies::Unavailable(err) => ForkedDependencies::Unavailable(err),
|
Dependencies::Unavailable(err) => ForkedDependencies::Unavailable(err),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Ok(result?.fork(env, python_requirement, &self.conflicting_groups))
|
Ok(result?.fork(env, python_requirement, &self.conflicts))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1387,15 +1387,12 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(err) =
|
if let Some(err) = find_conflicting_extra(&self.conflicts, &metadata.requires_dist)
|
||||||
find_conflicting_extra(&self.conflicting_groups, &metadata.requires_dist)
|
|
||||||
{
|
{
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
for dependencies in metadata.dependency_groups.values() {
|
for dependencies in metadata.dependency_groups.values() {
|
||||||
if let Some(err) =
|
if let Some(err) = find_conflicting_extra(&self.conflicts, dependencies) {
|
||||||
find_conflicting_extra(&self.conflicting_groups, dependencies)
|
|
||||||
{
|
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2694,7 +2691,7 @@ impl Dependencies {
|
||||||
self,
|
self,
|
||||||
env: &ResolverEnvironment,
|
env: &ResolverEnvironment,
|
||||||
python_requirement: &PythonRequirement,
|
python_requirement: &PythonRequirement,
|
||||||
conflicting_groups: &Conflicts,
|
conflicts: &Conflicts,
|
||||||
) -> ForkedDependencies {
|
) -> ForkedDependencies {
|
||||||
let deps = match self {
|
let deps = match self {
|
||||||
Dependencies::Available(deps) => deps,
|
Dependencies::Available(deps) => deps,
|
||||||
|
@ -2713,7 +2710,7 @@ impl Dependencies {
|
||||||
let Forks {
|
let Forks {
|
||||||
mut forks,
|
mut forks,
|
||||||
diverging_packages,
|
diverging_packages,
|
||||||
} = Forks::new(name_to_deps, env, python_requirement, conflicting_groups);
|
} = Forks::new(name_to_deps, env, python_requirement, conflicts);
|
||||||
if forks.is_empty() {
|
if forks.is_empty() {
|
||||||
ForkedDependencies::Unforked(vec![])
|
ForkedDependencies::Unforked(vec![])
|
||||||
} else if forks.len() == 1 {
|
} else if forks.len() == 1 {
|
||||||
|
@ -2775,7 +2772,7 @@ impl Forks {
|
||||||
name_to_deps: BTreeMap<PackageName, Vec<PubGrubDependency>>,
|
name_to_deps: BTreeMap<PackageName, Vec<PubGrubDependency>>,
|
||||||
env: &ResolverEnvironment,
|
env: &ResolverEnvironment,
|
||||||
python_requirement: &PythonRequirement,
|
python_requirement: &PythonRequirement,
|
||||||
conflicting_groups: &Conflicts,
|
conflicts: &Conflicts,
|
||||||
) -> Forks {
|
) -> Forks {
|
||||||
let python_marker = python_requirement.to_marker_tree();
|
let python_marker = python_requirement.to_marker_tree();
|
||||||
|
|
||||||
|
@ -2839,8 +2836,7 @@ impl Forks {
|
||||||
|
|
||||||
let mut new = vec![];
|
let mut new = vec![];
|
||||||
for fork in std::mem::take(&mut forks) {
|
for fork in std::mem::take(&mut forks) {
|
||||||
let Some((remaining_forker, envs)) = forker.fork(&fork.env, conflicting_groups)
|
let Some((remaining_forker, envs)) = forker.fork(&fork.env) else {
|
||||||
else {
|
|
||||||
new.push(fork);
|
new.push(fork);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
@ -2880,12 +2876,12 @@ impl Forks {
|
||||||
// For example, if we have conflicting groups {x1, x2} and {x3,
|
// For example, if we have conflicting groups {x1, x2} and {x3,
|
||||||
// x4}, we need to make sure the forks generated from one set
|
// x4}, we need to make sure the forks generated from one set
|
||||||
// also account for the other set.
|
// also account for the other set.
|
||||||
for groups in conflicting_groups.iter() {
|
for groups in conflicts.iter() {
|
||||||
let mut new = vec![];
|
let mut new = vec![];
|
||||||
for fork in std::mem::take(&mut forks) {
|
for fork in std::mem::take(&mut forks) {
|
||||||
let mut has_conflicting_dependency = false;
|
let mut has_conflicting_dependency = false;
|
||||||
for group in groups.iter() {
|
for group in groups.iter() {
|
||||||
if fork.contains_conflicting_group(group.as_ref()) {
|
if fork.contains_conflicting_item(group.as_ref()) {
|
||||||
has_conflicting_dependency = true;
|
has_conflicting_dependency = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2954,7 +2950,7 @@ struct Fork {
|
||||||
/// This exists to make some access patterns more efficient. Namely,
|
/// This exists to make some access patterns more efficient. Namely,
|
||||||
/// it makes it easy to check whether there's a dependency with a
|
/// it makes it easy to check whether there's a dependency with a
|
||||||
/// particular conflicting group in this fork.
|
/// particular conflicting group in this fork.
|
||||||
conflicting_groups: FxHashMap<PackageName, FxHashSet<ExtraName>>,
|
conflicts: FxHashMap<PackageName, FxHashSet<ExtraName>>,
|
||||||
/// The resolver environment for this fork.
|
/// The resolver environment for this fork.
|
||||||
///
|
///
|
||||||
/// Principally, this corresponds to the markers in this for. So in the
|
/// Principally, this corresponds to the markers in this for. So in the
|
||||||
|
@ -2975,18 +2971,18 @@ impl Fork {
|
||||||
fn new(env: ResolverEnvironment) -> Fork {
|
fn new(env: ResolverEnvironment) -> Fork {
|
||||||
Fork {
|
Fork {
|
||||||
dependencies: vec![],
|
dependencies: vec![],
|
||||||
conflicting_groups: FxHashMap::default(),
|
conflicts: FxHashMap::default(),
|
||||||
env,
|
env,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a dependency to this fork.
|
/// Add a dependency to this fork.
|
||||||
fn add_dependency(&mut self, dep: PubGrubDependency) {
|
fn add_dependency(&mut self, dep: PubGrubDependency) {
|
||||||
if let Some(conflicting_group) = dep.package.conflicting_group() {
|
if let Some(conflicting_item) = dep.package.conflicting_item() {
|
||||||
self.conflicting_groups
|
self.conflicts
|
||||||
.entry(conflicting_group.package().clone())
|
.entry(conflicting_item.package().clone())
|
||||||
.or_default()
|
.or_default()
|
||||||
.insert(conflicting_group.extra().clone());
|
.insert(conflicting_item.extra().clone());
|
||||||
}
|
}
|
||||||
self.dependencies.push(dep);
|
self.dependencies.push(dep);
|
||||||
}
|
}
|
||||||
|
@ -3004,9 +3000,9 @@ impl Fork {
|
||||||
if self.env.included_by_marker(markers) {
|
if self.env.included_by_marker(markers) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if let Some(conflicting_group) = dep.package.conflicting_group() {
|
if let Some(conflicting_item) = dep.package.conflicting_item() {
|
||||||
if let Some(set) = self.conflicting_groups.get_mut(conflicting_group.package()) {
|
if let Some(set) = self.conflicts.get_mut(conflicting_item.package()) {
|
||||||
set.remove(conflicting_group.extra());
|
set.remove(conflicting_item.extra());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
|
@ -3015,8 +3011,8 @@ impl Fork {
|
||||||
|
|
||||||
/// Returns true if any of the dependencies in this fork contain a
|
/// Returns true if any of the dependencies in this fork contain a
|
||||||
/// dependency with the given package and extra values.
|
/// dependency with the given package and extra values.
|
||||||
fn contains_conflicting_group(&self, group: ConflictItemRef<'_>) -> bool {
|
fn contains_conflicting_item(&self, group: ConflictItemRef<'_>) -> bool {
|
||||||
self.conflicting_groups
|
self.conflicts
|
||||||
.get(group.package())
|
.get(group.package())
|
||||||
.map(|set| set.contains(group.extra()))
|
.map(|set| set.contains(group.extra()))
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
|
@ -3028,15 +3024,15 @@ impl Fork {
|
||||||
fn exclude(mut self, groups: impl IntoIterator<Item = ConflictItem>) -> Fork {
|
fn exclude(mut self, groups: impl IntoIterator<Item = ConflictItem>) -> Fork {
|
||||||
self.env = self.env.exclude_by_group(groups);
|
self.env = self.env.exclude_by_group(groups);
|
||||||
self.dependencies.retain(|dep| {
|
self.dependencies.retain(|dep| {
|
||||||
let Some(conflicting_group) = dep.package.conflicting_group() else {
|
let Some(conflicting_item) = dep.package.conflicting_item() else {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
if self.env.included_by_group(conflicting_group) {
|
if self.env.included_by_group(conflicting_item) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if let Some(conflicting_group) = dep.package.conflicting_group() {
|
if let Some(conflicting_item) = dep.package.conflicting_item() {
|
||||||
if let Some(set) = self.conflicting_groups.get_mut(conflicting_group.package()) {
|
if let Some(set) = self.conflicts.get_mut(conflicting_item.package()) {
|
||||||
set.remove(conflicting_group.extra());
|
set.remove(conflicting_item.extra());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
|
|
|
@ -105,7 +105,7 @@ pub struct Options {
|
||||||
// `crates/uv-workspace/src/pyproject.rs`. The documentation lives on that struct.
|
// `crates/uv-workspace/src/pyproject.rs`. The documentation lives on that struct.
|
||||||
// They're only respected in `pyproject.toml` files, and should be rejected in `uv.toml` files.
|
// They're only respected in `pyproject.toml` files, and should be rejected in `uv.toml` files.
|
||||||
#[cfg_attr(feature = "schemars", schemars(skip))]
|
#[cfg_attr(feature = "schemars", schemars(skip))]
|
||||||
pub conflicting_groups: Option<serde::de::IgnoredAny>,
|
pub conflicts: Option<serde::de::IgnoredAny>,
|
||||||
|
|
||||||
#[cfg_attr(feature = "schemars", schemars(skip))]
|
#[cfg_attr(feature = "schemars", schemars(skip))]
|
||||||
pub workspace: Option<serde::de::IgnoredAny>,
|
pub workspace: Option<serde::de::IgnoredAny>,
|
||||||
|
@ -1626,7 +1626,7 @@ pub struct OptionsWire {
|
||||||
// NOTE(charlie): These fields should be kept in-sync with `ToolUv` in
|
// NOTE(charlie): These fields should be kept in-sync with `ToolUv` in
|
||||||
// `crates/uv-workspace/src/pyproject.rs`. The documentation lives on that struct.
|
// `crates/uv-workspace/src/pyproject.rs`. The documentation lives on that struct.
|
||||||
// They're only respected in `pyproject.toml` files, and should be rejected in `uv.toml` files.
|
// They're only respected in `pyproject.toml` files, and should be rejected in `uv.toml` files.
|
||||||
conflicting_groups: Option<serde::de::IgnoredAny>,
|
conflicts: Option<serde::de::IgnoredAny>,
|
||||||
workspace: Option<serde::de::IgnoredAny>,
|
workspace: Option<serde::de::IgnoredAny>,
|
||||||
sources: Option<serde::de::IgnoredAny>,
|
sources: Option<serde::de::IgnoredAny>,
|
||||||
managed: Option<serde::de::IgnoredAny>,
|
managed: Option<serde::de::IgnoredAny>,
|
||||||
|
@ -1681,7 +1681,7 @@ impl From<OptionsWire> for Options {
|
||||||
override_dependencies,
|
override_dependencies,
|
||||||
constraint_dependencies,
|
constraint_dependencies,
|
||||||
environments,
|
environments,
|
||||||
conflicting_groups,
|
conflicts,
|
||||||
publish_url,
|
publish_url,
|
||||||
trusted_publishing,
|
trusted_publishing,
|
||||||
workspace,
|
workspace,
|
||||||
|
@ -1743,7 +1743,7 @@ impl From<OptionsWire> for Options {
|
||||||
python_install_mirror,
|
python_install_mirror,
|
||||||
pypy_install_mirror,
|
pypy_install_mirror,
|
||||||
),
|
),
|
||||||
conflicting_groups,
|
conflicts,
|
||||||
publish: PublishOptions {
|
publish: PublishOptions {
|
||||||
publish_url,
|
publish_url,
|
||||||
trusted_publishing,
|
trusted_publishing,
|
||||||
|
|
|
@ -102,7 +102,7 @@ impl PyProjectToml {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the set of conflicts for the project.
|
/// Returns the set of conflicts for the project.
|
||||||
pub fn conflicting_groups(&self) -> Conflicts {
|
pub fn conflicts(&self) -> Conflicts {
|
||||||
let empty = Conflicts::empty();
|
let empty = Conflicts::empty();
|
||||||
let Some(project) = self.project.as_ref() else {
|
let Some(project) = self.project.as_ref() else {
|
||||||
return empty;
|
return empty;
|
||||||
|
@ -113,10 +113,10 @@ impl PyProjectToml {
|
||||||
let Some(tooluv) = tool.uv.as_ref() else {
|
let Some(tooluv) = tool.uv.as_ref() else {
|
||||||
return empty;
|
return empty;
|
||||||
};
|
};
|
||||||
let Some(conflicting) = tooluv.conflicting_groups.as_ref() else {
|
let Some(conflicting) = tooluv.conflicts.as_ref() else {
|
||||||
return empty;
|
return empty;
|
||||||
};
|
};
|
||||||
conflicting.to_conflicting_with_package_name(&project.name)
|
conflicting.to_conflicts_with_package_name(&project.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,7 +494,7 @@ pub struct ToolUv {
|
||||||
# Require that `package[test1]` and `package[test2]`
|
# Require that `package[test1]` and `package[test2]`
|
||||||
# requirements are resolved in different forks so that they
|
# requirements are resolved in different forks so that they
|
||||||
# cannot conflict with one another.
|
# cannot conflict with one another.
|
||||||
conflicting-groups = [
|
conflicts = [
|
||||||
[
|
[
|
||||||
{ extra = "test1" },
|
{ extra = "test1" },
|
||||||
{ extra = "test2" },
|
{ extra = "test2" },
|
||||||
|
@ -503,7 +503,7 @@ pub struct ToolUv {
|
||||||
"#
|
"#
|
||||||
)]
|
)]
|
||||||
*/
|
*/
|
||||||
pub conflicting_groups: Option<SchemaConflicts>,
|
pub conflicts: Option<SchemaConflicts>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
||||||
|
|
|
@ -393,10 +393,10 @@ impl Workspace {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the set of conflicts for the workspace.
|
/// Returns the set of conflicts for the workspace.
|
||||||
pub fn conflicting_groups(&self) -> Conflicts {
|
pub fn conflicts(&self) -> Conflicts {
|
||||||
let mut conflicting = Conflicts::empty();
|
let mut conflicting = Conflicts::empty();
|
||||||
for member in self.packages.values() {
|
for member in self.packages.values() {
|
||||||
conflicting.append(&mut member.pyproject_toml.conflicting_groups());
|
conflicting.append(&mut member.pyproject_toml.conflicts());
|
||||||
}
|
}
|
||||||
conflicting
|
conflicting
|
||||||
}
|
}
|
||||||
|
|
|
@ -242,7 +242,7 @@ async fn albatross_root_workspace() {
|
||||||
"override-dependencies": null,
|
"override-dependencies": null,
|
||||||
"constraint-dependencies": null,
|
"constraint-dependencies": null,
|
||||||
"environments": null,
|
"environments": null,
|
||||||
"conflicting-groups": null
|
"conflicts": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependency-groups": null
|
"dependency-groups": null
|
||||||
|
@ -334,7 +334,7 @@ async fn albatross_virtual_workspace() {
|
||||||
"override-dependencies": null,
|
"override-dependencies": null,
|
||||||
"constraint-dependencies": null,
|
"constraint-dependencies": null,
|
||||||
"environments": null,
|
"environments": null,
|
||||||
"conflicting-groups": null
|
"conflicts": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependency-groups": null
|
"dependency-groups": null
|
||||||
|
@ -540,7 +540,7 @@ async fn exclude_package() -> Result<()> {
|
||||||
"override-dependencies": null,
|
"override-dependencies": null,
|
||||||
"constraint-dependencies": null,
|
"constraint-dependencies": null,
|
||||||
"environments": null,
|
"environments": null,
|
||||||
"conflicting-groups": null
|
"conflicts": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependency-groups": null
|
"dependency-groups": null
|
||||||
|
@ -644,7 +644,7 @@ async fn exclude_package() -> Result<()> {
|
||||||
"override-dependencies": null,
|
"override-dependencies": null,
|
||||||
"constraint-dependencies": null,
|
"constraint-dependencies": null,
|
||||||
"environments": null,
|
"environments": null,
|
||||||
"conflicting-groups": null
|
"conflicts": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependency-groups": null
|
"dependency-groups": null
|
||||||
|
@ -761,7 +761,7 @@ async fn exclude_package() -> Result<()> {
|
||||||
"override-dependencies": null,
|
"override-dependencies": null,
|
||||||
"constraint-dependencies": null,
|
"constraint-dependencies": null,
|
||||||
"environments": null,
|
"environments": null,
|
||||||
"conflicting-groups": null
|
"conflicts": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependency-groups": null
|
"dependency-groups": null
|
||||||
|
@ -852,7 +852,7 @@ async fn exclude_package() -> Result<()> {
|
||||||
"override-dependencies": null,
|
"override-dependencies": null,
|
||||||
"constraint-dependencies": null,
|
"constraint-dependencies": null,
|
||||||
"environments": null,
|
"environments": null,
|
||||||
"conflicting-groups": null
|
"conflicts": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependency-groups": null
|
"dependency-groups": null
|
||||||
|
|
|
@ -54,7 +54,7 @@ pub(crate) async fn pip_compile(
|
||||||
constraints_from_workspace: Vec<Requirement>,
|
constraints_from_workspace: Vec<Requirement>,
|
||||||
overrides_from_workspace: Vec<Requirement>,
|
overrides_from_workspace: Vec<Requirement>,
|
||||||
environments: SupportedEnvironments,
|
environments: SupportedEnvironments,
|
||||||
conflicting_groups: Conflicts,
|
conflicts: Conflicts,
|
||||||
extras: ExtrasSpecification,
|
extras: ExtrasSpecification,
|
||||||
output_file: Option<&Path>,
|
output_file: Option<&Path>,
|
||||||
resolution_mode: ResolutionMode,
|
resolution_mode: ResolutionMode,
|
||||||
|
@ -256,7 +256,7 @@ pub(crate) async fn pip_compile(
|
||||||
(
|
(
|
||||||
None,
|
None,
|
||||||
ResolverEnvironment::universal(environments.into_markers()),
|
ResolverEnvironment::universal(environments.into_markers()),
|
||||||
conflicting_groups,
|
conflicts,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let (tags, marker_env) =
|
let (tags, marker_env) =
|
||||||
|
|
|
@ -104,7 +104,7 @@ pub(crate) async fn resolve<InstalledPackages: InstalledPackagesProvider>(
|
||||||
tags: Option<&Tags>,
|
tags: Option<&Tags>,
|
||||||
resolver_env: ResolverEnvironment,
|
resolver_env: ResolverEnvironment,
|
||||||
python_requirement: PythonRequirement,
|
python_requirement: PythonRequirement,
|
||||||
conflicting_groups: Conflicts,
|
conflicts: Conflicts,
|
||||||
client: &RegistryClient,
|
client: &RegistryClient,
|
||||||
flat_index: &FlatIndex,
|
flat_index: &FlatIndex,
|
||||||
index: &InMemoryIndex,
|
index: &InMemoryIndex,
|
||||||
|
@ -291,7 +291,7 @@ pub(crate) async fn resolve<InstalledPackages: InstalledPackagesProvider>(
|
||||||
options,
|
options,
|
||||||
&python_requirement,
|
&python_requirement,
|
||||||
resolver_env,
|
resolver_env,
|
||||||
conflicting_groups,
|
conflicts,
|
||||||
tags,
|
tags,
|
||||||
flat_index,
|
flat_index,
|
||||||
index,
|
index,
|
||||||
|
|
|
@ -631,7 +631,7 @@ async fn do_lock(
|
||||||
None,
|
None,
|
||||||
resolver_env,
|
resolver_env,
|
||||||
python_requirement,
|
python_requirement,
|
||||||
workspace.conflicting_groups(),
|
workspace.conflicts(),
|
||||||
&client,
|
&client,
|
||||||
&flat_index,
|
&flat_index,
|
||||||
&state.index,
|
&state.index,
|
||||||
|
@ -661,7 +661,7 @@ async fn do_lock(
|
||||||
let previous = existing_lock.map(ValidatedLock::into_lock);
|
let previous = existing_lock.map(ValidatedLock::into_lock);
|
||||||
let lock = Lock::from_resolution_graph(&resolution, workspace.install_path())?
|
let lock = Lock::from_resolution_graph(&resolution, workspace.install_path())?
|
||||||
.with_manifest(manifest)
|
.with_manifest(manifest)
|
||||||
.with_conflicting_groups(workspace.conflicting_groups())
|
.with_conflicts(workspace.conflicts())
|
||||||
.with_supported_environments(
|
.with_supported_environments(
|
||||||
environments
|
environments
|
||||||
.cloned()
|
.cloned()
|
||||||
|
@ -806,11 +806,11 @@ impl ValidatedLock {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the conflicting group config has changed, we have to perform a clean resolution.
|
// If the conflicting group config has changed, we have to perform a clean resolution.
|
||||||
if &workspace.conflicting_groups() != lock.conflicting_groups() {
|
if &workspace.conflicts() != lock.conflicts() {
|
||||||
debug!(
|
debug!(
|
||||||
"Ignoring existing lockfile due to change in conflicting groups: `{:?}` vs. `{:?}`",
|
"Ignoring existing lockfile due to change in conflicting groups: `{:?}` vs. `{:?}`",
|
||||||
workspace.conflicting_groups(),
|
workspace.conflicts(),
|
||||||
lock.conflicting_groups(),
|
lock.conflicts(),
|
||||||
);
|
);
|
||||||
return Ok(Self::Versions(lock));
|
return Ok(Self::Versions(lock));
|
||||||
}
|
}
|
||||||
|
|
|
@ -283,18 +283,15 @@ pub(super) async fn do_sync(
|
||||||
|
|
||||||
// Validate that we aren't trying to install extras that are
|
// Validate that we aren't trying to install extras that are
|
||||||
// declared as conflicting.
|
// declared as conflicting.
|
||||||
let conflicting_groups = target.lock().conflicting_groups();
|
let conflicts = target.lock().conflicts();
|
||||||
for groups in conflicting_groups.iter() {
|
for set in conflicts.iter() {
|
||||||
let conflicting = groups
|
let conflicting = set
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|group| extras.contains(group.extra()))
|
.filter(|item| extras.contains(item.extra()))
|
||||||
.map(|group| group.extra().clone())
|
.map(|item| item.extra().clone())
|
||||||
.collect::<Vec<ExtraName>>();
|
.collect::<Vec<ExtraName>>();
|
||||||
if conflicting.len() >= 2 {
|
if conflicting.len() >= 2 {
|
||||||
return Err(ProjectError::ExtraIncompatibility(
|
return Err(ProjectError::ExtraIncompatibility(set.clone(), conflicting));
|
||||||
groups.clone(),
|
|
||||||
conflicting,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2220,7 +2220,7 @@ fn lock_conflicting_extra_basic() -> Result<()> {
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
|
||||||
[tool.uv]
|
[tool.uv]
|
||||||
conflicting-groups = [
|
conflicts = [
|
||||||
[
|
[
|
||||||
{ extra = "project1" },
|
{ extra = "project1" },
|
||||||
{ extra = "project2" },
|
{ extra = "project2" },
|
||||||
|
@ -2257,7 +2257,7 @@ fn lock_conflicting_extra_basic() -> Result<()> {
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
resolution-markers = [
|
resolution-markers = [
|
||||||
]
|
]
|
||||||
conflicting-groups = [[
|
conflicts = [[
|
||||||
{ package = "project", extra = "project1" },
|
{ package = "project", extra = "project1" },
|
||||||
{ package = "project", extra = "project2" },
|
{ package = "project", extra = "project2" },
|
||||||
]]
|
]]
|
||||||
|
@ -2417,7 +2417,7 @@ fn lock_conflicting_extra_basic_three_extras() -> Result<()> {
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
|
||||||
[tool.uv]
|
[tool.uv]
|
||||||
conflicting-groups = [
|
conflicts = [
|
||||||
[
|
[
|
||||||
{ extra = "project1" },
|
{ extra = "project1" },
|
||||||
{ extra = "project2" },
|
{ extra = "project2" },
|
||||||
|
@ -2456,7 +2456,7 @@ fn lock_conflicting_extra_basic_three_extras() -> Result<()> {
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
resolution-markers = [
|
resolution-markers = [
|
||||||
]
|
]
|
||||||
conflicting-groups = [[
|
conflicts = [[
|
||||||
{ package = "project", extra = "project1" },
|
{ package = "project", extra = "project1" },
|
||||||
{ package = "project", extra = "project2" },
|
{ package = "project", extra = "project2" },
|
||||||
{ package = "project", extra = "project3" },
|
{ package = "project", extra = "project3" },
|
||||||
|
@ -2542,7 +2542,7 @@ fn lock_conflicting_extra_multiple_not_conflicting1() -> Result<()> {
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
|
||||||
[tool.uv]
|
[tool.uv]
|
||||||
conflicting-groups = [
|
conflicts = [
|
||||||
[
|
[
|
||||||
{ extra = "project1" },
|
{ extra = "project1" },
|
||||||
{ extra = "project2" },
|
{ extra = "project2" },
|
||||||
|
@ -2712,7 +2712,7 @@ fn lock_conflicting_extra_multiple_not_conflicting2() -> Result<()> {
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
|
||||||
[tool.uv]
|
[tool.uv]
|
||||||
conflicting-groups = [
|
conflicts = [
|
||||||
[
|
[
|
||||||
{ extra = "project1" },
|
{ extra = "project1" },
|
||||||
{ extra = "project2" },
|
{ extra = "project2" },
|
||||||
|
@ -2758,7 +2758,7 @@ fn lock_conflicting_extra_multiple_not_conflicting2() -> Result<()> {
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
|
||||||
[tool.uv]
|
[tool.uv]
|
||||||
conflicting-groups = [
|
conflicts = [
|
||||||
[
|
[
|
||||||
{ extra = "project1" },
|
{ extra = "project1" },
|
||||||
{ extra = "project2" },
|
{ extra = "project2" },
|
||||||
|
@ -2808,7 +2808,7 @@ fn lock_conflicting_extra_multiple_not_conflicting2() -> Result<()> {
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
|
||||||
[tool.uv]
|
[tool.uv]
|
||||||
conflicting-groups = [
|
conflicts = [
|
||||||
[
|
[
|
||||||
{ extra = "project1" },
|
{ extra = "project1" },
|
||||||
{ extra = "project2" },
|
{ extra = "project2" },
|
||||||
|
@ -2889,7 +2889,7 @@ fn lock_conflicting_extra_multiple_independent() -> Result<()> {
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
|
||||||
[tool.uv]
|
[tool.uv]
|
||||||
conflicting-groups = [
|
conflicts = [
|
||||||
[
|
[
|
||||||
{ extra = "project3" },
|
{ extra = "project3" },
|
||||||
{ extra = "project4" },
|
{ extra = "project4" },
|
||||||
|
@ -2928,7 +2928,7 @@ fn lock_conflicting_extra_multiple_independent() -> Result<()> {
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
|
||||||
[tool.uv]
|
[tool.uv]
|
||||||
conflicting-groups = [
|
conflicts = [
|
||||||
[
|
[
|
||||||
{ extra = "project1" },
|
{ extra = "project1" },
|
||||||
{ extra = "project2" },
|
{ extra = "project2" },
|
||||||
|
@ -2971,7 +2971,7 @@ fn lock_conflicting_extra_multiple_independent() -> Result<()> {
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
resolution-markers = [
|
resolution-markers = [
|
||||||
]
|
]
|
||||||
conflicting-groups = [[
|
conflicts = [[
|
||||||
{ package = "project", extra = "project1" },
|
{ package = "project", extra = "project1" },
|
||||||
{ package = "project", extra = "project2" },
|
{ package = "project", extra = "project2" },
|
||||||
], [
|
], [
|
||||||
|
@ -3098,7 +3098,7 @@ fn lock_conflicting_extra_config_change_ignore_lockfile() -> Result<()> {
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
|
||||||
[tool.uv]
|
[tool.uv]
|
||||||
conflicting-groups = [
|
conflicts = [
|
||||||
[
|
[
|
||||||
{ extra = "project1" },
|
{ extra = "project1" },
|
||||||
{ extra = "project2" },
|
{ extra = "project2" },
|
||||||
|
@ -3133,7 +3133,7 @@ fn lock_conflicting_extra_config_change_ignore_lockfile() -> Result<()> {
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
resolution-markers = [
|
resolution-markers = [
|
||||||
]
|
]
|
||||||
conflicting-groups = [[
|
conflicts = [[
|
||||||
{ package = "project", extra = "project1" },
|
{ package = "project", extra = "project1" },
|
||||||
{ package = "project", extra = "project2" },
|
{ package = "project", extra = "project2" },
|
||||||
]]
|
]]
|
||||||
|
@ -3272,7 +3272,7 @@ fn lock_conflicting_extra_unconditional() -> Result<()> {
|
||||||
project2 = ["anyio==4.2.0"]
|
project2 = ["anyio==4.2.0"]
|
||||||
|
|
||||||
[tool.uv]
|
[tool.uv]
|
||||||
conflicting-groups = [
|
conflicts = [
|
||||||
[
|
[
|
||||||
{ extra = "project1" },
|
{ extra = "project1" },
|
||||||
{ extra = "project2" },
|
{ extra = "project2" },
|
||||||
|
|
|
@ -191,7 +191,7 @@ fn invalid_pyproject_toml_option_unknown_field() -> Result<()> {
|
||||||
|
|
|
|
||||||
2 | unknown = "field"
|
2 | unknown = "field"
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
unknown field `unknown`, expected one of `native-tls`, `offline`, `no-cache`, `cache-dir`, `preview`, `python-preference`, `python-downloads`, `concurrent-downloads`, `concurrent-builds`, `concurrent-installs`, `index`, `index-url`, `extra-index-url`, `no-index`, `find-links`, `index-strategy`, `keyring-provider`, `allow-insecure-host`, `resolution`, `prerelease`, `dependency-metadata`, `config-settings`, `no-build-isolation`, `no-build-isolation-package`, `exclude-newer`, `link-mode`, `compile-bytecode`, `no-sources`, `upgrade`, `upgrade-package`, `reinstall`, `reinstall-package`, `no-build`, `no-build-package`, `no-binary`, `no-binary-package`, `python-install-mirror`, `pypy-install-mirror`, `publish-url`, `trusted-publishing`, `pip`, `cache-keys`, `override-dependencies`, `constraint-dependencies`, `environments`, `conflicting-groups`, `workspace`, `sources`, `managed`, `package`, `default-groups`, `dev-dependencies`
|
unknown field `unknown`, expected one of `native-tls`, `offline`, `no-cache`, `cache-dir`, `preview`, `python-preference`, `python-downloads`, `concurrent-downloads`, `concurrent-builds`, `concurrent-installs`, `index`, `index-url`, `extra-index-url`, `no-index`, `find-links`, `index-strategy`, `keyring-provider`, `allow-insecure-host`, `resolution`, `prerelease`, `dependency-metadata`, `config-settings`, `no-build-isolation`, `no-build-isolation-package`, `exclude-newer`, `link-mode`, `compile-bytecode`, `no-sources`, `upgrade`, `upgrade-package`, `reinstall`, `reinstall-package`, `no-build`, `no-build-package`, `no-binary`, `no-binary-package`, `python-install-mirror`, `pypy-install-mirror`, `publish-url`, `trusted-publishing`, `pip`, `cache-keys`, `override-dependencies`, `constraint-dependencies`, `environments`, `conflicts`, `workspace`, `sources`, `managed`, `package`, `default-groups`, `dev-dependencies`
|
||||||
|
|
||||||
Resolved in [TIME]
|
Resolved in [TIME]
|
||||||
Audited in [TIME]
|
Audited in [TIME]
|
||||||
|
@ -7289,7 +7289,7 @@ fn sklearn() {
|
||||||
let filters = std::iter::once((r"exit code: 1", "exit status: 1"))
|
let filters = std::iter::once((r"exit code: 1", "exit status: 1"))
|
||||||
.chain(context.filters())
|
.chain(context.filters())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
uv_snapshot!(filters, context.pip_install().arg("sklearn"), @r#"
|
uv_snapshot!(filters, context.pip_install().arg("sklearn"), @r###"
|
||||||
success: false
|
success: false
|
||||||
exit_code: 1
|
exit_code: 1
|
||||||
----- stdout -----
|
----- stdout -----
|
||||||
|
@ -7316,6 +7316,6 @@ fn sklearn() {
|
||||||
https://github.com/scikit-learn/sklearn-pypi-package
|
https://github.com/scikit-learn/sklearn-pypi-package
|
||||||
|
|
||||||
help: `sklearn` is often confused for `scikit-learn` Did you mean to install `scikit-learn` instead?
|
help: `sklearn` is often confused for `scikit-learn` Did you mean to install `scikit-learn` instead?
|
||||||
"#
|
"###
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3107,9 +3107,9 @@ fn resolve_both() -> anyhow::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tests that errors when parsing `conflicting-groups` are reported.
|
/// Tests that errors when parsing `conflicts` are reported.
|
||||||
#[test]
|
#[test]
|
||||||
fn invalid_conflicting_groups() -> anyhow::Result<()> {
|
fn invalid_conflicts() -> anyhow::Result<()> {
|
||||||
let context = TestContext::new("3.12");
|
let context = TestContext::new("3.12");
|
||||||
let pyproject = context.temp_dir.child("pyproject.toml");
|
let pyproject = context.temp_dir.child("pyproject.toml");
|
||||||
|
|
||||||
|
@ -3121,7 +3121,7 @@ fn invalid_conflicting_groups() -> anyhow::Result<()> {
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
|
||||||
[tool.uv]
|
[tool.uv]
|
||||||
conflicting-groups = [
|
conflicts = [
|
||||||
[{extra = "dev"}],
|
[{extra = "dev"}],
|
||||||
]
|
]
|
||||||
"#})?;
|
"#})?;
|
||||||
|
@ -3134,11 +3134,11 @@ fn invalid_conflicting_groups() -> anyhow::Result<()> {
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
error: Failed to parse: `pyproject.toml`
|
error: Failed to parse: `pyproject.toml`
|
||||||
Caused by: TOML parse error at line 7, column 22
|
Caused by: TOML parse error at line 7, column 13
|
||||||
|
|
|
|
||||||
7 | conflicting-groups = [
|
7 | conflicts = [
|
||||||
| ^
|
| ^
|
||||||
Each set of conflicting groups must have at least two entries, but found only one
|
Each set of conflicts must have at least two entries, but found only one
|
||||||
"###
|
"###
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -3150,7 +3150,7 @@ fn invalid_conflicting_groups() -> anyhow::Result<()> {
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
|
||||||
[tool.uv]
|
[tool.uv]
|
||||||
conflicting-groups = [[]]
|
conflicts = [[]]
|
||||||
"#})?;
|
"#})?;
|
||||||
|
|
||||||
// The file should be rejected for violating the schema.
|
// The file should be rejected for violating the schema.
|
||||||
|
@ -3161,20 +3161,20 @@ fn invalid_conflicting_groups() -> anyhow::Result<()> {
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
error: Failed to parse: `pyproject.toml`
|
error: Failed to parse: `pyproject.toml`
|
||||||
Caused by: TOML parse error at line 7, column 22
|
Caused by: TOML parse error at line 7, column 13
|
||||||
|
|
|
|
||||||
7 | conflicting-groups = [[]]
|
7 | conflicts = [[]]
|
||||||
| ^^^^
|
| ^^^^
|
||||||
Each set of conflicting groups must have at least two entries, but found none
|
Each set of conflicts must have at least two entries, but found none
|
||||||
"###
|
"###
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tests that valid `conflicting-groups` are parsed okay.
|
/// Tests that valid `conflicts` are parsed okay.
|
||||||
#[test]
|
#[test]
|
||||||
fn valid_conflicting_groups() -> anyhow::Result<()> {
|
fn valid_conflicts() -> anyhow::Result<()> {
|
||||||
let context = TestContext::new("3.12");
|
let context = TestContext::new("3.12");
|
||||||
let pyproject = context.temp_dir.child("pyproject.toml");
|
let pyproject = context.temp_dir.child("pyproject.toml");
|
||||||
|
|
||||||
|
@ -3186,7 +3186,7 @@ fn valid_conflicting_groups() -> anyhow::Result<()> {
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
|
|
||||||
[tool.uv]
|
[tool.uv]
|
||||||
conflicting-groups = [
|
conflicts = [
|
||||||
[{extra = "x1"}, {extra = "x2"}],
|
[{extra = "x1"}, {extra = "x2"}],
|
||||||
]
|
]
|
||||||
"#})?;
|
"#})?;
|
||||||
|
@ -3405,7 +3405,7 @@ fn resolve_config_file() -> anyhow::Result<()> {
|
||||||
|
|
|
|
||||||
1 | [project]
|
1 | [project]
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
unknown field `project`, expected one of `native-tls`, `offline`, `no-cache`, `cache-dir`, `preview`, `python-preference`, `python-downloads`, `concurrent-downloads`, `concurrent-builds`, `concurrent-installs`, `index`, `index-url`, `extra-index-url`, `no-index`, `find-links`, `index-strategy`, `keyring-provider`, `allow-insecure-host`, `resolution`, `prerelease`, `dependency-metadata`, `config-settings`, `no-build-isolation`, `no-build-isolation-package`, `exclude-newer`, `link-mode`, `compile-bytecode`, `no-sources`, `upgrade`, `upgrade-package`, `reinstall`, `reinstall-package`, `no-build`, `no-build-package`, `no-binary`, `no-binary-package`, `python-install-mirror`, `pypy-install-mirror`, `publish-url`, `trusted-publishing`, `pip`, `cache-keys`, `override-dependencies`, `constraint-dependencies`, `environments`, `conflicting-groups`, `workspace`, `sources`, `managed`, `package`, `default-groups`, `dev-dependencies`
|
unknown field `project`, expected one of `native-tls`, `offline`, `no-cache`, `cache-dir`, `preview`, `python-preference`, `python-downloads`, `concurrent-downloads`, `concurrent-builds`, `concurrent-installs`, `index`, `index-url`, `extra-index-url`, `no-index`, `find-links`, `index-strategy`, `keyring-provider`, `allow-insecure-host`, `resolution`, `prerelease`, `dependency-metadata`, `config-settings`, `no-build-isolation`, `no-build-isolation-package`, `exclude-newer`, `link-mode`, `compile-bytecode`, `no-sources`, `upgrade`, `upgrade-package`, `reinstall`, `reinstall-package`, `no-build`, `no-build-package`, `no-binary`, `no-binary-package`, `python-install-mirror`, `pypy-install-mirror`, `publish-url`, `trusted-publishing`, `pip`, `cache-keys`, `override-dependencies`, `constraint-dependencies`, `environments`, `conflicts`, `workspace`, `sources`, `managed`, `package`, `default-groups`, `dev-dependencies`
|
||||||
"###
|
"###
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue