Skip to content

Commit 2df3f0e

Browse files
Reduce ambiguity in conflicting extras example (#10877)
## Summary Closes #10378.
1 parent 4051cff commit 2df3f0e

File tree

3 files changed

+46
-54
lines changed

3 files changed

+46
-54
lines changed

crates/uv-workspace/src/pyproject.rs

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -504,48 +504,44 @@ pub struct ToolUv {
504504
)]
505505
pub environments: Option<SupportedEnvironments>,
506506

507-
/// Conflicting extras or groups may be declared here.
507+
/// Declare collections of extras or dependency groups that are conflicting
508+
/// (i.e., mutually exclusive).
508509
///
509-
/// It's useful to declare conflicts when, for example, two or more extras
510-
/// have mutually incompatible dependencies. Extra `foo` might depend
511-
/// on `numpy==2.0.0` while extra `bar` might depend on `numpy==2.1.0`.
512-
/// These extras cannot be activated at the same time. This usually isn't
513-
/// a problem for pip-style workflows, but when using projects in uv that
514-
/// support with universal resolution, it will try to produce a resolution
515-
/// that satisfies both extras simultaneously.
510+
/// It's useful to declare conflicts when two or more extras have mutually
511+
/// incompatible dependencies. For example, extra `foo` might depend
512+
/// on `numpy==2.0.0` while extra `bar` depends on `numpy==2.1.0`. While these
513+
/// dependencies conflict, it may be the case that users are not expected to
514+
/// activate both `foo` and `bar` at the same time, making it possible to
515+
/// generate a universal resolution for the project despite the incompatibility.
516516
///
517-
/// When this happens, resolution will fail, because one cannot install
518-
/// both `numpy 2.0.0` and `numpy 2.1.0` into the same environment.
519-
///
520-
/// To work around this, you may specify `foo` and `bar` as conflicting
521-
/// extras (you can do the same with groups). When doing universal
522-
/// resolution in project mode, these extras will get their own "forks"
523-
/// distinct from one another in order to permit conflicting dependencies.
524-
/// In exchange, if one tries to install from the lock file with both
525-
/// conflicting extras activated, installation will fail.
517+
/// By making such conflicts explicit, uv can generate a universal resolution
518+
/// for a project, taking into account that certain combinations of extras and
519+
/// groups are mutually exclusive. In exchange, installation will fail if a
520+
/// user attempts to activate both conflicting extras.
526521
#[cfg_attr(
527522
feature = "schemars",
528-
schemars(description = "A list sets of conflicting groups or extras.")
523+
schemars(description = "A list of sets of conflicting groups or extras.")
529524
)]
530525
#[option(
531526
default = r#"[]"#,
532527
value_type = "list[list[dict]]",
533528
example = r#"
534-
# Require that `package[test1]` and `package[test2]`
535-
# requirements are resolved in different forks so that they
536-
# cannot conflict with one another.
529+
# Require that `package[extra1]` and `package[extra2]` are resolved
530+
# in different forks so that they cannot conflict with one another.
537531
conflicts = [
538532
[
539-
{ extra = "test1" },
540-
{ extra = "test2" },
533+
{ extra = "extra1" },
534+
{ extra = "extra2" },
541535
]
542536
]
543537
544-
# Or, to declare conflicting groups:
538+
# Require that the dependency groups `group1` and `group2`
539+
# are resolved in different forks so that they cannot conflict
540+
# with one another.
545541
conflicts = [
546542
[
547-
{ group = "test1" },
548-
{ group = "test2" },
543+
{ group = "group1" },
544+
{ group = "group2" },
549545
]
550546
]
551547
"#

docs/reference/settings.md

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,20 @@
11
## Project metadata
22
### [`conflicts`](#conflicts) {: #conflicts }
33

4-
Conflicting extras or groups may be declared here.
5-
6-
It's useful to declare conflicts when, for example, two or more extras
7-
have mutually incompatible dependencies. Extra `foo` might depend
8-
on `numpy==2.0.0` while extra `bar` might depend on `numpy==2.1.0`.
9-
These extras cannot be activated at the same time. This usually isn't
10-
a problem for pip-style workflows, but when using projects in uv that
11-
support with universal resolution, it will try to produce a resolution
12-
that satisfies both extras simultaneously.
13-
14-
When this happens, resolution will fail, because one cannot install
15-
both `numpy 2.0.0` and `numpy 2.1.0` into the same environment.
16-
17-
To work around this, you may specify `foo` and `bar` as conflicting
18-
extras (you can do the same with groups). When doing universal
19-
resolution in project mode, these extras will get their own "forks"
20-
distinct from one another in order to permit conflicting dependencies.
21-
In exchange, if one tries to install from the lock file with both
22-
conflicting extras activated, installation will fail.
4+
Declare collections of extras or dependency groups that are conflicting
5+
(i.e., mutually exclusive).
6+
7+
It's useful to declare conflicts when two or more extras have mutually
8+
incompatible dependencies. For example, extra `foo` might depend
9+
on `numpy==2.0.0` while extra `bar` depends on `numpy==2.1.0`. While these
10+
dependencies conflict, it may be the case that users are not expected to
11+
activate both `foo` and `bar` at the same time, making it possible to
12+
generate a universal resolution for the project despite the incompatibility.
13+
14+
By making such conflicts explicit, uv can generate a universal resolution
15+
for a project, taking into account that certain combinations of extras and
16+
groups are mutually exclusive. In exchange, installation will fail if a
17+
user attempts to activate both conflicting extras.
2318

2419
**Default value**: `[]`
2520

@@ -29,21 +24,22 @@ conflicting extras activated, installation will fail.
2924

3025
```toml title="pyproject.toml"
3126
[tool.uv]
32-
# Require that `package[test1]` and `package[test2]`
33-
# requirements are resolved in different forks so that they
34-
# cannot conflict with one another.
27+
# Require that `package[extra1]` and `package[extra2]` are resolved
28+
# in different forks so that they cannot conflict with one another.
3529
conflicts = [
3630
[
37-
{ extra = "test1" },
38-
{ extra = "test2" },
31+
{ extra = "extra1" },
32+
{ extra = "extra2" },
3933
]
4034
]
4135

42-
# Or, to declare conflicting groups:
36+
# Require that the dependency groups `group1` and `group2`
37+
# are resolved in different forks so that they cannot conflict
38+
# with one another.
4339
conflicts = [
4440
[
45-
{ group = "test1" },
46-
{ group = "test2" },
41+
{ group = "group1" },
42+
{ group = "group2" },
4743
]
4844
]
4945
```

uv.schema.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)