diff --git a/crates/uv-settings/src/settings.rs b/crates/uv-settings/src/settings.rs index 8f580b9d6844..0557fb146228 100644 --- a/crates/uv-settings/src/settings.rs +++ b/crates/uv-settings/src/settings.rs @@ -40,13 +40,9 @@ pub struct Options { pub top_level: ResolverInstallerOptions, #[option_group] pub pip: Option, - #[cfg_attr( - feature = "schemars", - schemars( - with = "Option>", - description = "PEP 508 style requirements, e.g. `ruff==0.5.0`, or `ruff @ https://...`." - ) - )] + + // NOTE(charlie): These fields are shared with `ToolUv` in + // `crates/uv-workspace/src/pyproject.rs`, and the documentation lives on that struct. pub override_dependencies: Option>>, pub constraint_dependencies: Option>>, diff --git a/crates/uv-workspace/src/pyproject.rs b/crates/uv-workspace/src/pyproject.rs index f4d86ae3b390..559a6c931fcd 100644 --- a/crates/uv-workspace/src/pyproject.rs +++ b/crates/uv-workspace/src/pyproject.rs @@ -137,14 +137,66 @@ pub struct ToolUv { "# )] pub environments: Option, + /// Overrides to apply when resolving the project's dependencies. + /// + /// Overrides are used to force selection of a specific version of a package, regardless of the + /// version requested by any other package, and regardless of whether choosing that version + /// would typically constitute an invalid resolution. + /// + /// While constraints are _additive_, in that they're combined with the requirements of the + /// constituent packages, overrides are _absolute_, in that they completely replace the + /// requirements of any constituent packages. + /// + /// !!! note + /// In `uv lock`, `uv sync`, and `uv run`, uv will only read `override-dependencies` from + /// the `pyproject.toml` at the workspace root, and will ignore any declarations in other + /// workspace members or `uv.toml` files. #[cfg_attr( feature = "schemars", schemars( with = "Option>", - description = "PEP 508-style requirements, e.g. `ruff==0.5.0`, or `ruff @ https://...`." + description = "PEP 508-style requirements, e.g., `ruff==0.5.0`, or `ruff @ https://...`." ) )] + #[option( + default = r#"[]"#, + value_type = "list[str]", + example = r#" + # Always install Werkzeug 2.3.0, regardless of whether transitive dependencies request + # a different version. + override-dependencies = ["werkzeug==2.3.0"] + "# + )] pub override_dependencies: Option>>, + /// Constraints to apply when resolving the project's dependencies. + /// + /// Constraints are used to restrict the versions of dependencies that are selected during + /// resolution. + /// + /// Including a package as a constraint will _not_ trigger installation of the package on its + /// own; instead, the package must be requested elsewhere in the project's first-party or + /// transitive dependencies. + /// + /// !!! note + /// In `uv lock`, `uv sync`, and `uv run`, uv will only read `constraint-dependencies` from + /// the `pyproject.toml` at the workspace root, and will ignore any declarations in other + /// workspace members or `uv.toml` files. + #[cfg_attr( + feature = "schemars", + schemars( + with = "Option>", + description = "PEP 508-style requirements, e.g., `ruff==0.5.0`, or `ruff @ https://...`." + ) + )] + #[option( + default = r#"[]"#, + value_type = "list[str]", + example = r#" + # Ensure that the grpcio version is always less than 1.65, if it's requested by a + # transitive dependency. + constraint-dependencies = ["grpcio<1.65"] + "# + )] pub constraint_dependencies: Option>>, } diff --git a/docs/reference/settings.md b/docs/reference/settings.md index 25f80f258d55..f316ebf4d4a9 100644 --- a/docs/reference/settings.md +++ b/docs/reference/settings.md @@ -168,6 +168,47 @@ specified as `KEY=VALUE` pairs. --- +#### [`constraint-dependencies`](#constraint-dependencies) {: #constraint-dependencies } + +Constraints to apply when resolving the project's dependencies. + +Constraints are used to restrict the versions of dependencies that are selected during +resolution. + +Including a package as a constraint will _not_ trigger installation of the package on its +own; instead, the package must be requested elsewhere in the project's first-party or +transitive dependencies. + +!!! note + In `uv lock`, `uv sync`, and `uv run`, uv will only read `constraint-dependencies` from + the `pyproject.toml` at the workspace root, and will ignore any declarations in other + workspace members or `uv.toml` files. + +**Default value**: `[]` + +**Type**: `list[str]` + +**Example usage**: + +=== "pyproject.toml" + + ```toml + [tool.uv] + # Ensure that the grpcio version is always less than 1.65, if it's requested by a + # transitive dependency. + constraint-dependencies = ["grpcio<1.65"] + ``` +=== "uv.toml" + + ```toml + + # Ensure that the grpcio version is always less than 1.65, if it's requested by a + # transitive dependency. + constraint-dependencies = ["grpcio<1.65"] + ``` + +--- + #### [`dev-dependencies`](#dev-dependencies) {: #dev-dependencies } The project's development dependencies. Development dependencies will be installed by @@ -772,6 +813,48 @@ Disable network access, relying only on locally cached data and locally availabl --- +#### [`override-dependencies`](#override-dependencies) {: #override-dependencies } + +Overrides to apply when resolving the project's dependencies. + +Overrides are used to force selection of a specific version of a package, regardless of the +version requested by any other package, and regardless of whether choosing that version +would typically constitute an invalid resolution. + +While constraints are _additive_, in that they're combined with the requirements of the +constituent packages, overrides are _absolute_, in that they completely replace the +requirements of any constituent packages. + +!!! note + In `uv lock`, `uv sync`, and `uv run`, uv will only read `override-dependencies` from + the `pyproject.toml` at the workspace root, and will ignore any declarations in other + workspace members or `uv.toml` files. + +**Default value**: `[]` + +**Type**: `list[str]` + +**Example usage**: + +=== "pyproject.toml" + + ```toml + [tool.uv] + # Always install Werkzeug 2.3.0, regardless of whether transitive dependencies request + # a different version. + override-dependencies = ["werkzeug==2.3.0"] + ``` +=== "uv.toml" + + ```toml + + # Always install Werkzeug 2.3.0, regardless of whether transitive dependencies request + # a different version. + override-dependencies = ["werkzeug==2.3.0"] + ``` + +--- + #### [`prerelease`](#prerelease) {: #prerelease } The strategy to use when considering pre-release versions. diff --git a/uv.schema.json b/uv.schema.json index 6fe0959f999b..871fa0e12eb3 100644 --- a/uv.schema.json +++ b/uv.schema.json @@ -57,12 +57,13 @@ ] }, "constraint-dependencies": { + "description": "PEP 508-style requirements, e.g., `ruff==0.5.0`, or `ruff @ https://...`.", "type": [ "array", "null" ], "items": { - "$ref": "#/definitions/Requirement" + "type": "string" } }, "dev-dependencies": { @@ -254,7 +255,7 @@ ] }, "override-dependencies": { - "description": "PEP 508-style requirements, e.g. `ruff==0.5.0`, or `ruff @ https://...`.", + "description": "PEP 508-style requirements, e.g., `ruff==0.5.0`, or `ruff @ https://...`.", "type": [ "array", "null"