diff --git a/crates/uv-workspace/src/pyproject.rs b/crates/uv-workspace/src/pyproject.rs index e6ae3a0b2dcf2..483169d7edf75 100644 --- a/crates/uv-workspace/src/pyproject.rs +++ b/crates/uv-workspace/src/pyproject.rs @@ -504,48 +504,44 @@ pub struct ToolUv { )] pub environments: Option, - /// Conflicting extras or groups may be declared here. + /// Declare collections of extras or dependency groups that are conflicting + /// (i.e., mutually exclusive). /// - /// It's useful to declare conflicts when, for example, two or more extras - /// have mutually incompatible dependencies. Extra `foo` might depend - /// on `numpy==2.0.0` while extra `bar` might depend on `numpy==2.1.0`. - /// These extras cannot be activated at the same time. This usually isn't - /// a problem for pip-style workflows, but when using projects in uv that - /// support with universal resolution, it will try to produce a resolution - /// that satisfies both extras simultaneously. + /// It's useful to declare conflicts when two or more extras have mutually + /// incompatible dependencies. For example, extra `foo` might depend + /// on `numpy==2.0.0` while extra `bar` depends on `numpy==2.1.0`. While these + /// dependencies conflict, it may be the case that users are not expected to + /// activate both `foo` and `bar` at the same time, making it possible to + /// generate a universal resolution for the project despite the incompatibility. /// - /// When this happens, resolution will fail, because one cannot install - /// both `numpy 2.0.0` and `numpy 2.1.0` into the same environment. - /// - /// To work around this, you may specify `foo` and `bar` as conflicting - /// extras (you can do the same with groups). When doing universal - /// resolution in project mode, these extras will get their own "forks" - /// distinct from one another in order to permit conflicting dependencies. - /// In exchange, if one tries to install from the lock file with both - /// conflicting extras activated, installation will fail. + /// By making such conflicts explicit, uv can generate a universal resolution + /// for a project, taking into account that certain combinations of extras and + /// groups are mutually exclusive. In exchange, installation will fail if a + /// user attempts to activate both conflicting extras. #[cfg_attr( feature = "schemars", - schemars(description = "A list sets of conflicting groups or extras.") + schemars(description = "A list of sets of conflicting groups or extras.") )] #[option( default = r#"[]"#, value_type = "list[list[dict]]", example = r#" - # Require that `package[test1]` and `package[test2]` - # requirements are resolved in different forks so that they - # cannot conflict with one another. + # Require that `package[extra1]` and `package[extra2]` are resolved + # in different forks so that they cannot conflict with one another. conflicts = [ [ - { extra = "test1" }, - { extra = "test2" }, + { extra = "extra1" }, + { extra = "extra2" }, ] ] - # Or, to declare conflicting groups: + # Require that the dependency groups `group1` and `group2` + # are resolved in different forks so that they cannot conflict + # with one another. conflicts = [ [ - { group = "test1" }, - { group = "test2" }, + { group = "group1" }, + { group = "group2" }, ] ] "# diff --git a/docs/reference/settings.md b/docs/reference/settings.md index 0368c66950d45..9f80d1b4942d2 100644 --- a/docs/reference/settings.md +++ b/docs/reference/settings.md @@ -1,25 +1,20 @@ ## Project metadata ### [`conflicts`](#conflicts) {: #conflicts } -Conflicting extras or groups may be declared here. - -It's useful to declare conflicts when, for example, two or more extras -have mutually incompatible dependencies. Extra `foo` might depend -on `numpy==2.0.0` while extra `bar` might depend on `numpy==2.1.0`. -These extras cannot be activated at the same time. This usually isn't -a problem for pip-style workflows, but when using projects in uv that -support with universal resolution, it will try to produce a resolution -that satisfies both extras simultaneously. - -When this happens, resolution will fail, because one cannot install -both `numpy 2.0.0` and `numpy 2.1.0` into the same environment. - -To work around this, you may specify `foo` and `bar` as conflicting -extras (you can do the same with groups). When doing universal -resolution in project mode, these extras will get their own "forks" -distinct from one another in order to permit conflicting dependencies. -In exchange, if one tries to install from the lock file with both -conflicting extras activated, installation will fail. +Declare collections of extras or dependency groups that are conflicting +(i.e., mutually exclusive). + +It's useful to declare conflicts when two or more extras have mutually +incompatible dependencies. For example, extra `foo` might depend +on `numpy==2.0.0` while extra `bar` depends on `numpy==2.1.0`. While these +dependencies conflict, it may be the case that users are not expected to +activate both `foo` and `bar` at the same time, making it possible to +generate a universal resolution for the project despite the incompatibility. + +By making such conflicts explicit, uv can generate a universal resolution +for a project, taking into account that certain combinations of extras and +groups are mutually exclusive. In exchange, installation will fail if a +user attempts to activate both conflicting extras. **Default value**: `[]` @@ -29,21 +24,22 @@ conflicting extras activated, installation will fail. ```toml title="pyproject.toml" [tool.uv] -# Require that `package[test1]` and `package[test2]` -# requirements are resolved in different forks so that they -# cannot conflict with one another. +# Require that `package[extra1]` and `package[extra2]` are resolved +# in different forks so that they cannot conflict with one another. conflicts = [ [ - { extra = "test1" }, - { extra = "test2" }, + { extra = "extra1" }, + { extra = "extra2" }, ] ] -# Or, to declare conflicting groups: +# Require that the dependency groups `group1` and `group2` +# are resolved in different forks so that they cannot conflict +# with one another. conflicts = [ [ - { group = "test1" }, - { group = "test2" }, + { group = "group1" }, + { group = "group2" }, ] ] ``` diff --git a/uv.schema.json b/uv.schema.json index 52f5e3661a273..9abf18d313c59 100644 --- a/uv.schema.json +++ b/uv.schema.json @@ -88,7 +88,7 @@ ] }, "conflicts": { - "description": "A list sets of conflicting groups or extras.", + "description": "A list of sets of conflicting groups or extras.", "anyOf": [ { "$ref": "#/definitions/SchemaConflicts"