mirror of https://github.com/astral-sh/uv
Fix handling of Python requests with pre-releases in ranges
This commit is contained in:
parent
24ebdf02c0
commit
fb7d5361b0
|
|
@ -2,6 +2,7 @@ use itertools::{Either, Itertools};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use rustc_hash::{FxBuildHasher, FxHashSet};
|
use rustc_hash::{FxBuildHasher, FxHashSet};
|
||||||
use same_file::is_same_file;
|
use same_file::is_same_file;
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::env::consts::EXE_SUFFIX;
|
use std::env::consts::EXE_SUFFIX;
|
||||||
use std::fmt::{self, Debug, Formatter};
|
use std::fmt::{self, Debug, Formatter};
|
||||||
use std::{env, io, iter};
|
use std::{env, io, iter};
|
||||||
|
|
@ -2692,7 +2693,16 @@ impl VersionRequest {
|
||||||
&& variant.matches_interpreter(interpreter)
|
&& variant.matches_interpreter(interpreter)
|
||||||
}
|
}
|
||||||
Self::Range(specifiers, variant) => {
|
Self::Range(specifiers, variant) => {
|
||||||
let version = interpreter.python_version().only_release();
|
// If the specifier contains pre-releases, use the full version for comparison.
|
||||||
|
// Otherwise, strip pre-release so that, e.g., `>=3.14` matches `3.14.0rc3`.
|
||||||
|
let version = if specifiers
|
||||||
|
.iter()
|
||||||
|
.any(uv_pep440::VersionSpecifier::any_prerelease)
|
||||||
|
{
|
||||||
|
Cow::Borrowed(interpreter.python_version())
|
||||||
|
} else {
|
||||||
|
Cow::Owned(interpreter.python_version().only_release())
|
||||||
|
};
|
||||||
specifiers.contains(&version) && variant.matches_interpreter(interpreter)
|
specifiers.contains(&version) && variant.matches_interpreter(interpreter)
|
||||||
}
|
}
|
||||||
Self::MajorMinorPrerelease(major, minor, prerelease, variant) => {
|
Self::MajorMinorPrerelease(major, minor, prerelease, variant) => {
|
||||||
|
|
@ -2725,7 +2735,19 @@ impl VersionRequest {
|
||||||
(version.major(), version.minor(), version.patch())
|
(version.major(), version.minor(), version.patch())
|
||||||
== (*major, *minor, Some(*patch))
|
== (*major, *minor, Some(*patch))
|
||||||
}
|
}
|
||||||
Self::Range(specifiers, _) => specifiers.contains(&version.version.only_release()),
|
Self::Range(specifiers, _) => {
|
||||||
|
// If the specifier contains pre-releases, use the full version for comparison.
|
||||||
|
// Otherwise, strip pre-release so that, e.g., `>=3.14` matches `3.14.0rc3`.
|
||||||
|
let version = if specifiers
|
||||||
|
.iter()
|
||||||
|
.any(uv_pep440::VersionSpecifier::any_prerelease)
|
||||||
|
{
|
||||||
|
Cow::Borrowed(&version.version)
|
||||||
|
} else {
|
||||||
|
Cow::Owned(version.version.only_release())
|
||||||
|
};
|
||||||
|
specifiers.contains(&version)
|
||||||
|
}
|
||||||
Self::MajorMinorPrerelease(major, minor, prerelease, _) => {
|
Self::MajorMinorPrerelease(major, minor, prerelease, _) => {
|
||||||
(version.major(), version.minor(), version.pre())
|
(version.major(), version.minor(), version.pre())
|
||||||
== (*major, *minor, Some(*prerelease))
|
== (*major, *minor, Some(*prerelease))
|
||||||
|
|
|
||||||
|
|
@ -1335,3 +1335,101 @@ fn python_find_freethreaded_314() {
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
");
|
");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn python_find_prerelease_version_specifiers() {
|
||||||
|
let context: TestContext = TestContext::new_with_versions(&[])
|
||||||
|
.with_filtered_python_keys()
|
||||||
|
.with_filtered_python_sources()
|
||||||
|
.with_managed_python_dirs()
|
||||||
|
.with_python_download_cache()
|
||||||
|
.with_filtered_python_install_bin()
|
||||||
|
.with_filtered_python_names()
|
||||||
|
.with_filtered_exe_suffix();
|
||||||
|
|
||||||
|
context.python_install().arg("3.14.0rc2").assert().success();
|
||||||
|
context.python_install().arg("3.14.0rc3").assert().success();
|
||||||
|
|
||||||
|
// `>=3.14` should allow pre-release versions
|
||||||
|
uv_snapshot!(context.filters(), context.python_find().arg(">=3.14"), @r"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
[TEMP_DIR]/managed/cpython-3.14.0rc3-[PLATFORM]/[INSTALL-BIN]/[PYTHON]
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
");
|
||||||
|
|
||||||
|
// `>3.14rc2` should not match rc2
|
||||||
|
uv_snapshot!(context.filters(), context.python_find().arg(">3.14.0rc2"), @r"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
[TEMP_DIR]/managed/cpython-3.14.0rc3-[PLATFORM]/[INSTALL-BIN]/[PYTHON]
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
");
|
||||||
|
|
||||||
|
// `>3.14rc3` should not match rc3
|
||||||
|
uv_snapshot!(context.filters(), context.python_find().arg(">3.14.0rc3"), @r"
|
||||||
|
success: false
|
||||||
|
exit_code: 2
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
error: No interpreter found for Python >3.14.0rc3 in [PYTHON SOURCES]
|
||||||
|
");
|
||||||
|
|
||||||
|
// `>=3.14.0rc3` should match rc3
|
||||||
|
uv_snapshot!(context.filters(), context.python_find().arg(">=3.14.0rc3"), @r"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
[TEMP_DIR]/managed/cpython-3.14.0rc3-[PLATFORM]/[INSTALL-BIN]/[PYTHON]
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
");
|
||||||
|
|
||||||
|
// `<3.14.0rc3` should match rc2
|
||||||
|
uv_snapshot!(context.filters(), context.python_find().arg("<3.14.0rc3"), @r"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
[TEMP_DIR]/managed/cpython-3.14.0rc2-[PLATFORM]/[INSTALL-BIN]/[PYTHON]
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
");
|
||||||
|
|
||||||
|
// `<=3.14.0rc3` should match rc3
|
||||||
|
uv_snapshot!(context.filters(), context.python_find().arg("<=3.14.0rc3"), @r"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
[TEMP_DIR]/managed/cpython-3.14.0rc3-[PLATFORM]/[INSTALL-BIN]/[PYTHON]
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
");
|
||||||
|
|
||||||
|
// Install the stable version
|
||||||
|
context.python_install().arg("3.14.0").assert().success();
|
||||||
|
|
||||||
|
// `>=3.14` should prefer stable
|
||||||
|
uv_snapshot!(context.filters(), context.python_find().arg(">=3.14"), @r"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
[TEMP_DIR]/managed/cpython-3.14.0-[PLATFORM]/[INSTALL-BIN]/[PYTHON]
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
");
|
||||||
|
|
||||||
|
// `>3.14rc2` should prefer stable
|
||||||
|
uv_snapshot!(context.filters(), context.python_find().arg(">3.14.0rc2"), @r"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
[TEMP_DIR]/managed/cpython-3.14.0-[PLATFORM]/[INSTALL-BIN]/[PYTHON]
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
");
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue