diff --git a/crates/uv-cli/src/lib.rs b/crates/uv-cli/src/lib.rs index e9ae8243d..7bcce8dcd 100644 --- a/crates/uv-cli/src/lib.rs +++ b/crates/uv-cli/src/lib.rs @@ -1608,7 +1608,7 @@ pub struct PipCompileArgs { /// /// Multiple packages may be provided. Disable binaries for all packages with `:all:`. /// Clear previously specified packages with `:none:`. - #[arg(long, conflicts_with = "no_build")] + #[arg(long, value_delimiter = ',', conflicts_with = "no_build")] pub no_binary: Option>, /// Only use pre-built wheels; don't build source distributions. @@ -1619,7 +1619,7 @@ pub struct PipCompileArgs { /// /// Multiple packages may be provided. Disable binaries for all packages with `:all:`. /// Clear previously specified packages with `:none:`. - #[arg(long, conflicts_with = "no_build")] + #[arg(long, value_delimiter = ',', conflicts_with = "no_build")] pub only_binary: Option>, /// The Python version to use for resolution. @@ -1969,7 +1969,7 @@ pub struct PipSyncArgs { /// /// Multiple packages may be provided. Disable binaries for all packages with `:all:`. Clear /// previously specified packages with `:none:`. - #[arg(long, conflicts_with = "no_build")] + #[arg(long, value_delimiter = ',', conflicts_with = "no_build")] pub no_binary: Option>, /// Only use pre-built wheels; don't build source distributions. @@ -1980,7 +1980,7 @@ pub struct PipSyncArgs { /// /// Multiple packages may be provided. Disable binaries for all packages with `:all:`. Clear /// previously specified packages with `:none:`. - #[arg(long, conflicts_with = "no_build")] + #[arg(long, value_delimiter = ',', conflicts_with = "no_build")] pub only_binary: Option>, /// Allow sync of empty requirements, which will clear the environment of all packages. @@ -2346,7 +2346,7 @@ pub struct PipInstallArgs { /// /// Multiple packages may be provided. Disable binaries for all packages with `:all:`. Clear /// previously specified packages with `:none:`. - #[arg(long, conflicts_with = "no_build")] + #[arg(long, value_delimiter = ',', conflicts_with = "no_build")] pub no_binary: Option>, /// Only use pre-built wheels; don't build source distributions. @@ -2357,7 +2357,7 @@ pub struct PipInstallArgs { /// /// Multiple packages may be provided. Disable binaries for all packages with `:all:`. Clear /// previously specified packages with `:none:`. - #[arg(long, conflicts_with = "no_build")] + #[arg(long, value_delimiter = ',', conflicts_with = "no_build")] pub only_binary: Option>, /// The minimum Python version that should be supported by the requirements (e.g., `3.7` or diff --git a/crates/uv/tests/it/pip_install.rs b/crates/uv/tests/it/pip_install.rs index e7129c40b..55339586e 100644 --- a/crates/uv/tests/it/pip_install.rs +++ b/crates/uv/tests/it/pip_install.rs @@ -2765,6 +2765,37 @@ fn install_no_binary_overrides_only_binary_all() { context.assert_command("import anyio").success(); } +/// Accept comma-separated values for `--no-binary` (pip compatibility) +#[test] +fn install_no_binary_comma_separated() { + let context = TestContext::new("3.12"); + + // Use comma-separated format for `--no-binary` + let mut command = context.pip_install(); + command + .arg("anyio") + .arg("--no-binary=idna,sniffio") + .arg("--strict"); + uv_snapshot!( + command, + @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 3 packages in [TIME] + Prepared 3 packages in [TIME] + Installed 3 packages in [TIME] + + anyio==4.3.0 + + idna==3.6 + + sniffio==1.3.1 + "### + ); + + context.assert_command("import anyio").success(); +} + /// Disable binaries with an environment variable /// TODO(zanieb): This is not yet implemented #[test] @@ -2876,6 +2907,37 @@ fn install_only_binary_overrides_no_binary_all() { context.assert_command("import anyio").success(); } +/// Accept comma-separated values for `--only-binary` (pip compatibility) +#[test] +fn install_only_binary_comma_separated() { + let context = TestContext::new("3.12"); + + // Use comma-separated format for `--only-binary` + let mut command = context.pip_install(); + command + .arg("anyio") + .arg("--only-binary=idna,sniffio") + .arg("--strict"); + uv_snapshot!( + command, + @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 3 packages in [TIME] + Prepared 3 packages in [TIME] + Installed 3 packages in [TIME] + + anyio==4.3.0 + + idna==3.6 + + sniffio==1.3.1 + "### + ); + + context.assert_command("import anyio").success(); +} + /// Overlapping usage of `--no-binary` and `--only-binary` // TODO(zanieb): We should have a better error message here #[test]