Skip to content

Commit

Permalink
Tweak tests and docs
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Feb 18, 2025
1 parent d22fb8e commit b33c5a5
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 42 deletions.
17 changes: 9 additions & 8 deletions crates/uv-workspace/src/pyproject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -479,18 +479,19 @@ pub struct ToolUv {
)]
pub constraint_dependencies: Option<Vec<uv_pep508::Requirement<VerbatimParsedUrl>>>,

/// Constrains to build dependencies using the given requirements files when building source
/// distributions.
/// Constraints to apply when solving build dependencies.
///
/// 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.
/// Build constraints are used to restrict the versions of build dependencies that are selected
/// when building a package during resolution or installation.
///
/// Including a package as a constraint will _not_ trigger installation of the package during
/// a build; instead, the package must be requested elsewhere in the project's build dependency
/// graph.
///
/// !!! note
/// In `uv lock`, `uv sync`, and `uv run`, uv will only read `build-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(
Expand All @@ -502,8 +503,8 @@ pub struct ToolUv {
default = "[]",
value_type = "list[str]",
example = r#"
# Ensure that the `setuptools 60.0.0` is used to build any packages with a build dependency
on `setuptools`.
# Ensure that the setuptools v60.0.0 is used whenever a package has a build dependency
# on setuptools.
build-constraint-dependencies = ["setuptools==60.0.0"]
"#
)]
Expand Down
20 changes: 9 additions & 11 deletions crates/uv/tests/it/lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1897,10 +1897,8 @@ fn lock_project_with_build_constraints() -> Result<()> {
requires-python = ">=3.12"
dependencies = ["anyio==3.7.0"]

# This should be ignored because none of the dependencies requires `setuptools`
[tool.uv]
constraint-dependencies = ["idna<3.4"]

# This should be ignored because none of the dependencies requires 'setuptools'
build-constraint-dependencies = ["setuptools==1"]
"#,
)?;
Expand Down Expand Up @@ -1934,11 +1932,10 @@ fn lock_project_with_build_constraints() -> Result<()> {
Prepared 3 packages in [TIME]
Installed 3 packages in [TIME]
+ anyio==3.7.0
+ idna==3.3
+ idna==3.6
+ sniffio==1.3.1
"###);

//
let pyproject_toml = context.temp_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"
Expand All @@ -1948,6 +1945,7 @@ fn lock_project_with_build_constraints() -> Result<()> {
requires-python = ">=3.8"
dependencies = ["requests==1.2"]

# This should fail the operation, since `requests` depends on `setuptools` at build time.
[tool.uv]
build-constraint-dependencies = ["setuptools==1"]
"#,
Expand All @@ -1972,22 +1970,22 @@ fn lock_project_with_build_constraints() -> Result<()> {
/// Lock a project with `uv.tool.build-constraint-dependencies` that reference `tool.uv.sources`.
#[test]
fn lock_project_with_build_constraint_sources() -> Result<()> {
let context = TestContext::new("3.12");
let context = TestContext::new("3.9");

let pyproject_toml = context.temp_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["anyio==3.7.0"]
requires-python = ">=3.8"
dependencies = ["requests==1.2"]

[tool.uv]
constraint-dependencies = ["idna<3.4"]
build-constraint-dependencies = ["setuptools==75.8.0"]

[tool.uv.sources]
idna = { url = "https://files.pythonhosted.org/packages/d7/77/ff688d1504cdc4db2a938e2b7b9adee5dd52e34efbd2431051efc9984de9/idna-3.2-py3-none-any.whl" }
setuptools = { url = "https://files.pythonhosted.org/packages/69/8a/b9dc7678803429e4a3bc9ba462fa3dd9066824d3c607490235c6a796be5a/setuptools-75.8.0-py3-none-any.whl" }
"#,
)?;

Expand All @@ -1997,7 +1995,7 @@ fn lock_project_with_build_constraint_sources() -> Result<()> {
----- stdout -----

----- stderr -----
Resolved 4 packages in [TIME]
Resolved 2 packages in [TIME]
"###);

// Re-run with `--locked`.
Expand Down
6 changes: 3 additions & 3 deletions crates/uv/tests/it/pip_install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7837,7 +7837,7 @@ fn compatible_build_constraint_in_pyproject_toml() -> Result<()> {
pyproject_toml.write_str(
r#"[tool.uv]
build-constraint-dependencies = [
"setuptools>=40",
"setuptools==40.8.0",
]
"#,
)?;
Expand All @@ -7864,7 +7864,7 @@ build-constraint-dependencies = [
fn incompatible_build_constraint_merged_with_pyproject_toml() -> Result<()> {
let context = TestContext::new("3.8");

// incompatible setuptools version in pyproject.toml, compatible in build_constraints.txt
// Incompatible setuptools version in pyproject.toml, compatible in build_constraints.txt.
let constraints_txt = context.temp_dir.child("build_constraints.txt");
constraints_txt.write_str("setuptools>=40")?;
let pyproject_toml = context.temp_dir.child("pyproject.toml");
Expand Down Expand Up @@ -7892,7 +7892,7 @@ build-constraint-dependencies = [
"###
);

// compatible setuptools version in pyproject.toml, incompatible in build_constraints.txt
// Compatible setuptools version in pyproject.toml, incompatible in build_constraints.txt.
let constraints_txt = context.temp_dir.child("build_constraints.txt");
constraints_txt.write_str("setuptools==1")?;
let pyproject_toml = context.temp_dir.child("pyproject.toml");
Expand Down
21 changes: 18 additions & 3 deletions docs/pip/compile.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,24 @@ when building runtime dependencies.

Build constraint files are `requirements.txt`-like files that only control the _version_ of a
build-time requirement. However, including a package in a build constraints file will _not_ trigger
its installation; instead, constraints apply only when the package is required as a direct or
transitive build-time dependency. Build constraints can be used to add bounds to dependencies that
are not explicitly declared as build-time dependencies of the current project.
its installation at build time; instead, constraints apply only when the package is required as a
direct or transitive build-time dependency. Build constraints can be used to add bounds to
dependencies that are not explicitly declared as build-time dependencies of the current project.

For example, if a package defines its build dependencies as follows:

```toml title="pyproject.toml"
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
```

Build constraints could be used to ensure that a specific version of `setuptools` is used for every
package in the workspace:

```python title="build-constraints.txt"
setuptools==75.0.0
```

uv will also read `build-constraint-dependencies` from the `pyproject.toml` at the workspace root,
and append them to those specified in the build constraints file.
Expand Down
16 changes: 9 additions & 7 deletions docs/reference/settings.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
## Project metadata
### [`build-constraint-dependencies`](#build-constraint-dependencies) {: #build-constraint-dependencies }

Constrains to build dependencies using the given requirements files when building source
distributions.
Constraints to apply when solving build dependencies.

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.
Build constraints are used to restrict the versions of build dependencies that are selected
when building a package during resolution or installation.

Including a package as a constraint will _not_ trigger installation of the package during
a build; instead, the package must be requested elsewhere in the project's build dependency
graph.

!!! note
In `uv lock`, `uv sync`, and `uv run`, uv will only read `build-constraint-dependencies` from
Expand All @@ -21,8 +23,8 @@ transitive dependencies.

```toml title="pyproject.toml"
[tool.uv]
# Ensure that the `setuptools 60.0.0` is used to build any packages with a build dependency
on `setuptools`.
# Ensure that the setuptools v60.0.0 is used whenever a package has a build dependency
# on setuptools.
build-constraint-dependencies = ["setuptools==60.0.0"]
```

Expand Down
20 changes: 10 additions & 10 deletions docs/reference/troubleshooting/build-failures.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,27 +288,27 @@ uv will avoid using an old version of `apache-beam`.
Constraints can also be defined for indirect dependencies using `constraints.txt` files or the
[`constraint-dependencies`](../settings.md#constraint-dependencies) setting.

### Old Version of a Build Dependency is Used
### Old Version of a build dependency is used

If a package fails to build because `uv` selects an incompatible or outdated version of a build-time
dependency, you can enforce constraints specifically for build dependencies. The
[`build-constraint-dependencies`](../settings.md#build-constraint-dependencies) setting or a
`build-constraints.txt` file can help ensure that `uv` selects an appropriate version of build
requirements.
[`build-constraint-dependencies`](../settings.md#build-constraint-dependencies) setting (or an
analogous `build-constraints.txt` file) can be used to ensure that `uv` selects an appropriate
version of a given build requirements.

For example, the issue described in
[uv#5551](https://github.com/astral-sh/uv/issues/5551#issuecomment-2256055975) can be addressed by
specifying a build constraint that excludes `setuptools` version `72.0.0`, which causes a build
failure for certain packages. This can be done as follows:
[#5551](https://github.com/astral-sh/uv/issues/5551#issuecomment-2256055975) could be addressed by
specifying a build constraint that excludes `setuptools` version `72.0.0`:

```toml title="pyproject.toml"
[tool.uv]
# Prevent setuptools version 72.0.0 from being used as a build dependency
# Prevent setuptools version 72.0.0 from being used as a build dependency.
build-constraint-dependencies = ["setuptools!=72.0.0"]
```

This ensures that any package requiring `setuptools` during the build process will avoid using the
problematic version, preventing build failures caused by incompatible build dependencies.
The build constraint will thus ensure that any package requiring `setuptools` during the build
process will avoid using the problematic version, preventing build failures caused by incompatible
build dependencies.

### Package is only needed for an unused platform

Expand Down

0 comments on commit b33c5a5

Please sign in to comment.