Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions crates/uv/src/commands/project/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -894,13 +894,17 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
Some(spec) => {
debug!("Syncing ephemeral requirements");

// Read the build constraints from the lock file.
let build_constraints = lock
.as_ref()
.map(|(lock, path)| lock.build_constraints(path));

let result = CachedEnvironment::from_spec(
EnvironmentSpecification::from(spec).with_lock(
lock.as_ref()
.map(|(lock, install_path)| (lock, install_path.as_ref())),
),
// TODO(bluefact): Respect build constraints for `uv run --with` dependencies.
Constraints::default(),
build_constraints.unwrap_or_default(),
&base_interpreter,
&settings,
&network_settings,
Expand Down
75 changes: 75 additions & 0 deletions crates/uv/tests/it/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1266,6 +1266,81 @@ fn run_with() -> Result<()> {
Ok(())
}

#[test]
fn run_with_build_constraints() -> Result<()> {
let context = TestContext::new("3.8");

let pyproject_toml = context.temp_dir.child("pyproject.toml");
pyproject_toml.write_str(indoc! { r#"
[project]
name = "foo"
version = "1.0.0"
requires-python = ">=3.8"
dependencies = ["anyio"]

[tool.uv]
build-constraint-dependencies = ["setuptools==1"]
"#
})?;

let test_script = context.temp_dir.child("main.py");
test_script.write_str(indoc! { r"
import os
"
})?;

// Installing requests with incompatible build constraints should fail.
uv_snapshot!(context.filters(), context.run().arg("--with").arg("requests==1.2").arg("main.py"), @r###"
success: false
exit_code: 1
----- stdout -----

----- stderr -----
Resolved 6 packages in [TIME]
Prepared 5 packages in [TIME]
Installed 5 packages in [TIME]
+ anyio==4.3.0
+ exceptiongroup==1.2.0
+ idna==3.6
+ sniffio==1.3.1
+ typing-extensions==4.10.0
Resolved 1 package in [TIME]
× Failed to download and build `requests==1.2.0`
├─▶ Failed to resolve requirements from `setup.py` build
├─▶ No solution found when resolving: `setuptools>=40.8.0`
╰─▶ Because you require setuptools>=40.8.0 and setuptools==1, we can conclude that your requirements are unsatisfiable.
"###);

// Change the build constraint to be compatible with `requests==1.2`.
pyproject_toml.write_str(indoc! { r#"
[project]
name = "foo"
version = "1.0.0"
requires-python = ">=3.8"
dependencies = ["anyio"]

[tool.uv]
build-constraint-dependencies = ["setuptools>=42"]
"#
})?;

uv_snapshot!(context.filters(), context.run().arg("--with").arg("requests==1.2").arg("main.py"), @r###"
success: true
exit_code: 0
----- stdout -----

----- stderr -----
Resolved 6 packages in [TIME]
Audited 5 packages in [TIME]
Resolved 1 package in [TIME]
Prepared 1 package in [TIME]
Installed 1 package in [TIME]
+ requests==1.2.0
"###);

Ok(())
}

/// Sync all members in a workspace.
#[test]
fn run_in_workspace() -> Result<()> {
Expand Down
Loading