From aa702bf3b281653d727a894fc4236e9acc8aee5f Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Mon, 4 Nov 2024 06:48:02 -0600 Subject: [PATCH] do not imply pre-release when `!=` operator is used (#7974) closes #6640 Could you suggest how I should test it? (already tested locally) --------- Co-authored-by: konstin Co-authored-by: Charles Tapley Hoyt Co-authored-by: Charlie Marsh --- crates/uv-resolver/src/prerelease.rs | 8 +++++-- crates/uv/tests/it/pip_compile.rs | 36 ++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/crates/uv-resolver/src/prerelease.rs b/crates/uv-resolver/src/prerelease.rs index 4a4cd492a171..ea6843a898c9 100644 --- a/crates/uv-resolver/src/prerelease.rs +++ b/crates/uv-resolver/src/prerelease.rs @@ -1,10 +1,11 @@ use uv_pypi_types::RequirementSource; -use uv_normalize::PackageName; - use crate::resolver::ForkSet; use crate::{DependencyMode, Manifest, ResolverEnvironment}; +use uv_normalize::PackageName; +use uv_pep440::Operator; + #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "clap", derive(clap::ValueEnum))] @@ -84,6 +85,9 @@ impl PrereleaseStrategy { if specifier .iter() + .filter(|spec| { + !matches!(spec.operator(), Operator::NotEqual | Operator::NotEqualStar) + }) .any(uv_pep440::VersionSpecifier::any_prerelease) { packages.add(&requirement, ()); diff --git a/crates/uv/tests/it/pip_compile.rs b/crates/uv/tests/it/pip_compile.rs index 0cfcc8194a99..352dead2b4d6 100644 --- a/crates/uv/tests/it/pip_compile.rs +++ b/crates/uv/tests/it/pip_compile.rs @@ -12686,3 +12686,39 @@ fn unsupported_requires_python_dynamic_metadata() -> Result<()> { Ok(()) } + +#[test] +fn negation_not_imply_prerelease() -> Result<()> { + let context = TestContext::new("3.12"); + + let requirements_in = context.temp_dir.child("requirements.in"); + requirements_in.write_str("flask<2.0.1, !=2.0.0rc1")?; + uv_snapshot!(context + .pip_compile() + .arg("requirements.in"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + # This file was autogenerated by uv via the following command: + # uv pip compile --cache-dir [CACHE_DIR] requirements.in + click==8.1.7 + # via flask + flask==2.0.0 + # via -r requirements.in + itsdangerous==2.1.2 + # via flask + jinja2==3.1.3 + # via flask + markupsafe==2.1.5 + # via + # jinja2 + # werkzeug + werkzeug==3.0.1 + # via flask + + ----- stderr ----- + Resolved 6 packages in [TIME] + "###); + + Ok(()) +}