From 13e7ad62cb0d3ca8bf5eeee407d658d6d887d5f9 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Mon, 15 Dec 2025 20:18:40 -0500 Subject: [PATCH] Accept `--torch-backend` in `[tool.uv]` (#17116) ## Summary I'd like to add `--torch-backend` to `uv tool`, so this PR lifts the setting out of `[tool.uv.pip]`. Like other settings, if it's in `[tool.uv.pip]`, it will take preference for `uv pip` operations. --- crates/uv-cli/src/options.rs | 1 + crates/uv-settings/src/lib.rs | 4 ++++ crates/uv-settings/src/settings.rs | 31 +++++++++++++++++++++++++++++ crates/uv/src/settings.rs | 2 ++ crates/uv/tests/it/show_settings.rs | 3 ++- uv.schema.json | 13 +++++++++++- 6 files changed, 52 insertions(+), 2 deletions(-) diff --git a/crates/uv-cli/src/options.rs b/crates/uv-cli/src/options.rs index fe196ce68..1ed9ff851 100644 --- a/crates/uv-cli/src/options.rs +++ b/crates/uv-cli/src/options.rs @@ -495,5 +495,6 @@ pub fn resolver_installer_options( Some(no_binary_package) }, no_sources: if no_sources { Some(true) } else { None }, + torch_backend: None, } } diff --git a/crates/uv-settings/src/lib.rs b/crates/uv-settings/src/lib.rs index 4d370a6c4..ecc687229 100644 --- a/crates/uv-settings/src/lib.rs +++ b/crates/uv-settings/src/lib.rs @@ -336,6 +336,7 @@ fn warn_uv_toml_masked_fields(options: &Options) { no_build_package, no_binary, no_binary_package, + torch_backend, }, install_mirrors: PythonInstallMirrors { @@ -497,6 +498,9 @@ fn warn_uv_toml_masked_fields(options: &Options) { if no_binary_package.is_some() { masked_fields.push("no-binary-package"); } + if torch_backend.is_some() { + masked_fields.push("torch-backend"); + } if python_install_mirror.is_some() { masked_fields.push("python-install-mirror"); } diff --git a/crates/uv-settings/src/settings.rs b/crates/uv-settings/src/settings.rs index 8f8ca022b..8d38c1607 100644 --- a/crates/uv-settings/src/settings.rs +++ b/crates/uv-settings/src/settings.rs @@ -412,6 +412,7 @@ pub struct ResolverInstallerOptions { pub no_build_package: Option>, pub no_binary: Option, pub no_binary_package: Option>, + pub torch_backend: Option, } impl From for ResolverInstallerOptions { @@ -447,6 +448,7 @@ impl From for ResolverInstallerOptions { no_build_package, no_binary, no_binary_package, + torch_backend, } = value; Self { index, @@ -486,6 +488,7 @@ impl From for ResolverInstallerOptions { no_build_package, no_binary, no_binary_package, + torch_backend, } } } @@ -967,6 +970,28 @@ pub struct ResolverInstallerSchema { "# )] pub no_binary_package: Option>, + /// The backend to use when fetching packages in the PyTorch ecosystem. + /// + /// When set, uv will ignore the configured index URLs for packages in the PyTorch ecosystem, + /// and will instead use the defined backend. + /// + /// For example, when set to `cpu`, uv will use the CPU-only PyTorch index; when set to `cu126`, + /// uv will use the PyTorch index for CUDA 12.6. + /// + /// The `auto` mode will attempt to detect the appropriate PyTorch index based on the currently + /// installed CUDA drivers. + /// + /// This setting is only respected by `uv pip` commands. + /// + /// This option is in preview and may change in any future release. + #[option( + default = "null", + value_type = "str", + example = r#" + torch-backend = "auto" + "# + )] + pub torch_backend: Option, } /// Shared settings, relevant to all operations that might create managed python installations. @@ -1801,6 +1826,8 @@ pub struct PipOptions { /// The `auto` mode will attempt to detect the appropriate PyTorch index based on the currently /// installed CUDA drivers. /// + /// This setting is only respected by `uv pip` commands. + /// /// This option is in preview and may change in any future release. #[option( default = "null", @@ -2041,6 +2068,7 @@ impl From for ResolverInstallerOptions { no_build_package: value.no_build_package, no_binary: value.no_binary, no_binary_package: value.no_binary_package, + torch_backend: None, } } } @@ -2097,6 +2125,7 @@ pub struct OptionsWire { no_build_package: Option>, no_binary: Option, no_binary_package: Option>, + torch_backend: Option, // #[serde(flatten)] // install_mirror: PythonInstallMirrors, @@ -2189,6 +2218,7 @@ impl From for Options { no_build_package, no_binary, no_binary_package, + torch_backend, pip, cache_keys, override_dependencies, @@ -2262,6 +2292,7 @@ impl From for Options { no_build_package, no_binary, no_binary_package, + torch_backend, }, pip, cache_keys, diff --git a/crates/uv/src/settings.rs b/crates/uv/src/settings.rs index 71704b50d..204ce41b2 100644 --- a/crates/uv/src/settings.rs +++ b/crates/uv/src/settings.rs @@ -3520,6 +3520,7 @@ impl PipSettings { no_binary: top_level_no_binary, no_binary_package: top_level_no_binary_package, exclude_newer_package: top_level_exclude_newer_package, + torch_backend: top_level_torch_backend, } = top_level; // Merge the top-level options (`tool.uv`) with the pip-specific options (`tool.uv.pip`), @@ -3562,6 +3563,7 @@ impl PipSettings { let upgrade_package = upgrade_package.combine(top_level_upgrade_package); let reinstall = reinstall.combine(top_level_reinstall); let reinstall_package = reinstall_package.combine(top_level_reinstall_package); + let torch_backend = torch_backend.combine(top_level_torch_backend); Self { index_locations: IndexLocations::new( diff --git a/crates/uv/tests/it/show_settings.rs b/crates/uv/tests/it/show_settings.rs index ebdd271b6..bfd03da94 100644 --- a/crates/uv/tests/it/show_settings.rs +++ b/crates/uv/tests/it/show_settings.rs @@ -3573,6 +3573,7 @@ fn resolve_tool() -> anyhow::Result<()> { no_build_package: None, no_binary: None, no_binary_package: None, + torch_backend: None, }, settings: ResolverInstallerSettings { resolver: ResolverSettings { @@ -4684,7 +4685,7 @@ fn resolve_config_file() -> anyhow::Result<()> { | 1 | [project] | ^^^^^^^ - unknown field `project`, expected one of `required-version`, `native-tls`, `offline`, `no-cache`, `cache-dir`, `preview`, `python-preference`, `python-downloads`, `concurrent-downloads`, `concurrent-builds`, `concurrent-installs`, `index`, `index-url`, `extra-index-url`, `no-index`, `find-links`, `index-strategy`, `keyring-provider`, `allow-insecure-host`, `resolution`, `prerelease`, `fork-strategy`, `dependency-metadata`, `config-settings`, `config-settings-package`, `no-build-isolation`, `no-build-isolation-package`, `extra-build-dependencies`, `extra-build-variables`, `exclude-newer`, `exclude-newer-package`, `link-mode`, `compile-bytecode`, `no-sources`, `upgrade`, `upgrade-package`, `reinstall`, `reinstall-package`, `no-build`, `no-build-package`, `no-binary`, `no-binary-package`, `python-install-mirror`, `pypy-install-mirror`, `python-downloads-json-url`, `publish-url`, `trusted-publishing`, `check-url`, `add-bounds`, `pip`, `cache-keys`, `override-dependencies`, `exclude-dependencies`, `constraint-dependencies`, `build-constraint-dependencies`, `environments`, `required-environments`, `conflicts`, `workspace`, `sources`, `managed`, `package`, `default-groups`, `dependency-groups`, `dev-dependencies`, `build-backend` + unknown field `project`, expected one of `required-version`, `native-tls`, `offline`, `no-cache`, `cache-dir`, `preview`, `python-preference`, `python-downloads`, `concurrent-downloads`, `concurrent-builds`, `concurrent-installs`, `index`, `index-url`, `extra-index-url`, `no-index`, `find-links`, `index-strategy`, `keyring-provider`, `allow-insecure-host`, `resolution`, `prerelease`, `fork-strategy`, `dependency-metadata`, `config-settings`, `config-settings-package`, `no-build-isolation`, `no-build-isolation-package`, `extra-build-dependencies`, `extra-build-variables`, `exclude-newer`, `exclude-newer-package`, `link-mode`, `compile-bytecode`, `no-sources`, `upgrade`, `upgrade-package`, `reinstall`, `reinstall-package`, `no-build`, `no-build-package`, `no-binary`, `no-binary-package`, `torch-backend`, `python-install-mirror`, `pypy-install-mirror`, `python-downloads-json-url`, `publish-url`, `trusted-publishing`, `check-url`, `add-bounds`, `pip`, `cache-keys`, `override-dependencies`, `exclude-dependencies`, `constraint-dependencies`, `build-constraint-dependencies`, `environments`, `required-environments`, `conflicts`, `workspace`, `sources`, `managed`, `package`, `default-groups`, `dependency-groups`, `dev-dependencies`, `build-backend` " ); diff --git a/uv.schema.json b/uv.schema.json index 02497d26a..78784098a 100644 --- a/uv.schema.json +++ b/uv.schema.json @@ -595,6 +595,17 @@ } ] }, + "torch-backend": { + "description": "The backend to use when fetching packages in the PyTorch ecosystem.\n\nWhen set, uv will ignore the configured index URLs for packages in the PyTorch ecosystem,\nand will instead use the defined backend.\n\nFor example, when set to `cpu`, uv will use the CPU-only PyTorch index; when set to `cu126`,\nuv will use the PyTorch index for CUDA 12.6.\n\nThe `auto` mode will attempt to detect the appropriate PyTorch index based on the currently\ninstalled CUDA drivers.\n\nThis setting is only respected by `uv pip` commands.\n\nThis option is in preview and may change in any future release.", + "anyOf": [ + { + "$ref": "#/definitions/TorchMode" + }, + { + "type": "null" + } + ] + }, "trusted-publishing": { "description": "Configure trusted publishing.\n\nBy default, uv checks for trusted publishing when running in a supported environment, but\nignores it if it isn't configured.\n\nuv's supported environments for trusted publishing include GitHub Actions and GitLab CI/CD.", "anyOf": [ @@ -1716,7 +1727,7 @@ ] }, "torch-backend": { - "description": "The backend to use when fetching packages in the PyTorch ecosystem.\n\nWhen set, uv will ignore the configured index URLs for packages in the PyTorch ecosystem,\nand will instead use the defined backend.\n\nFor example, when set to `cpu`, uv will use the CPU-only PyTorch index; when set to `cu126`,\nuv will use the PyTorch index for CUDA 12.6.\n\nThe `auto` mode will attempt to detect the appropriate PyTorch index based on the currently\ninstalled CUDA drivers.\n\nThis option is in preview and may change in any future release.", + "description": "The backend to use when fetching packages in the PyTorch ecosystem.\n\nWhen set, uv will ignore the configured index URLs for packages in the PyTorch ecosystem,\nand will instead use the defined backend.\n\nFor example, when set to `cpu`, uv will use the CPU-only PyTorch index; when set to `cu126`,\nuv will use the PyTorch index for CUDA 12.6.\n\nThe `auto` mode will attempt to detect the appropriate PyTorch index based on the currently\ninstalled CUDA drivers.\n\nThis setting is only respected by `uv pip` commands.\n\nThis option is in preview and may change in any future release.", "anyOf": [ { "$ref": "#/definitions/TorchMode"