diff --git a/crates/uv/src/commands/project/mod.rs b/crates/uv/src/commands/project/mod.rs index 4b0995a0227b4..7248be90de084 100644 --- a/crates/uv/src/commands/project/mod.rs +++ b/crates/uv/src/commands/project/mod.rs @@ -2827,11 +2827,22 @@ pub(crate) fn script_specification( .map_ok(LoweredRequirement::into_inner) }) .collect::, _>>()?; + let excludes = script + .metadata() + .tool + .as_ref() + .and_then(|tool| tool.uv.as_ref()) + .and_then(|uv| uv.exclude_dependencies.as_ref()) + .into_iter() + .flatten() + .cloned() + .collect::>(); - Ok(Some(RequirementsSpecification::from_overrides( + Ok(Some(RequirementsSpecification::from_excludes( requirements, constraints, overrides, + excludes, ))) } diff --git a/crates/uv/tests/it/run.rs b/crates/uv/tests/it/run.rs index 58b656771e646..b40c9bf0fc408 100644 --- a/crates/uv/tests/it/run.rs +++ b/crates/uv/tests/it/run.rs @@ -844,6 +844,43 @@ fn run_pep723_script_overrides() -> Result<()> { Ok(()) } +/// Run a PEP 723-compatible script with `tool.uv` excludes. +#[test] +fn run_pep723_script_excludes() -> Result<()> { + let context = uv_test::test_context!("3.12"); + + let test_script = context.temp_dir.child("main.py"); + test_script.write_str(indoc! { r#" + # /// script + # requires-python = ">=3.11" + # dependencies = [ + # "anyio>=3", + # ] + # + # [tool.uv] + # exclude-dependencies = ["idna"] + # /// + + import anyio + "# + })?; + + uv_snapshot!(context.filters(), context.run().arg("main.py"), @" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 2 packages in [TIME] + Prepared 2 packages in [TIME] + Installed 2 packages in [TIME] + + anyio==4.3.0 + + sniffio==1.3.1 + "); + + Ok(()) +} + /// Run a PEP 723-compatible script with `tool.uv` build constraints. #[test] fn run_pep723_script_build_constraints() -> Result<()> {