mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-01 12:24:15 +00:00
Make < exclusive for non-prerelease markers (#1878)
## Summary Even when pre-releases are "allowed", per PEP 440, `pydantic<2.0.0` should _not_ include pre-releases. This PR modifies the specifier translation to treat `pydantic<2.0.0` as `pydantic<2.0.0.min0`, where `min` is an internal-only version segment that's invisible to users. Closes https://github.com/astral-sh/uv/issues/1641.
This commit is contained in:
parent
53a250714c
commit
8d706b0f2a
10 changed files with 440 additions and 58 deletions
|
|
@ -95,4 +95,15 @@ impl PreReleaseStrategy {
|
|||
),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if a [`PackageName`] is allowed to have pre-release versions.
|
||||
pub(crate) fn allows(&self, package: &PackageName) -> bool {
|
||||
match self {
|
||||
Self::Disallow => false,
|
||||
Self::Allow => true,
|
||||
Self::IfNecessary => false,
|
||||
Self::Explicit(packages) => packages.contains(package),
|
||||
Self::IfNecessaryOrExplicit(packages) => packages.contains(package),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ use rustc_hash::FxHashMap;
|
|||
use uv_normalize::PackageName;
|
||||
|
||||
use crate::candidate_selector::CandidateSelector;
|
||||
use crate::prerelease_mode::PreReleaseStrategy;
|
||||
use crate::python_requirement::PythonRequirement;
|
||||
use crate::resolver::UnavailablePackage;
|
||||
|
||||
|
|
@ -346,25 +345,10 @@ impl PubGrubReportFormatter<'_> {
|
|||
) -> IndexSet<PubGrubHint> {
|
||||
/// Returns `true` if pre-releases were allowed for a package.
|
||||
fn allowed_prerelease(package: &PubGrubPackage, selector: &CandidateSelector) -> bool {
|
||||
match selector.prerelease_strategy() {
|
||||
PreReleaseStrategy::Disallow => false,
|
||||
PreReleaseStrategy::Allow => true,
|
||||
PreReleaseStrategy::IfNecessary => false,
|
||||
PreReleaseStrategy::Explicit(packages) => {
|
||||
if let PubGrubPackage::Package(package, ..) = package {
|
||||
packages.contains(package)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
PreReleaseStrategy::IfNecessaryOrExplicit(packages) => {
|
||||
if let PubGrubPackage::Package(package, ..) = package {
|
||||
packages.contains(package)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
let PubGrubPackage::Package(package, ..) = package else {
|
||||
return false;
|
||||
};
|
||||
selector.prerelease_strategy().allows(package)
|
||||
}
|
||||
|
||||
let mut hints = IndexSet::default();
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ impl TryFrom<&VersionSpecifier> for PubGrubSpecifier {
|
|||
let [rest @ .., last, _] = specifier.version().release() else {
|
||||
return Err(ResolveError::InvalidTildeEquals(specifier.clone()));
|
||||
};
|
||||
let upper = pep440_rs::Version::new(rest.iter().chain([&(last + 1)]))
|
||||
let upper = Version::new(rest.iter().chain([&(last + 1)]))
|
||||
.with_epoch(specifier.version().epoch())
|
||||
.with_dev(Some(0));
|
||||
let version = specifier.version().clone();
|
||||
|
|
@ -46,7 +46,14 @@ impl TryFrom<&VersionSpecifier> for PubGrubSpecifier {
|
|||
}
|
||||
Operator::LessThan => {
|
||||
let version = specifier.version().clone();
|
||||
Range::strictly_lower_than(version)
|
||||
if version.any_prerelease() {
|
||||
Range::strictly_lower_than(version)
|
||||
} else {
|
||||
// Per PEP 440: "The exclusive ordered comparison <V MUST NOT allow a
|
||||
// pre-release of the specified version unless the specified version is itself a
|
||||
// pre-release.
|
||||
Range::strictly_lower_than(version.with_min(Some(0)))
|
||||
}
|
||||
}
|
||||
Operator::LessThanEqual => {
|
||||
let version = specifier.version().clone();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue