docs: add some words about specifying conflicting extras/groups (#9120)

This doesn't cover the optional `package` key since I wasn't quite sure
how to articulate its utility in a digestible way.

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
This commit is contained in:
Andrew Gallant 2024-11-14 14:50:18 -05:00 committed by GitHub
parent 3a7db17147
commit ed130b0c11
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 67 additions and 5 deletions

View File

@ -389,6 +389,11 @@ To add an optional dependency, use the `--optional <extra>` option:
$ uv add httpx --optional network
```
!!! note
If you have optional dependencies that conflict with one another, resolution will fail
unless you explicitly [declare them as conflicting](./projects.md#optional-dependencies).
## Development dependencies
Unlike optional dependencies, development dependencies are local-only and will _not_ be included in
@ -455,8 +460,8 @@ to resolve the requirements of the project with an error.
!!! note
There is currently no way to declare conflicting dependency groups. See
[astral.sh/uv#6981](https://github.com/astral-sh/uv/issues/6981) to track support.
If you have dependency groups that conflict with one another, resolution will fail
unless you explicitly [declare them as conflicting](./projects.md#optional-dependencies).
### Default groups

View File

@ -484,10 +484,67 @@ each other and resolves all optional dependencies together when creating the loc
If optional dependencies declared in one extra are not compatible with those in another extra, uv
will fail to resolve the requirements of the project with an error.
!!! note
To work around this, uv supports declaring conflicting extras. For example, consider two sets of
optional dependencies that conflict with one another:
There is currently no way to declare conflicting optional dependencies. See
[astral.sh/uv#6981](https://github.com/astral-sh/uv/issues/6981) to track support.
```toml title="pyproject.toml"
[project.optional-dependencies]
extra1 = ["numpy==2.1.2"]
extra2 = ["numpy==2.0.0"]
```
If you run `uv lock` with the above dependencies, resolution will fail:
```console
$ uv lock
x No solution found when resolving dependencies:
`-> Because myproject[extra2] depends on numpy==2.0.0 and myproject[extra1] depends on numpy==2.1.2, we can conclude that myproject[extra1] and
myproject[extra2] are incompatible.
And because your project requires myproject[extra1] and myproject[extra2], we can conclude that your projects's requirements are unsatisfiable.
```
But if you specify that `extra1` and `extra2` are conflicting, uv will resolve them separately.
Specify conflicts in the `tool.uv` section:
```toml title="pyproject.toml"
[tool.uv]
conflicts = [
[
{ extra = "extra1" },
{ extra = "extra2" },
],
]
```
Now, running `uv lock` will succeed. Note though, that now you cannot install both `extra1` and
`extra2` at the same time:
```console
$ uv sync --extra extra1 --extra extra2
Resolved 3 packages in 14ms
error: extra `extra1`, extra `extra2` are incompatible with the declared conflicts: {`myproject[extra1]`, `myproject[extra2]`}
```
This error occurs because installing both `extra1` and `extra2` would result in installing two
different versions of a package into the same environment.
The above strategy for dealing with conflicting extras also works with dependency groups:
```toml title="pyproject.toml"
[dependency-groups]
group1 = ["numpy==2.1.2"]
group2 = ["numpy==2.0.0"]
[tool.uv]
conflicts = [
[
{ group = "group1" },
{ group = "group2" },
],
]
```
The only difference with conflicting extras is that you need to use `group` instead of `extra`.
## Managing dependencies