mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-24 05:35:04 +00:00
Allow conflicting extras in explicit index assignments (#9160)
## Summary This PR enables something like the "final boss" of PyTorch setups -- explicit support for CPU vs. GPU-enabled variants via extras: ```toml [project] name = "project" version = "0.1.0" requires-python = ">=3.13.0" dependencies = [] [project.optional-dependencies] cpu = [ "torch==2.5.1+cpu", ] gpu = [ "torch==2.5.1", ] [tool.uv.sources] torch = [ { index = "torch-cpu", extra = "cpu" }, { index = "torch-gpu", extra = "gpu" }, ] [[tool.uv.index]] name = "torch-cpu" url = "https://download.pytorch.org/whl/cpu" explicit = true [[tool.uv.index]] name = "torch-gpu" url = "https://download.pytorch.org/whl/cu124" explicit = true [tool.uv] conflicts = [ [ { extra = "cpu" }, { extra = "gpu" }, ], ] ``` It builds atop the conflicting extras work to allow sources to be marked as specific to a dedicated extra being enabled or disabled. As part of this work, sources now have an `extra` field. If a source has an `extra`, it means that the source is only applied to the requirement when defined within that optional group. For example, `{ index = "torch-cpu", extra = "cpu" }` above only applies to `"torch==2.5.1+cpu"`. The `extra` field does _not_ mean that the source is "enabled" when the extra is activated. For example, this wouldn't work: ```toml [project] name = "project" version = "0.1.0" requires-python = ">=3.13.0" dependencies = ["torch"] [tool.uv.sources] torch = [ { index = "torch-cpu", extra = "cpu" }, { index = "torch-gpu", extra = "gpu" }, ] [[tool.uv.index]] name = "torch-cpu" url = "https://download.pytorch.org/whl/cpu" explicit = true [[tool.uv.index]] name = "torch-gpu" url = "https://download.pytorch.org/whl/cu124" explicit = true ``` In this case, the sources would effectively be ignored. Extras are really confusing... but I think this is correct? We don't want enabling or disabling extras to affect resolution information that's _outside_ of the relevant optional group.
This commit is contained in:
parent
a88a3e5eba
commit
e4fc875afa
19 changed files with 1607 additions and 227 deletions
|
@ -1607,104 +1607,108 @@ mod tests {
|
|||
".workspace.packages.*.pyproject_toml" => "[PYPROJECT_TOML]"
|
||||
},
|
||||
@r###"
|
||||
{
|
||||
"project_root": "[ROOT]/albatross-root-workspace",
|
||||
"project_name": "albatross",
|
||||
"workspace": {
|
||||
"install_path": "[ROOT]/albatross-root-workspace",
|
||||
"packages": {
|
||||
"albatross": {
|
||||
"root": "[ROOT]/albatross-root-workspace",
|
||||
"project": {
|
||||
"name": "albatross",
|
||||
"version": "0.1.0",
|
||||
"requires-python": ">=3.12",
|
||||
"dependencies": [
|
||||
"bird-feeder",
|
||||
"tqdm>=4,<5"
|
||||
],
|
||||
"optional-dependencies": null
|
||||
},
|
||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||
},
|
||||
"bird-feeder": {
|
||||
"root": "[ROOT]/albatross-root-workspace/packages/bird-feeder",
|
||||
"project": {
|
||||
"name": "bird-feeder",
|
||||
"version": "1.0.0",
|
||||
"requires-python": ">=3.8",
|
||||
"dependencies": [
|
||||
"anyio>=4.3.0,<5",
|
||||
"seeds"
|
||||
],
|
||||
"optional-dependencies": null
|
||||
},
|
||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||
},
|
||||
"seeds": {
|
||||
"root": "[ROOT]/albatross-root-workspace/packages/seeds",
|
||||
"project": {
|
||||
"name": "seeds",
|
||||
"version": "1.0.0",
|
||||
"requires-python": ">=3.12",
|
||||
"dependencies": [
|
||||
"idna==3.6"
|
||||
],
|
||||
"optional-dependencies": null
|
||||
},
|
||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||
}
|
||||
},
|
||||
"sources": {
|
||||
"bird-feeder": [
|
||||
{
|
||||
"workspace": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"indexes": [],
|
||||
"pyproject_toml": {
|
||||
"project": {
|
||||
"name": "albatross",
|
||||
"version": "0.1.0",
|
||||
"requires-python": ">=3.12",
|
||||
"dependencies": [
|
||||
"bird-feeder",
|
||||
"tqdm>=4,<5"
|
||||
],
|
||||
"optional-dependencies": null
|
||||
},
|
||||
"tool": {
|
||||
"uv": {
|
||||
"sources": {
|
||||
"bird-feeder": [
|
||||
{
|
||||
"workspace": true
|
||||
}
|
||||
]
|
||||
{
|
||||
"project_root": "[ROOT]/albatross-root-workspace",
|
||||
"project_name": "albatross",
|
||||
"workspace": {
|
||||
"install_path": "[ROOT]/albatross-root-workspace",
|
||||
"packages": {
|
||||
"albatross": {
|
||||
"root": "[ROOT]/albatross-root-workspace",
|
||||
"project": {
|
||||
"name": "albatross",
|
||||
"version": "0.1.0",
|
||||
"requires-python": ">=3.12",
|
||||
"dependencies": [
|
||||
"bird-feeder",
|
||||
"tqdm>=4,<5"
|
||||
],
|
||||
"optional-dependencies": null
|
||||
},
|
||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||
},
|
||||
"index": null,
|
||||
"workspace": {
|
||||
"members": [
|
||||
"packages/*"
|
||||
"bird-feeder": {
|
||||
"root": "[ROOT]/albatross-root-workspace/packages/bird-feeder",
|
||||
"project": {
|
||||
"name": "bird-feeder",
|
||||
"version": "1.0.0",
|
||||
"requires-python": ">=3.8",
|
||||
"dependencies": [
|
||||
"anyio>=4.3.0,<5",
|
||||
"seeds"
|
||||
],
|
||||
"optional-dependencies": null
|
||||
},
|
||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||
},
|
||||
"seeds": {
|
||||
"root": "[ROOT]/albatross-root-workspace/packages/seeds",
|
||||
"project": {
|
||||
"name": "seeds",
|
||||
"version": "1.0.0",
|
||||
"requires-python": ">=3.12",
|
||||
"dependencies": [
|
||||
"idna==3.6"
|
||||
],
|
||||
"optional-dependencies": null
|
||||
},
|
||||
"pyproject_toml": "[PYPROJECT_TOML]"
|
||||
}
|
||||
},
|
||||
"sources": {
|
||||
"bird-feeder": [
|
||||
{
|
||||
"workspace": true,
|
||||
"extra": null,
|
||||
"group": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"indexes": [],
|
||||
"pyproject_toml": {
|
||||
"project": {
|
||||
"name": "albatross",
|
||||
"version": "0.1.0",
|
||||
"requires-python": ">=3.12",
|
||||
"dependencies": [
|
||||
"bird-feeder",
|
||||
"tqdm>=4,<5"
|
||||
],
|
||||
"exclude": null
|
||||
"optional-dependencies": null
|
||||
},
|
||||
"managed": null,
|
||||
"package": null,
|
||||
"default-groups": null,
|
||||
"dev-dependencies": null,
|
||||
"override-dependencies": null,
|
||||
"constraint-dependencies": null,
|
||||
"environments": null,
|
||||
"conflicts": null
|
||||
"tool": {
|
||||
"uv": {
|
||||
"sources": {
|
||||
"bird-feeder": [
|
||||
{
|
||||
"workspace": true,
|
||||
"extra": null,
|
||||
"group": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"index": null,
|
||||
"workspace": {
|
||||
"members": [
|
||||
"packages/*"
|
||||
],
|
||||
"exclude": null
|
||||
},
|
||||
"managed": null,
|
||||
"package": null,
|
||||
"default-groups": null,
|
||||
"dev-dependencies": null,
|
||||
"override-dependencies": null,
|
||||
"constraint-dependencies": null,
|
||||
"environments": null,
|
||||
"conflicts": null
|
||||
}
|
||||
},
|
||||
"dependency-groups": null
|
||||
}
|
||||
},
|
||||
"dependency-groups": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"###);
|
||||
"###);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue