From b7968e778942af16009086f41e1ea5567e03d54c Mon Sep 17 00:00:00 2001 From: John Mumm Date: Sat, 8 Mar 2025 19:21:25 +0100 Subject: [PATCH] Conflicting groups should handle conflicting inclusions automatically (#12005) This adds support for inferring dependency group conflict sets from the directly defined conflicts in configuration. For example, if you declare a conflict between groups `alpha` and `beta` and `dev` includes `beta`, then we will infer a conflict between `dev` and `alpha`. We will also handle a conflict between two groups if they transitively include groups that conflict with each other. See #11232 for more details. Closes #11232 --- Cargo.lock | 2 + crates/uv-pypi-types/Cargo.toml | 2 + crates/uv-pypi-types/src/conflicts.rs | 227 ++++++++++++++- crates/uv/src/commands/project/lock.rs | 13 +- crates/uv/src/commands/project/mod.rs | 7 +- crates/uv/tests/it/lock_conflict.rs | 257 ++++++++--------- crates/uv/tests/it/sync.rs | 372 ++++++++++++++++++++++++- 7 files changed, 712 insertions(+), 168 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f738bb09..4db672fa7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5391,8 +5391,10 @@ dependencies = [ "itertools 0.14.0", "jiff", "mailparse", + "petgraph", "regex", "rkyv", + "rustc-hash", "schemars", "serde", "serde-untagged", diff --git a/crates/uv-pypi-types/Cargo.toml b/crates/uv-pypi-types/Cargo.toml index db515b86a..4261fe720 100644 --- a/crates/uv-pypi-types/Cargo.toml +++ b/crates/uv-pypi-types/Cargo.toml @@ -29,8 +29,10 @@ indexmap = { workspace = true, features = ["serde"] } itertools = { workspace = true } jiff = { workspace = true, features = ["serde"] } mailparse = { workspace = true } +petgraph = { workspace = true } regex = { workspace = true } rkyv = { workspace = true } +rustc-hash = { workspace = true } schemars = { workspace = true, optional = true } serde = { workspace = true } serde-untagged = { workspace = true } diff --git a/crates/uv-pypi-types/src/conflicts.rs b/crates/uv-pypi-types/src/conflicts.rs index 937fb211a..4c65eb1b6 100644 --- a/crates/uv-pypi-types/src/conflicts.rs +++ b/crates/uv-pypi-types/src/conflicts.rs @@ -1,11 +1,19 @@ +use petgraph::{ + algo::toposort, + graph::{DiGraph, NodeIndex}, +}; +use rustc_hash::{FxHashMap, FxHashSet}; +use std::{collections::BTreeSet, hash::Hash, rc::Rc}; use uv_normalize::{ExtraName, GroupName, PackageName}; +use crate::dependency_groups::{DependencyGroupSpecifier, DependencyGroups}; + /// 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 /// unavoidable conflicts with each other. (The alternative is that resolution /// will fail.) -#[derive(Debug, Default, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] +#[derive(Debug, Default, Clone, Eq, PartialEq, serde::Deserialize)] pub struct Conflicts(Vec); impl Conflicts { @@ -47,6 +55,157 @@ impl Conflicts { pub fn append(&mut self, other: &mut Conflicts) { self.0.append(&mut other.0); } + + /// Expand [`Conflicts`]s to include all [`ConflictSet`]s that can + /// be transitively inferred from group conflicts directly defined + /// in configuration. + /// + /// A directed acyclic graph (DAG) is created representing all + /// transitive group includes, with nodes corresponding to group conflict + /// items. For every conflict item directly mentioned in configuration, + /// its node starts with a set of canonical items with itself as the only + /// member. + /// + /// The graph is traversed one node at a time in topological order and + /// canonical items are propagated to each neighbor. We also update our + /// substitutions at each neighbor to reflect that this neighbor transitively + /// includes all canonical items visited so far to reach it. + /// + /// Finally, we apply the substitutions to the conflict sets that were + /// directly defined in configuration to generate all transitively inferable + /// [`ConflictSet`]s. + /// + /// There is an assumption that inclusion graphs will not be very large + /// or complex. This algorithm creates all combinations of substitutions. + /// Each resulting [`ConflictSet`] would also later correspond to a separate + /// resolver fork during resolution. + pub fn expand_transitive_group_includes( + &mut self, + package: &PackageName, + groups: &DependencyGroups, + ) { + let mut graph = DiGraph::new(); + let mut group_node_idxs: FxHashMap<&GroupName, NodeIndex> = FxHashMap::default(); + let mut node_conflict_items: FxHashMap> = FxHashMap::default(); + // Used for transitively deriving new conflict sets with substitutions. + // The keys are canonical items (mentioned directly in configured conflicts). + // The values correspond to groups that transitively include them. + let mut substitutions: FxHashMap, FxHashSet>> = + FxHashMap::default(); + + // Conflict sets that were directly defined in configuration. + let mut direct_conflict_sets: FxHashSet<&ConflictSet> = FxHashSet::default(); + // Conflict sets that we will transitively infer in this method. + let mut transitive_conflict_sets: FxHashSet = FxHashSet::default(); + + // Add groups in directly defined conflict sets to the graph. + let mut seen: FxHashSet<&GroupName> = FxHashSet::default(); + + for set in &self.0 { + direct_conflict_sets.insert(set); + for item in set.iter() { + let ConflictPackage::Group(group) = &item.conflict else { + // TODO(john): Do we also want to handle extras here? + continue; + }; + if !seen.insert(group) { + continue; + } + let item = Rc::new(item.clone()); + let mut canonical_items = FxHashSet::default(); + canonical_items.insert(item.clone()); + let node_id = graph.add_node(canonical_items); + group_node_idxs.insert(group, node_id); + node_conflict_items.insert(node_id, item.clone()); + } + } + + // Create conflict items for remaining groups and add them to the graph. + for group in groups.keys() { + if !seen.insert(group) { + continue; + } + let group_conflict_item = ConflictItem { + package: package.clone(), + conflict: ConflictPackage::Group(group.clone()), + }; + let node_id = graph.add_node(FxHashSet::default()); + group_node_idxs.insert(group, node_id); + node_conflict_items.insert(node_id, Rc::new(group_conflict_item)); + } + + // Create edges representing group inclusion (with edges reversed so that + // included groups point to including groups). + for (group, specifiers) in groups { + if let Some(includer) = group_node_idxs.get(group) { + for specifier in specifiers { + if let DependencyGroupSpecifier::IncludeGroup { include_group } = specifier { + if let Some(included) = group_node_idxs.get(include_group) { + graph.add_edge(*included, *includer, ()); + } + } + } + } + } + + let Ok(topo_nodes) = toposort(&graph, None) else { + // FIXME: If we hit a cycle, we are currently bailing and waiting for + // more detailed cycle detection downstream. Is this what we want? + return; + }; + // Propagate canonical items through the graph and populate substitutions. + for node in topo_nodes { + for neighbor_idx in graph.neighbors(node).collect::>() { + let mut neighbor_canonical_items = Vec::new(); + if let Some(canonical_items) = graph.node_weight(node) { + let neighbor_item = node_conflict_items + .get(&neighbor_idx) + .expect("ConflictItem should already be in graph") + .clone(); + for canonical_item in canonical_items { + neighbor_canonical_items.push(canonical_item.clone()); + substitutions + .entry(canonical_item.clone()) + .or_default() + .insert(neighbor_item.clone()); + } + } + graph + .node_weight_mut(neighbor_idx) + .expect("Graph node should have weight") + .extend(neighbor_canonical_items.into_iter()); + } + } + + // Create new conflict sets for all possible replacements of canonical + // items by substitution items. + // Note that new sets are (potentially) added to transitive_conflict_sets + // at the end of each iteration. + for (canonical_item, subs) in substitutions { + let mut new_conflict_sets = FxHashSet::default(); + for conflict_set in direct_conflict_sets + .iter() + .copied() + .chain(transitive_conflict_sets.iter()) + .filter(|set| set.contains_item(&canonical_item)) + { + for sub in &subs { + let mut new_set = conflict_set + .replaced_item(&canonical_item, (**sub).clone()) + .expect("`ConflictItem` should be in `ConflictSet`"); + if !direct_conflict_sets.contains(&new_set) { + new_set = new_set.with_inferred_conflict(); + if !transitive_conflict_sets.contains(&new_set) { + new_conflict_sets.insert(new_set); + } + } + } + } + transitive_conflict_sets.extend(new_conflict_sets.into_iter()); + } + + self.0.extend(transitive_conflict_sets); + } } /// A single set of package-extra pairs that conflict with one another. @@ -58,23 +217,24 @@ impl Conflicts { /// /// A `TryFrom>` impl may be used to build a set from a /// sequence. Note though that at least 2 items are required. -#[derive(Debug, Default, Clone, Eq, PartialEq, serde::Serialize)] -pub struct ConflictSet(Vec); +#[derive(Debug, Default, Clone, Hash, Eq, PartialEq)] +pub struct ConflictSet { + set: BTreeSet, + is_inferred_conflict: bool, +} impl ConflictSet { /// Create a pair of items that conflict with one another. pub fn pair(item1: ConflictItem, item2: ConflictItem) -> ConflictSet { - ConflictSet(vec![item1, item2]) - } - - /// Add a new conflicting item to this set. - pub fn push(&mut self, item: ConflictItem) { - self.0.push(item); + ConflictSet { + set: BTreeSet::from_iter(vec![item1, item2]), + is_inferred_conflict: false, + } } /// Returns an iterator over all conflicting items. pub fn iter(&self) -> impl Iterator + Clone + '_ { - self.0.iter() + self.set.iter() } /// Returns true if this conflicting item contains the given package and @@ -88,6 +248,42 @@ impl ConflictSet { self.iter() .any(|set| set.package() == package && *set.conflict() == conflict) } + + /// Returns true if these conflicts contain any set that contains the given + /// [`ConflictItem`]. + pub fn contains_item(&self, conflict_item: &ConflictItem) -> bool { + self.set.contains(conflict_item) + } + + /// This [`ConflictSet`] was inferred from directly defined conflicts. + pub fn is_inferred_conflict(&self) -> bool { + self.is_inferred_conflict + } + + /// Replace an old [`ConflictItem`] with a new one. + pub fn replaced_item( + &self, + old: &ConflictItem, + new: ConflictItem, + ) -> Result { + let mut new_set = self.set.clone(); + if !new_set.contains(old) { + return Err(ConflictError::ReplaceMissingConflictItem); + } + new_set.remove(old); + new_set.insert(new); + Ok(Self { + set: new_set, + is_inferred_conflict: false, + }) + } + + /// Mark this [`ConflictSet`] as being inferred from directly + /// defined conflicts. + fn with_inferred_conflict(mut self) -> Self { + self.is_inferred_conflict = true; + self + } } impl<'de> serde::Deserialize<'de> for ConflictSet { @@ -109,14 +305,17 @@ impl TryFrom> for ConflictSet { 1 => return Err(ConflictError::OneItem), _ => {} } - Ok(ConflictSet(items)) + Ok(ConflictSet { + set: BTreeSet::from_iter(items), + is_inferred_conflict: false, + }) } } /// A single item in a conflicting set. /// -/// Each item is a pair of a package and a corresponding extra name for that -/// package. +/// Each item is a pair of a package and a corresponding extra or group name +/// for that package. #[derive( Debug, Clone, Eq, Hash, PartialEq, PartialOrd, Ord, serde::Deserialize, serde::Serialize, )] @@ -364,6 +563,8 @@ pub enum ConflictError { /// An error that occurs when both `extra` and `group` are present. #[error("Expected one of `extra` or `group` in conflicting entry, but found both")] FoundExtraAndGroup, + #[error("Expected `ConflictSet` to contain `ConflictItem` to replace")] + ReplaceMissingConflictItem, } /// Like [`Conflicts`], but for deserialization in `pyproject.toml`. diff --git a/crates/uv/src/commands/project/lock.rs b/crates/uv/src/commands/project/lock.rs index af6933781..231614f9e 100644 --- a/crates/uv/src/commands/project/lock.rs +++ b/crates/uv/src/commands/project/lock.rs @@ -396,7 +396,14 @@ async fn do_lock( .collect::, ProjectError>>()?; // Collect the conflicts. - let conflicts = target.conflicts(); + let mut conflicts = target.conflicts(); + if let LockTarget::Workspace(workspace) = target { + if let Some(groups) = &workspace.pyproject_toml().dependency_groups { + if let Some(project) = &workspace.pyproject_toml().project { + conflicts.expand_transitive_group_includes(&project.name, groups); + } + } + } // Collect the list of supported environments. let environments = { @@ -756,7 +763,7 @@ async fn do_lock( None, resolver_env, python_requirement, - conflicts, + conflicts.clone(), &client, &flat_index, state.index(), @@ -787,7 +794,7 @@ async fn do_lock( let previous = existing_lock.map(ValidatedLock::into_lock); let lock = Lock::from_resolution(&resolution, target.install_path())? .with_manifest(manifest) - .with_conflicts(target.conflicts()) + .with_conflicts(conflicts) .with_supported_environments( environments .cloned() diff --git a/crates/uv/src/commands/project/mod.rs b/crates/uv/src/commands/project/mod.rs index 89d091614..32cb28ec2 100644 --- a/crates/uv/src/commands/project/mod.rs +++ b/crates/uv/src/commands/project/mod.rs @@ -300,9 +300,14 @@ impl std::fmt::Display for ConflictError { .iter() .all(|conflict| matches!(conflict, ConflictPackage::Group(..))) { + let conflict_source = if self.set.is_inferred_conflict() { + "transitively inferred" + } else { + "declared" + }; write!( f, - "Groups {} are incompatible with the declared conflicts: {{{set}}}", + "Groups {} are incompatible with the {conflict_source} conflicts: {{{set}}}", conjunction( self.conflicts .iter() diff --git a/crates/uv/tests/it/lock_conflict.rs b/crates/uv/tests/it/lock_conflict.rs index 80e1732d9..8b56c688a 100644 --- a/crates/uv/tests/it/lock_conflict.rs +++ b/crates/uv/tests/it/lock_conflict.rs @@ -2090,13 +2090,13 @@ fn mixed() -> Result<()> { filters => context.filters(), }, { assert_snapshot!( - lock, @r###" + lock, @r#" version = 1 revision = 1 requires-python = ">=3.12" conflicts = [[ - { package = "project", group = "group1" }, { package = "project", extra = "extra1" }, + { package = "project", group = "group1" }, ]] [options] @@ -2141,7 +2141,7 @@ fn mixed() -> Result<()> { wheels = [ { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575 }, ] - "### + "# ); }); @@ -2189,14 +2189,14 @@ fn mixed() -> Result<()> { + sortedcontainers==2.4.0 "###); // And finally, installing both the group and the extra should fail. - uv_snapshot!(context.filters(), context.sync().arg("--frozen").arg("--group=group1").arg("--extra=extra1"), @r###" + uv_snapshot!(context.filters(), context.sync().arg("--frozen").arg("--group=group1").arg("--extra=extra1"), @r" success: false exit_code: 2 ----- stdout ----- ----- stderr ----- - error: Group `group1` and extra `extra1` are incompatible with the declared conflicts: {`project:group1`, `project[extra1]`} - "###); + error: Extra `extra1` and group `group1` are incompatible with the declared conflicts: {`project[extra1]`, `project:group1`} + "); Ok(()) } @@ -3054,13 +3054,13 @@ fn shared_optional_dependency_extra1() -> Result<()> { filters => context.filters(), }, { assert_snapshot!( - lock, @r###" + lock, @r#" version = 1 revision = 1 requires-python = ">=3.12" conflicts = [[ - { package = "project", extra = "foo" }, { package = "project", extra = "bar" }, + { package = "project", extra = "foo" }, ]] [options] @@ -3130,7 +3130,7 @@ fn shared_optional_dependency_extra1() -> Result<()> { wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, ] - "### + "# ); }); @@ -3194,13 +3194,13 @@ fn shared_optional_dependency_group1() -> Result<()> { filters => context.filters(), }, { assert_snapshot!( - lock, @r###" + lock, @r#" version = 1 revision = 1 requires-python = ">=3.12" conflicts = [[ - { package = "project", group = "foo" }, { package = "project", group = "bar" }, + { package = "project", group = "foo" }, ]] [options] @@ -3269,7 +3269,7 @@ fn shared_optional_dependency_group1() -> Result<()> { wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, ] - "### + "# ); }); @@ -3480,13 +3480,13 @@ fn shared_optional_dependency_extra2() -> Result<()> { filters => context.filters(), }, { assert_snapshot!( - lock, @r###" + lock, @r#" version = 1 revision = 1 requires-python = "==3.11.*" conflicts = [[ - { package = "project", extra = "foo" }, { package = "project", extra = "bar" }, + { package = "project", extra = "foo" }, ]] [options] @@ -3556,7 +3556,7 @@ fn shared_optional_dependency_extra2() -> Result<()> { wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, ] - "### + "# ); }); @@ -3621,13 +3621,13 @@ fn shared_optional_dependency_group2() -> Result<()> { filters => context.filters(), }, { assert_snapshot!( - lock, @r###" + lock, @r#" version = 1 revision = 1 requires-python = "==3.11.*" conflicts = [[ - { package = "project", group = "foo" }, { package = "project", group = "bar" }, + { package = "project", group = "foo" }, ]] [options] @@ -3700,7 +3700,7 @@ fn shared_optional_dependency_group2() -> Result<()> { wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, ] - "### + "# ); }); @@ -3911,13 +3911,13 @@ fn shared_dependency_extra() -> Result<()> { filters => context.filters(), }, { assert_snapshot!( - lock, @r###" + lock, @r#" version = 1 revision = 1 requires-python = ">=3.12" conflicts = [[ - { package = "project", extra = "foo" }, { package = "project", extra = "bar" }, + { package = "project", extra = "foo" }, ]] [options] @@ -3987,7 +3987,7 @@ fn shared_dependency_extra() -> Result<()> { wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, ] - "### + "# ); }); @@ -4086,13 +4086,13 @@ fn shared_dependency_group() -> Result<()> { filters => context.filters(), }, { assert_snapshot!( - lock, @r###" + lock, @r#" version = 1 revision = 1 requires-python = ">=3.12" conflicts = [[ - { package = "project", group = "foo" }, { package = "project", group = "bar" }, + { package = "project", group = "foo" }, ]] [options] @@ -4161,7 +4161,7 @@ fn shared_dependency_group() -> Result<()> { wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, ] - "### + "# ); }); @@ -4988,13 +4988,13 @@ fn collision_extra() -> Result<()> { }, { assert_snapshot!( lock, - @r###" + @r#" version = 1 revision = 1 requires-python = ">=3.12" conflicts = [[ - { package = "pkg", extra = "foo" }, { package = "pkg", extra = "bar" }, + { package = "pkg", extra = "foo" }, ]] [options] @@ -5077,7 +5077,7 @@ fn collision_extra() -> Result<()> { wheels = [ { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575 }, ] - "### + "# ); }); @@ -10167,14 +10167,14 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { "#, )?; - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock(), @r" success: true exit_code: 0 ----- stdout ----- ----- stderr ----- - Resolved 133 packages in [TIME] - "###); + Resolved 132 packages in [TIME] + "); let lock = context.read("uv.lock"); insta::with_settings!({ @@ -10182,20 +10182,11 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { }, { assert_snapshot!( lock, - @r###" + @r#" version = 1 revision = 1 requires-python = ">=3.10" resolution-markers = [ - "python_full_version >= '3.12' and sys_platform == 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version >= '3.12' and sys_platform != 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and sys_platform != 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and sys_platform != 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version >= '3.12' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", "python_full_version >= '3.12' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", "python_full_version >= '3.12' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", "python_full_version == '3.11.*' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", @@ -10208,6 +10199,15 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { "python_full_version == '3.11.*' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", "python_full_version < '3.11' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version >= '3.12' and sys_platform == 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", + "python_full_version >= '3.12' and sys_platform != 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", + "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", + "python_full_version == '3.11.*' and sys_platform != 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", + "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", + "python_full_version < '3.11' and sys_platform != 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", + "python_full_version >= '3.12' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version == '3.11.*' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version < '3.11' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", "python_full_version >= '3.12' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", "python_full_version >= '3.12' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", "python_full_version == '3.11.*' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", @@ -10225,14 +10225,14 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { "python_full_version < '3.11' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", ] conflicts = [[ - { package = "test", extra = "chgnet" }, { package = "test", extra = "alignn" }, + { package = "test", extra = "chgnet" }, ], [ { package = "test", extra = "chgnet" }, { package = "test", extra = "m3gnet" }, ], [ - { package = "test", extra = "all" }, { package = "test", extra = "alignn" }, + { package = "test", extra = "all" }, ], [ { package = "test", extra = "all" }, { package = "test", extra = "m3gnet" }, @@ -10368,7 +10368,7 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { { name = "pydantic" }, { name = "pydantic-settings" }, { name = "pydocstyle" }, - { name = "pyparsing" }, + { name = "pyparsing", version = "2.4.7", source = { registry = "https://pypi.org/simple" } }, { name = "scikit-learn" }, { name = "scipy" }, { name = "spglib" }, @@ -10629,8 +10629,7 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { { name = "numpy" }, { name = "opt-einsum" }, { name = "scipy" }, - { name = "sympy", version = "1.13.1", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-all' or extra == 'extra-4-test-chgnet' or (extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet')" }, - { name = "sympy", version = "1.13.3", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-alignn' or extra == 'extra-4-test-m3gnet'" }, + { name = "sympy" }, ] sdist = { url = "https://files.pythonhosted.org/packages/70/91/c37b2ad1c8534b183eeacb97d2096f50cd2d0a180d1830f235c06aa94bbd/cuequivariance-0.2.0.tar.gz", hash = "sha256:e75999ef436f281e3f5cded9f1353055a599fedae55eea861bdc840cffaf63eb", size = 76738 } wheels = [ @@ -10733,8 +10732,7 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { dependencies = [ { name = "opt-einsum-fx" }, { name = "scipy" }, - { name = "sympy", version = "1.13.1", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-all' or extra == 'extra-4-test-chgnet' or (extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet')" }, - { name = "sympy", version = "1.13.3", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-alignn' or extra == 'extra-4-test-m3gnet'" }, + { name = "sympy" }, { name = "torch", version = "2.2.0", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-alignn' or extra == 'extra-4-test-m3gnet'" }, { name = "torch", version = "2.5.1", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-all' or extra == 'extra-4-test-chgnet' or (extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet')" }, ] @@ -11269,7 +11267,8 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { { name = "numpy" }, { name = "packaging" }, { name = "pillow" }, - { name = "pyparsing" }, + { name = "pyparsing", version = "2.4.7", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-alignn' or (extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet')" }, + { name = "pyparsing", version = "3.2.1", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-all' or extra == 'extra-4-test-chgnet' or extra != 'extra-4-test-alignn'" }, { name = "python-dateutil" }, ] sdist = { url = "https://files.pythonhosted.org/packages/68/dd/fa2e1a45fce2d09f4aea3cee169760e672c8262325aa5796c49d543dc7e6/matplotlib-3.10.0.tar.gz", hash = "sha256:b886d02a581b96704c9d1ffe55709e49b4d2d52709ccebc4be42db856e511278", size = 36686418 } @@ -11754,7 +11753,7 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { "python_full_version < '3.11' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", ] dependencies = [ - { name = "nvidia-nvjitlink-cu12", version = "12.4.127", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-all' or extra == 'extra-4-test-chgnet' or (extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet')" }, + { name = "nvidia-nvjitlink-cu12", marker = "extra == 'extra-4-test-all' or extra == 'extra-4-test-chgnet' or (extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet')" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/7a/8a/0e728f749baca3fbeffad762738276e5df60851958be7783af121a7221e7/nvidia_cufft_cu12-11.2.1.3-py3-none-manylinux2014_aarch64.whl", hash = "sha256:5dad8008fc7f92f5ddfa2101430917ce2ffacd86824914c82e28990ad7f00399", size = 211422548 }, @@ -11824,7 +11823,7 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { dependencies = [ { name = "nvidia-cublas-cu12", version = "12.1.3.1", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-alignn' or extra == 'extra-4-test-m3gnet'" }, { name = "nvidia-cusparse-cu12", version = "12.1.0.106", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-alignn' or extra == 'extra-4-test-m3gnet'" }, - { name = "nvidia-nvjitlink-cu12", version = "12.8.61", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-alignn' or extra == 'extra-4-test-m3gnet'" }, + { name = "nvidia-nvjitlink-cu12", marker = "extra == 'extra-4-test-alignn' or extra == 'extra-4-test-m3gnet'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/bc/1d/8de1e5c67099015c834315e333911273a8c6aaba78923dd1d1e25fc5f217/nvidia_cusolver_cu12-11.4.5.107-py3-none-manylinux1_x86_64.whl", hash = "sha256:8a7ec542f0412294b15072fa7dab71d31334014a69f953004ea7a118206fe0dd", size = 124161928 }, @@ -11852,7 +11851,7 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { dependencies = [ { name = "nvidia-cublas-cu12", version = "12.4.5.8", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-all' or extra == 'extra-4-test-chgnet' or (extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet')" }, { name = "nvidia-cusparse-cu12", version = "12.3.1.170", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-all' or extra == 'extra-4-test-chgnet' or (extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet')" }, - { name = "nvidia-nvjitlink-cu12", version = "12.4.127", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-all' or extra == 'extra-4-test-chgnet' or (extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet')" }, + { name = "nvidia-nvjitlink-cu12", marker = "extra == 'extra-4-test-all' or extra == 'extra-4-test-chgnet' or (extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet')" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/46/6b/a5c33cf16af09166845345275c34ad2190944bcc6026797a39f8e0a282e0/nvidia_cusolver_cu12-11.6.1.9-py3-none-manylinux2014_aarch64.whl", hash = "sha256:d338f155f174f90724bbde3758b7ac375a70ce8e706d70b018dd3375545fc84e", size = 127634111 }, @@ -11876,7 +11875,7 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { "python_full_version < '3.11' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", ] dependencies = [ - { name = "nvidia-nvjitlink-cu12", version = "12.8.61", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-alignn' or extra == 'extra-4-test-m3gnet'" }, + { name = "nvidia-nvjitlink-cu12", marker = "extra == 'extra-4-test-alignn' or extra == 'extra-4-test-m3gnet'" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/65/5b/cfaeebf25cd9fdec14338ccb16f6b2c4c7fa9163aefcf057d86b9cc248bb/nvidia_cusparse_cu12-12.1.0.106-py3-none-manylinux1_x86_64.whl", hash = "sha256:f3b50f42cf363f86ab21f720998517a659a48131e8d538dc02f8768237bd884c", size = 195958278 }, @@ -11902,7 +11901,7 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { "python_full_version < '3.11' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", ] dependencies = [ - { name = "nvidia-nvjitlink-cu12", version = "12.4.127", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-all' or extra == 'extra-4-test-chgnet' or (extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet')" }, + { name = "nvidia-nvjitlink-cu12", marker = "extra == 'extra-4-test-all' or extra == 'extra-4-test-chgnet' or (extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet')" }, ] wheels = [ { url = "https://files.pythonhosted.org/packages/96/a9/c0d2f83a53d40a4a41be14cea6a0bf9e668ffcf8b004bd65633f433050c0/nvidia_cusparse_cu12-12.3.1.170-py3-none-manylinux2014_aarch64.whl", hash = "sha256:9d32f62896231ebe0480efd8a7f702e143c98cfaa0e8a76df3386c1ba2b54df3", size = 207381987 }, @@ -11961,47 +11960,12 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { name = "nvidia-nvjitlink-cu12" version = "12.4.127" source = { registry = "https://pypi.org/simple" } - resolution-markers = [ - "python_full_version >= '3.12' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version >= '3.12' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version >= '3.12' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version >= '3.12' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - ] wheels = [ { url = "https://files.pythonhosted.org/packages/02/45/239d52c05074898a80a900f49b1615d81c07fceadd5ad6c4f86a987c0bc4/nvidia_nvjitlink_cu12-12.4.127-py3-none-manylinux2014_aarch64.whl", hash = "sha256:4abe7fef64914ccfa909bc2ba39739670ecc9e820c83ccc7a6ed414122599b83", size = 20552510 }, { url = "https://files.pythonhosted.org/packages/ff/ff/847841bacfbefc97a00036e0fce5a0f086b640756dc38caea5e1bb002655/nvidia_nvjitlink_cu12-12.4.127-py3-none-manylinux2014_x86_64.whl", hash = "sha256:06b3b9b25bf3f8af351d664978ca26a16d2c5127dbd53c0497e28d1fb9611d57", size = 21066810 }, { url = "https://files.pythonhosted.org/packages/81/19/0babc919031bee42620257b9a911c528f05fb2688520dcd9ca59159ffea8/nvidia_nvjitlink_cu12-12.4.127-py3-none-win_amd64.whl", hash = "sha256:fd9020c501d27d135f983c6d3e244b197a7ccad769e34df53a42e276b0e25fa1", size = 95336325 }, ] - [[package]] - name = "nvidia-nvjitlink-cu12" - version = "12.8.61" - source = { registry = "https://pypi.org/simple" } - resolution-markers = [ - "python_full_version >= '3.12' and sys_platform != 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and sys_platform != 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and sys_platform != 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version >= '3.12' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version >= '3.12' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - ] - wheels = [ - { url = "https://files.pythonhosted.org/packages/03/f8/9d85593582bd99b8d7c65634d2304780aefade049b2b94d96e44084be90b/nvidia_nvjitlink_cu12-12.8.61-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:45fd79f2ae20bd67e8bc411055939049873bfd8fac70ff13bd4865e0b9bdab17", size = 39243473 }, - { url = "https://files.pythonhosted.org/packages/af/53/698f3758f48c5fcb1112721e40cc6714da3980d3c7e93bae5b29dafa9857/nvidia_nvjitlink_cu12-12.8.61-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9b80ecab31085dda3ce3b41d043be0ec739216c3fc633b8abe212d5a30026df0", size = 38374634 }, - { url = "https://files.pythonhosted.org/packages/7f/c6/0d1b2bfeb2ef42c06db0570c4d081e5cde4450b54c09e43165126cfe6ff6/nvidia_nvjitlink_cu12-12.8.61-py3-none-win_amd64.whl", hash = "sha256:1166a964d25fdc0eae497574d38824305195a5283324a21ccb0ce0c802cbf41c", size = 268514099 }, - ] - [[package]] name = "nvidia-nvtx-cu12" version = "12.1.105" @@ -12480,8 +12444,7 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { { name = "ruamel-yaml" }, { name = "scipy" }, { name = "spglib" }, - { name = "sympy", version = "1.13.1", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-all' or extra == 'extra-4-test-chgnet'" }, - { name = "sympy", version = "1.13.3", source = { registry = "https://pypi.org/simple" }, marker = "(extra == 'extra-4-test-alignn' and extra == 'extra-4-test-all') or (extra == 'extra-4-test-alignn' and extra == 'extra-4-test-chgnet') or (extra != 'extra-4-test-alignn' and extra == 'extra-4-test-m3gnet') or (extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet')" }, + { name = "sympy" }, { name = "tabulate" }, { name = "tqdm" }, { name = "uncertainties" }, @@ -12509,11 +12472,60 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { name = "pyparsing" version = "2.4.7" source = { registry = "https://pypi.org/simple" } + resolution-markers = [ + "python_full_version >= '3.12' and sys_platform == 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", + "python_full_version >= '3.12' and sys_platform != 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", + "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", + "python_full_version == '3.11.*' and sys_platform != 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", + "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", + "python_full_version < '3.11' and sys_platform != 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", + "python_full_version >= '3.12' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version == '3.11.*' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version < '3.11' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + ] sdist = { url = "https://files.pythonhosted.org/packages/c1/47/dfc9c342c9842bbe0036c7f763d2d6686bcf5eb1808ba3e170afdb282210/pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", size = 649718 } wheels = [ { url = "https://files.pythonhosted.org/packages/8a/bb/488841f56197b13700afd5658fc279a2025a39e22449b7cf29864669b15d/pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b", size = 67842 }, ] + [[package]] + name = "pyparsing" + version = "3.2.1" + source = { registry = "https://pypi.org/simple" } + resolution-markers = [ + "python_full_version >= '3.12' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version >= '3.12' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version == '3.11.*' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version == '3.11.*' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version < '3.11' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version >= '3.12' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version >= '3.12' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version == '3.11.*' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version == '3.11.*' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version < '3.11' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version >= '3.12' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", + "python_full_version >= '3.12' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", + "python_full_version == '3.11.*' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", + "python_full_version == '3.11.*' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", + "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", + "python_full_version < '3.11' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", + "python_full_version >= '3.12' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version >= '3.12' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version == '3.11.*' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version == '3.11.*' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version < '3.11' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version >= '3.12' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version == '3.11.*' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + "python_full_version < '3.11' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", + ] + sdist = { url = "https://files.pythonhosted.org/packages/8b/1a/3544f4f299a47911c2ab3710f534e52fea62a633c96806995da5d25be4b2/pyparsing-3.2.1.tar.gz", hash = "sha256:61980854fd66de3a90028d679a954d5f2623e83144b5afe5ee86f43d762e5f0a", size = 1067694 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/1c/a7/c8a2d361bf89c0d9577c934ebb7421b25dc84bf3a8e3ac0a40aed9acc547/pyparsing-3.2.1-py3-none-any.whl", hash = "sha256:506ff4f4386c4cec0590ec19e6302d3aedb992fdc02c761e90416f158dacf8e1", size = 107716 }, + ] + [[package]] name = "python-dateutil" version = "2.9.0.post0" @@ -12858,66 +12870,14 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { name = "sympy" version = "1.13.1" source = { registry = "https://pypi.org/simple" } - resolution-markers = [ - "python_full_version >= '3.12' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version >= '3.12' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version >= '3.12' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version >= '3.12' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra == 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version >= '3.12' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version >= '3.12' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra == 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version >= '3.12' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - ] dependencies = [ - { name = "mpmath", marker = "extra == 'extra-4-test-all' or extra == 'extra-4-test-chgnet' or (extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet')" }, + { name = "mpmath" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ca/99/5a5b6f19ff9f083671ddf7b9632028436167cd3d33e11015754e41b249a4/sympy-1.13.1.tar.gz", hash = "sha256:9cebf7e04ff162015ce31c9c6c9144daa34a93bd082f54fd8f12deca4f47515f", size = 7533040 } wheels = [ { url = "https://files.pythonhosted.org/packages/b2/fe/81695a1aa331a842b582453b605175f419fe8540355886031328089d840a/sympy-1.13.1-py3-none-any.whl", hash = "sha256:db36cdc64bf61b9b24578b6f7bab1ecdd2452cf008f34faa33776680c26d66f8", size = 6189177 }, ] - [[package]] - name = "sympy" - version = "1.13.3" - source = { registry = "https://pypi.org/simple" } - resolution-markers = [ - "python_full_version >= '3.12' and sys_platform == 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version >= '3.12' and sys_platform != 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and sys_platform == 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and sys_platform != 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and sys_platform == 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and sys_platform != 'win32' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version >= '3.12' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and extra == 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra != 'extra-4-test-m3gnet'", - "python_full_version >= '3.12' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version >= '3.12' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version == '3.11.*' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and sys_platform == 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - "python_full_version < '3.11' and sys_platform != 'win32' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-all' and extra != 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet'", - ] - dependencies = [ - { name = "mpmath", marker = "extra == 'extra-4-test-alignn' or extra == 'extra-4-test-m3gnet'" }, - ] - sdist = { url = "https://files.pythonhosted.org/packages/11/8a/5a7fd6284fa8caac23a26c9ddf9c30485a48169344b4bd3b0f02fef1890f/sympy-1.13.3.tar.gz", hash = "sha256:b27fd2c6530e0ab39e275fc9b683895367e51d5da91baa8d3d64db2565fec4d9", size = 7533196 } - wheels = [ - { url = "https://files.pythonhosted.org/packages/99/ff/c87e0622b1dadea79d2fb0b25ade9ed98954c9033722eb707053d310d4f3/sympy-1.13.3-py3-none-any.whl", hash = "sha256:54612cf55a62755ee71824ce692986f23c88ffa77207b30c1368eda4a7060f73", size = 6189483 }, - ] - [[package]] name = "tabulate" version = "0.9.0" @@ -13028,7 +12988,7 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { { name = "nvidia-cusparse-cu12", version = "12.1.0.106", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-alignn') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-alignn' and extra == 'extra-4-test-all') or (platform_machine != 'x86_64' and extra == 'extra-4-test-alignn' and extra == 'extra-4-test-chgnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-alignn' and extra == 'extra-4-test-all') or (sys_platform != 'linux' and extra == 'extra-4-test-alignn' and extra == 'extra-4-test-chgnet') or (sys_platform != 'linux' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet')" }, { name = "nvidia-nccl-cu12", version = "2.19.3", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-alignn') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-alignn' and extra == 'extra-4-test-all') or (platform_machine != 'x86_64' and extra == 'extra-4-test-alignn' and extra == 'extra-4-test-chgnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-alignn' and extra == 'extra-4-test-all') or (sys_platform != 'linux' and extra == 'extra-4-test-alignn' and extra == 'extra-4-test-chgnet') or (sys_platform != 'linux' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet')" }, { name = "nvidia-nvtx-cu12", version = "12.1.105", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-alignn') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-alignn' and extra == 'extra-4-test-all') or (platform_machine != 'x86_64' and extra == 'extra-4-test-alignn' and extra == 'extra-4-test-chgnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-alignn' and extra == 'extra-4-test-all') or (sys_platform != 'linux' and extra == 'extra-4-test-alignn' and extra == 'extra-4-test-chgnet') or (sys_platform != 'linux' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet')" }, - { name = "sympy", version = "1.13.3", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-alignn' or extra == 'extra-4-test-m3gnet'" }, + { name = "sympy", marker = "extra == 'extra-4-test-alignn' or extra == 'extra-4-test-m3gnet'" }, { name = "triton", version = "2.2.0", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-alignn') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-alignn' and extra == 'extra-4-test-all') or (platform_machine != 'x86_64' and extra == 'extra-4-test-alignn' and extra == 'extra-4-test-chgnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-alignn' and extra == 'extra-4-test-all') or (sys_platform != 'linux' and extra == 'extra-4-test-alignn' and extra == 'extra-4-test-chgnet') or (sys_platform != 'linux' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet')" }, { name = "typing-extensions", marker = "extra == 'extra-4-test-alignn' or extra == 'extra-4-test-m3gnet'" }, ] @@ -13092,10 +13052,10 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { { name = "nvidia-cusolver-cu12", version = "11.6.1.9", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-chgnet') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet') or (extra == 'extra-4-test-alignn' and extra == 'extra-4-test-all') or (extra == 'extra-4-test-alignn' and extra == 'extra-4-test-chgnet')" }, { name = "nvidia-cusparse-cu12", version = "12.3.1.170", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-chgnet') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet') or (extra == 'extra-4-test-alignn' and extra == 'extra-4-test-all') or (extra == 'extra-4-test-alignn' and extra == 'extra-4-test-chgnet')" }, { name = "nvidia-nccl-cu12", version = "2.21.5", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-chgnet') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet') or (extra == 'extra-4-test-alignn' and extra == 'extra-4-test-all') or (extra == 'extra-4-test-alignn' and extra == 'extra-4-test-chgnet')" }, - { name = "nvidia-nvjitlink-cu12", version = "12.4.127", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-chgnet') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet') or (extra == 'extra-4-test-alignn' and extra == 'extra-4-test-all') or (extra == 'extra-4-test-alignn' and extra == 'extra-4-test-chgnet')" }, + { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-chgnet') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet') or (extra == 'extra-4-test-alignn' and extra == 'extra-4-test-all') or (extra == 'extra-4-test-alignn' and extra == 'extra-4-test-chgnet')" }, { name = "nvidia-nvtx-cu12", version = "12.4.127", source = { registry = "https://pypi.org/simple" }, marker = "(platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-all') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-chgnet') or (platform_machine == 'x86_64' and sys_platform == 'linux' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet') or (extra == 'extra-4-test-alignn' and extra == 'extra-4-test-all') or (extra == 'extra-4-test-alignn' and extra == 'extra-4-test-chgnet')" }, { name = "setuptools", marker = "(python_full_version >= '3.12' and extra == 'extra-4-test-all') or (python_full_version >= '3.12' and extra == 'extra-4-test-chgnet') or (python_full_version >= '3.12' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet') or (extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet') or (extra == 'extra-4-test-alignn' and extra == 'extra-4-test-all') or (extra == 'extra-4-test-alignn' and extra == 'extra-4-test-chgnet')" }, - { name = "sympy", version = "1.13.1", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-all' or extra == 'extra-4-test-chgnet' or (extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet')" }, + { name = "sympy", marker = "extra == 'extra-4-test-all' or extra == 'extra-4-test-chgnet' or (extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet')" }, { name = "triton", version = "3.1.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.13' and platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-all') or (python_full_version < '3.13' and platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'extra-4-test-chgnet') or (python_full_version < '3.13' and platform_machine == 'x86_64' and sys_platform == 'linux' and extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet') or (python_full_version >= '3.13' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (python_full_version >= '3.13' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (platform_machine != 'x86_64' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (sys_platform != 'linux' and extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet') or (extra == 'extra-4-test-alignn' and extra == 'extra-4-test-all') or (extra == 'extra-4-test-alignn' and extra == 'extra-4-test-chgnet')" }, { name = "typing-extensions", marker = "extra == 'extra-4-test-all' or extra == 'extra-4-test-chgnet' or (extra != 'extra-4-test-alignn' and extra != 'extra-4-test-m3gnet')" }, ] @@ -13138,7 +13098,8 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { { name = "jinja2" }, { name = "numpy" }, { name = "psutil" }, - { name = "pyparsing" }, + { name = "pyparsing", version = "2.4.7", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-alignn' or (extra == 'extra-4-test-all' and extra == 'extra-4-test-m3gnet') or (extra == 'extra-4-test-chgnet' and extra == 'extra-4-test-m3gnet')" }, + { name = "pyparsing", version = "3.2.1", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-4-test-all' or extra == 'extra-4-test-chgnet' or extra != 'extra-4-test-alignn'" }, { name = "requests" }, { name = "tqdm" }, ] @@ -13378,7 +13339,7 @@ fn duplicate_torch_and_sympy_because_of_wrong_inferences() -> Result<()> { { url = "https://files.pythonhosted.org/packages/f5/d5/688db678e987c3e0fb17867970700b92603cadf36c56e5fb08f23e822a0c/yarl-1.18.3-cp313-cp313-win_amd64.whl", hash = "sha256:578e281c393af575879990861823ef19d66e2b1d0098414855dd367e234f5b3c", size = 315723 }, { url = "https://files.pythonhosted.org/packages/f5/4b/a06e0ec3d155924f77835ed2d167ebd3b211a7b0853da1cf8d8414d784ef/yarl-1.18.3-py3-none-any.whl", hash = "sha256:b57f4f58099328dfb26c6a771d09fb20dbbae81d20cfb66141251ea063bd101b", size = 45109 }, ] - "### + "# ); }); diff --git a/crates/uv/tests/it/sync.rs b/crates/uv/tests/it/sync.rs index de86b838c..9996ba48c 100644 --- a/crates/uv/tests/it/sync.rs +++ b/crates/uv/tests/it/sync.rs @@ -8019,15 +8019,381 @@ fn multiple_group_conflicts() -> Result<()> { + iniconfig==1.1.1 "###); - uv_snapshot!(context.filters(), context.sync().arg("--group").arg("foo").arg("--group").arg("bar"), @r###" + uv_snapshot!(context.filters(), context.sync().arg("--group").arg("foo").arg("--group").arg("bar"), @r" success: false exit_code: 2 ----- stdout ----- ----- stderr ----- Resolved 3 packages in [TIME] - error: Groups `foo` and `bar` are incompatible with the declared conflicts: {`project:foo`, `project:bar`} - "###); + error: Groups `bar` and `foo` are incompatible with the declared conflicts: {`project:bar`, `project:foo`} + "); + + Ok(()) +} + +/// See: +#[test] +fn transitive_group_conflicts_shallow() -> Result<()> { + let context = TestContext::new("3.12"); + + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str( + r#" + [project] + name = "example" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = [] + + [dependency-groups] + dev = [ + { include-group = "test" }, + ] + test = ["anyio>4"] + magic = ["anyio<4"] + + [tool.uv] + conflicts = [ + [ + { group = "test" }, + { group = "magic" }, + ], + ] + "#, + )?; + + uv_snapshot!(context.filters(), context.sync(), @r" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 5 packages in [TIME] + Prepared 3 packages in [TIME] + Installed 3 packages in [TIME] + + anyio==4.3.0 + + idna==3.6 + + sniffio==1.3.1 + "); + + uv_snapshot!(context.filters(), context.sync().arg("--group").arg("dev"), @r" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 5 packages in [TIME] + Audited 3 packages in [TIME] + "); + + uv_snapshot!(context.filters(), context.sync().arg("--group").arg("dev").arg("--group").arg("test"), @r" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 5 packages in [TIME] + Audited 3 packages in [TIME] + "); + + uv_snapshot!(context.filters(), context.sync().arg("--group").arg("test").arg("--group").arg("magic"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + Resolved 5 packages in [TIME] + error: Groups `magic` and `test` are incompatible with the declared conflicts: {`example:magic`, `example:test`} + "); + + uv_snapshot!(context.filters(), context.sync().arg("--group").arg("dev").arg("--group").arg("magic"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + Resolved 5 packages in [TIME] + error: Groups `dev` and `magic` are incompatible with the transitively inferred conflicts: {`example:dev`, `example:magic`} + "); + + Ok(()) +} + +/// See: +#[test] +fn transitive_group_conflicts_deep() -> Result<()> { + let context = TestContext::new("3.12"); + + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str( + r#" + [project] + name = "example" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = [] + + [dependency-groups] + dev = [ + { include-group = "intermediate" }, + ] + intermediate = [ + { include-group = "test" }, + { include-group = "other" }, + ] + test = ["iniconfig>=2"] + magic = ["iniconfig<2", "anyio<4"] + other = ["anyio>4"] + + [tool.uv] + conflicts = [ + [ + { group = "test" }, + { group = "magic" }, + ], + [ + { group = "other" }, + { group = "magic" }, + ], + ]"#, + )?; + + uv_snapshot!(context.filters(), context.sync(), @r" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 7 packages in [TIME] + Prepared 4 packages in [TIME] + Installed 4 packages in [TIME] + + anyio==4.3.0 + + idna==3.6 + + iniconfig==2.0.0 + + sniffio==1.3.1 + "); + + uv_snapshot!(context.filters(), context.sync().arg("--group").arg("dev"), @r" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 7 packages in [TIME] + Audited 4 packages in [TIME] + "); + + uv_snapshot!(context.filters(), context.sync().arg("--group").arg("dev").arg("--group").arg("test"), @r" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 7 packages in [TIME] + Audited 4 packages in [TIME] + "); + + uv_snapshot!(context.filters(), context.sync().arg("--group").arg("dev").arg("--group").arg("magic"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + Resolved 7 packages in [TIME] + error: Groups `dev` and `magic` are incompatible with the transitively inferred conflicts: {`example:dev`, `example:magic`} + "); + + uv_snapshot!(context.filters(), context.sync().arg("--no-dev").arg("--group").arg("intermediate").arg("--group").arg("magic"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + Resolved 7 packages in [TIME] + error: Groups `intermediate` and `magic` are incompatible with the transitively inferred conflicts: {`example:intermediate`, `example:magic`} + "); + + Ok(()) +} + +/// See: +#[test] +fn transitive_group_conflicts_siblings() -> Result<()> { + let context = TestContext::new("3.12"); + + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str( + r#" + [project] + name = "example" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = [] + + [dependency-groups] + dev = [ + { include-group = "test" }, + ] + dev2 = [ + { include-group = "magic" }, + ] + test = ["anyio>4"] + magic = ["anyio<4"] + + [tool.uv] + conflicts = [ + [ + { group = "test" }, + { group = "magic" }, + ], + ]"#, + )?; + + uv_snapshot!(context.filters(), context.sync(), @r" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 5 packages in [TIME] + Prepared 3 packages in [TIME] + Installed 3 packages in [TIME] + + anyio==4.3.0 + + idna==3.6 + + sniffio==1.3.1 + "); + + uv_snapshot!(context.filters(), context.sync().arg("--group").arg("dev"), @r" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 5 packages in [TIME] + Audited 3 packages in [TIME] + "); + + uv_snapshot!(context.filters(), context.sync().arg("--no-dev").arg("--group").arg("dev2"), @r" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 5 packages in [TIME] + Prepared 1 package in [TIME] + Uninstalled 1 package in [TIME] + Installed 1 package in [TIME] + - anyio==4.3.0 + + anyio==3.7.1 + "); + + uv_snapshot!(context.filters(), context.sync().arg("--group").arg("dev2"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + Resolved 5 packages in [TIME] + error: Groups `dev` (enabled by default) and `dev2` are incompatible with the transitively inferred conflicts: {`example:dev`, `example:dev2`} + "); + + uv_snapshot!(context.filters(), context.sync().arg("--group").arg("dev").arg("--group").arg("dev2"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + Resolved 5 packages in [TIME] + error: Groups `dev` and `dev2` are incompatible with the transitively inferred conflicts: {`example:dev`, `example:dev2`} + "); + + Ok(()) +} + +/// See: +#[test] +fn transitive_group_conflicts_cycle() -> Result<()> { + let context = TestContext::new("3.12"); + + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str( + r#" + [project] + name = "example" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = [] + + [dependency-groups] + dev = [ + { include-group = "test" }, + ] + test = [ + "anyio>4", + { include-group = "dev" }, + ] + magic = ["anyio<4"] + + [tool.uv] + conflicts = [ + [ + { group = "test" }, + { group = "magic" }, + ], + ] + "#, + )?; + + uv_snapshot!(context.filters(), context.sync(), @r" + success: false + exit_code: 1 + ----- stdout ----- + + ----- stderr ----- + × Failed to build `example @ file://[TEMP_DIR]/` + ╰─▶ Detected a cycle in `dependency-groups`: `dev` -> `test` -> `dev` + "); + + uv_snapshot!(context.filters(), context.sync().arg("--group").arg("dev"), @r" + success: false + exit_code: 1 + ----- stdout ----- + + ----- stderr ----- + × Failed to build `example @ file://[TEMP_DIR]/` + ╰─▶ Detected a cycle in `dependency-groups`: `dev` -> `test` -> `dev` + "); + + uv_snapshot!(context.filters(), context.sync().arg("--group").arg("dev").arg("--group").arg("test"), @r" + success: false + exit_code: 1 + ----- stdout ----- + + ----- stderr ----- + × Failed to build `example @ file://[TEMP_DIR]/` + ╰─▶ Detected a cycle in `dependency-groups`: `dev` -> `test` -> `dev` + "); + + uv_snapshot!(context.filters(), context.sync().arg("--group").arg("test").arg("--group").arg("magic"), @r" + success: false + exit_code: 1 + ----- stdout ----- + + ----- stderr ----- + × Failed to build `example @ file://[TEMP_DIR]/` + ╰─▶ Detected a cycle in `dependency-groups`: `dev` -> `test` -> `dev` + "); + + uv_snapshot!(context.filters(), context.sync().arg("--group").arg("dev").arg("--group").arg("magic"), @r" + success: false + exit_code: 1 + ----- stdout ----- + + ----- stderr ----- + × Failed to build `example @ file://[TEMP_DIR]/` + ╰─▶ Detected a cycle in `dependency-groups`: `dev` -> `test` -> `dev` + "); Ok(()) }