mirror of https://github.com/astral-sh/uv
Move "Conflicting dependencies" to the "Resolution" page (#14633)
This commit is contained in:
parent
863e73a841
commit
8d6d0678a7
|
|
@ -196,41 +196,6 @@ To target this environment, you'd export `UV_PROJECT_ENVIRONMENT=/usr/local`.
|
||||||
environment. The `--active` flag can be used to opt-in to respecting `VIRTUAL_ENV`. The
|
environment. The `--active` flag can be used to opt-in to respecting `VIRTUAL_ENV`. The
|
||||||
`--no-active` flag can be used to silence the warning.
|
`--no-active` flag can be used to silence the warning.
|
||||||
|
|
||||||
## Limited resolution environments
|
|
||||||
|
|
||||||
If your project supports a more limited set of platforms or Python versions, you can constrain the
|
|
||||||
set of solved platforms via the `environments` setting, which accepts a list of PEP 508 environment
|
|
||||||
markers. For example, to constrain the lockfile to macOS and Linux, and exclude Windows:
|
|
||||||
|
|
||||||
```toml title="pyproject.toml"
|
|
||||||
[tool.uv]
|
|
||||||
environments = [
|
|
||||||
"sys_platform == 'darwin'",
|
|
||||||
"sys_platform == 'linux'",
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
See the [resolution documentation](../resolution.md#limited-resolution-environments) for more.
|
|
||||||
|
|
||||||
## Required environments
|
|
||||||
|
|
||||||
If your project _must_ support a specific platform or Python version, you can mark that platform as
|
|
||||||
required via the `required-environments` setting. For example, to require that the project supports
|
|
||||||
Intel macOS:
|
|
||||||
|
|
||||||
```toml title="pyproject.toml"
|
|
||||||
[tool.uv]
|
|
||||||
required-environments = [
|
|
||||||
"sys_platform == 'darwin' and platform_machine == 'x86_64'",
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
The `required-environments` setting is only relevant for packages that do not publish a source
|
|
||||||
distribution (like PyTorch), as such packages can _only_ be installed on environments covered by the
|
|
||||||
set of pre-built binary distributions (wheels) published by that package.
|
|
||||||
|
|
||||||
See the [resolution documentation](../resolution.md#required-environments) for more.
|
|
||||||
|
|
||||||
## Build isolation
|
## Build isolation
|
||||||
|
|
||||||
By default, uv builds all packages in isolated virtual environments, as per
|
By default, uv builds all packages in isolated virtual environments, as per
|
||||||
|
|
@ -401,33 +366,12 @@ in the deployed environment without a dependency on the originating source code.
|
||||||
|
|
||||||
## Conflicting dependencies
|
## Conflicting dependencies
|
||||||
|
|
||||||
uv requires that all optional dependencies ("extras") declared by the project are compatible with
|
uv requires resolves all project dependencies together, including optional dependencies ("extras")
|
||||||
each other and resolves all optional dependencies together when creating the lockfile.
|
and dependency groups. If dependencies declared in one section are not compatible with those in
|
||||||
|
another section, uv will fail to resolve the requirements of the project with an error.
|
||||||
|
|
||||||
If optional dependencies declared in one extra are not compatible with those in another extra, uv
|
uv supports explicit declaration of conflicting dependency groups. For example, to declare that the
|
||||||
will fail to resolve the requirements of the project with an error.
|
`optional-dependency` groups `extra1` and `extra2` are incompatible:
|
||||||
|
|
||||||
To work around this, uv supports declaring conflicting extras. For example, consider two sets of
|
|
||||||
optional dependencies that conflict with one another:
|
|
||||||
|
|
||||||
```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"
|
```toml title="pyproject.toml"
|
||||||
[tool.uv]
|
[tool.uv]
|
||||||
|
|
@ -439,25 +383,9 @@ conflicts = [
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
Now, running `uv lock` will succeed. Note though, that now you cannot install both `extra1` and
|
Or, to declare the development dependency groups `group1` and `group2` incompatible:
|
||||||
`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"
|
```toml title="pyproject.toml"
|
||||||
[dependency-groups]
|
|
||||||
group1 = ["numpy==2.1.2"]
|
|
||||||
group2 = ["numpy==2.0.0"]
|
|
||||||
|
|
||||||
[tool.uv]
|
[tool.uv]
|
||||||
conflicts = [
|
conflicts = [
|
||||||
[
|
[
|
||||||
|
|
@ -467,4 +395,39 @@ conflicts = [
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
The only difference with conflicting extras is that you need to use `group` instead of `extra`.
|
See the [resolution documentation](../resolution.md#conflicting-dependencies) for more.
|
||||||
|
|
||||||
|
## Limited resolution environments
|
||||||
|
|
||||||
|
If your project supports a more limited set of platforms or Python versions, you can constrain the
|
||||||
|
set of solved platforms via the `environments` setting, which accepts a list of PEP 508 environment
|
||||||
|
markers. For example, to constrain the lockfile to macOS and Linux, and exclude Windows:
|
||||||
|
|
||||||
|
```toml title="pyproject.toml"
|
||||||
|
[tool.uv]
|
||||||
|
environments = [
|
||||||
|
"sys_platform == 'darwin'",
|
||||||
|
"sys_platform == 'linux'",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
See the [resolution documentation](../resolution.md#limited-resolution-environments) for more.
|
||||||
|
|
||||||
|
## Required environments
|
||||||
|
|
||||||
|
If your project _must_ support a specific platform or Python version, you can mark that platform as
|
||||||
|
required via the `required-environments` setting. For example, to require that the project supports
|
||||||
|
Intel macOS:
|
||||||
|
|
||||||
|
```toml title="pyproject.toml"
|
||||||
|
[tool.uv]
|
||||||
|
required-environments = [
|
||||||
|
"sys_platform == 'darwin' and platform_machine == 'x86_64'",
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
The `required-environments` setting is only relevant for packages that do not publish a source
|
||||||
|
distribution (like PyTorch), as such packages can _only_ be installed on environments covered by the
|
||||||
|
set of pre-built binary distributions (wheels) published by that package.
|
||||||
|
|
||||||
|
See the [resolution documentation](../resolution.md#required-environments) for more.
|
||||||
|
|
|
||||||
|
|
@ -453,6 +453,77 @@ though only `name`, `version`, `requires-dist`, `requires-python`, and `provides
|
||||||
uv. The `version` field is also considered optional. If omitted, the metadata will be used for all
|
uv. The `version` field is also considered optional. If omitted, the metadata will be used for all
|
||||||
versions of the specified package.
|
versions of the specified package.
|
||||||
|
|
||||||
|
## Conflicting dependencies
|
||||||
|
|
||||||
|
uv requires that all optional dependencies ("extras") declared by the project are compatible with
|
||||||
|
each other and resolves all optional dependencies together when creating the lockfile.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
To work around this, uv supports declaring conflicting extras. For example, consider two sets of
|
||||||
|
optional dependencies that conflict with one another:
|
||||||
|
|
||||||
|
```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 from conflicting extras is that you need to use the `group` key instead of
|
||||||
|
`extra`.
|
||||||
|
|
||||||
## Lower bounds
|
## Lower bounds
|
||||||
|
|
||||||
By default, `uv add` adds lower bounds to dependencies and, when using uv to manage projects, uv
|
By default, `uv add` adds lower bounds to dependencies and, when using uv to manage projects, uv
|
||||||
|
|
@ -513,11 +584,6 @@ reading and extracting archives in the following formats:
|
||||||
- lzma tarball (`.tar.lzma`)
|
- lzma tarball (`.tar.lzma`)
|
||||||
- zip (`.zip`)
|
- zip (`.zip`)
|
||||||
|
|
||||||
## Learn more
|
|
||||||
|
|
||||||
For more details about the internals of the resolver, see the
|
|
||||||
[resolver reference](../reference/resolver-internals.md) documentation.
|
|
||||||
|
|
||||||
## Lockfile versioning
|
## Lockfile versioning
|
||||||
|
|
||||||
The `uv.lock` file uses a versioned schema. The schema version is included in the `version` field of
|
The `uv.lock` file uses a versioned schema. The schema version is included in the `version` field of
|
||||||
|
|
@ -539,3 +605,8 @@ other words, lockfiles may only be rejected across minor releases.
|
||||||
The `revision` field of the lockfile is used to track backwards compatible changes to the lockfile.
|
The `revision` field of the lockfile is used to track backwards compatible changes to the lockfile.
|
||||||
For example, adding a new field to distributions. Changes to the revision will not cause older
|
For example, adding a new field to distributions. Changes to the revision will not cause older
|
||||||
versions of uv to error.
|
versions of uv to error.
|
||||||
|
|
||||||
|
## Learn more
|
||||||
|
|
||||||
|
For more details about the internals of the resolver, see the
|
||||||
|
[resolver reference](../reference/resolver-internals.md) documentation.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue