From 25f0391bc7e1d9f2863683a605c98d6f6d368cb5 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Sun, 20 Jul 2025 13:56:37 -0400 Subject: [PATCH] Disallow multiple pylock.toml files --- crates/uv-requirements/src/specification.rs | 11 ++-- crates/uv/tests/it/pip_install.rs | 58 +++++++++++++++++++++ 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/crates/uv-requirements/src/specification.rs b/crates/uv-requirements/src/specification.rs index 4c5741392..192e586c3 100644 --- a/crates/uv-requirements/src/specification.rs +++ b/crates/uv-requirements/src/specification.rs @@ -254,22 +254,19 @@ impl RequirementsSpecification { .iter() .any(|source| matches!(source, RequirementsSource::PylockToml(..))) { - if requirements - .iter() - .any(|source| !matches!(source, RequirementsSource::PylockToml(..))) - { + if requirements.len() > 1 { return Err(anyhow::anyhow!( - "Cannot specify additional requirements alongside a `pylock.toml` file", + "Cannot specify additional requirements with a `pylock.toml` file", )); } if !constraints.is_empty() { return Err(anyhow::anyhow!( - "Cannot specify additional requirements with a `pylock.toml` file" + "Cannot specify constraints with a `pylock.toml` file" )); } if !overrides.is_empty() { return Err(anyhow::anyhow!( - "Cannot specify constraints with a `pylock.toml` file" + "Cannot specify overrides with a `pylock.toml` file" )); } if !groups.is_empty() { diff --git a/crates/uv/tests/it/pip_install.rs b/crates/uv/tests/it/pip_install.rs index a977ac813..f69ae6651 100644 --- a/crates/uv/tests/it/pip_install.rs +++ b/crates/uv/tests/it/pip_install.rs @@ -10730,6 +10730,64 @@ fn change_layout_custom_directory() -> Result<()> { Ok(()) } +#[test] +fn pep_751_reject_additional_requirements() -> Result<()> { + let context = TestContext::new("3.12"); + + context.temp_dir.child("pylock.toml").touch()?; + context.temp_dir.child("requirements.txt").touch()?; + + // Disallow `pylock.toml` and `requirements.txt` in a single command. + uv_snapshot!(context.filters(), context.pip_install() + .arg("--preview") + .arg("-r") + .arg("pylock.toml") + .arg("-r") + .arg("requirements.txt"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: Cannot specify additional requirements with a `pylock.toml` file + " + ); + + // Disallow multiple `pylock.toml` files in a single command. + uv_snapshot!(context.filters(), context.pip_install() + .arg("--preview") + .arg("-r") + .arg("pylock.toml") + .arg("-r") + .arg("pylock.toml"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: Cannot specify additional requirements with a `pylock.toml` file + " + ); + + // Disallow `pylock.toml` and a constraint in a single command. + uv_snapshot!(context.filters(), context.pip_install() + .arg("--preview") + .arg("-r") + .arg("pylock.toml") + .arg("-c") + .arg("requirements.txt"), @r" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: Cannot specify constraints with a `pylock.toml` file + " + ); + + Ok(()) +} + #[test] fn pep_751_install_registry_wheel() -> Result<()> { let context = TestContext::new("3.12");