Skip to content

Commit 8871d2e

Browse files
committed
docs: add some words about specifying conflicting extras/groups
This doesn't cover the optional `package` key since I wasn't quite sure how to articulate its utility in a digestible way.
1 parent 57ff533 commit 8871d2e

File tree

2 files changed

+68
-5
lines changed

2 files changed

+68
-5
lines changed

docs/concepts/dependencies.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,12 @@ To add an optional dependency, use the `--optional <extra>` option:
389389
$ uv add httpx --optional network
390390
```
391391

392+
!!! note
393+
394+
If you have optional dependencies that conflict with one another and are using uv in
395+
project mode with universal resolution, then resolution will fail. To work around this,
396+
it's possible to [declare them as conflicting](./projects.md#optional-dependencies).
397+
392398
## Development dependencies
393399

394400
Unlike optional dependencies, development dependencies are local-only and will _not_ be included in
@@ -455,8 +461,9 @@ to resolve the requirements of the project with an error.
455461

456462
!!! note
457463

458-
There is currently no way to declare conflicting dependency groups. See
459-
[astral.sh/uv#6981](https://github.com/astral-sh/uv/issues/6981) to track support.
464+
If you have dependency groups that conflict with one another and are using uv in
465+
project mode with universal resolution, then resolution will fail. To work around this,
466+
it's possible to [declare them as conflicting](./projects.md#optional-dependencies).
460467

461468
### Default groups
462469

docs/concepts/projects.md

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -484,10 +484,66 @@ each other and resolves all optional dependencies together when creating the loc
484484
If optional dependencies declared in one extra are not compatible with those in another extra, uv
485485
will fail to resolve the requirements of the project with an error.
486486

487-
!!! note
487+
To work around this, uv supports declaring conflicting extras. For example, consider two sets of
488+
optional dependencies that conflict with one another:
489+
490+
```toml title="pyproject.toml"
491+
[project.optional-dependencies]
492+
project1 = ["numpy==2.1.2"]
493+
project2 = ["numpy==2.0.0"]
494+
```
495+
496+
If you try to run `uv lock` with the above dependencies, you should get an error like this:
497+
498+
```
499+
x No solution found when resolving dependencies:
500+
`-> Because myproject[project2] depends on numpy==2.0.0 and myproject[project1] depends on numpy==2.1.2, we can conclude that myproject[project1] and
501+
myproject[project2] are incompatible.
502+
And because your project requires myproject[project1] and myproject[project2], we can conclude that your projects's requirements are unsatisfiable.
503+
```
504+
505+
But if we specify that `project1` and `project2` are conflicting, uv will resolve them in different
506+
forks. We can specify conflicts in the `tool.uv` section:
507+
508+
```toml title="pyproject.toml"
509+
[tool.uv]
510+
conflicts = [
511+
[
512+
{ extra = "project1" },
513+
{ extra = "project2" },
514+
],
515+
]
516+
```
517+
518+
And now running `uv lock` will succeed. Note though, that this will prevent you from enabling
519+
both `project1` and `project2` simultaneously:
520+
521+
```console
522+
$ uv sync --extra project1 --extra project2
523+
Resolved 3 packages in 14ms
524+
error: extra `project1`, extra `project2` are incompatible with the declared conflicts: {`myproject[project1]`, `myproject[project2]`}
525+
```
526+
527+
This error occurs because installing both `project1` and `project2` simultaneously could result
528+
in installing two different versions of the same package into the same environment.
529+
530+
The above strategy for dealing with conflicting extras also works with groups:
531+
532+
```toml title="pyproject.toml"
533+
[dependency-groups]
534+
project1 = ["numpy==2.1.2"]
535+
project2 = ["numpy==2.0.0"]
536+
537+
[tool.uv]
538+
conflicts = [
539+
[
540+
{ group = "project1" },
541+
{ group = "project2" },
542+
],
543+
]
544+
```
488545

489-
There is currently no way to declare conflicting optional dependencies. See
490-
[astral.sh/uv#6981](https://github.com/astral-sh/uv/issues/6981) to track support.
546+
The only difference with conflicting extras is that you need to use `group` instead of `extra`.
491547

492548
## Managing dependencies
493549

0 commit comments

Comments
 (0)