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 <konstin@mailbox.org>
Co-authored-by: Charles Tapley Hoyt <cthoyt@gmail.com>
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
This commit is contained in:
Zanie Blue 2024-11-04 06:48:02 -06:00
parent b622315a6c
commit 4874b32d85
2 changed files with 42 additions and 2 deletions

View file

@ -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, ());

View file

@ -12687,6 +12687,42 @@ 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(())
}
/// Perform a universal resolution with a constraint, where the constraint itself has a marker.
#[test]
fn lowest_direct_fork() -> Result<()> {