mirror of
https://github.com/astral-sh/uv.git
synced 2026-05-06 08:56:53 -04:00
Omit compatible release desugaring for pre-release hints (#19267)
## Summary `~=3.6` gets expanded to `>=3.6,<4.dev0`, which causes us to show a pre-release hint. We now omit such ranges. This could lead to false negatives (i.e., if a user _actually_ requested `>=3.6,<4.dev0`), but I think this is the right tradeoff. Closes https://github.com/astral-sh/uv/issues/19266.
This commit is contained in:
@@ -1157,7 +1157,9 @@ impl PubGrubReportFormatter<'_> {
|
||||
|
||||
let is_pre2 = match end {
|
||||
Bound::Included(version) => version.any_prerelease(),
|
||||
Bound::Excluded(version) => version.any_prerelease(),
|
||||
Bound::Excluded(version) => {
|
||||
version.any_prerelease() && !is_compatible_release_upper_bound(version)
|
||||
}
|
||||
Bound::Unbounded => false,
|
||||
};
|
||||
if is_pre2 {
|
||||
@@ -1209,6 +1211,14 @@ impl PubGrubReportFormatter<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Return `true` for the excluded `.dev0` upper bounds used to desugar compatible releases.
|
||||
///
|
||||
/// For example, `~=3.6` becomes `>=3.6,<4.dev0`. The `<4.dev0` boundary preserves PEP 440's
|
||||
/// ordering semantics, but it does not mean the user requested pre-releases.
|
||||
fn is_compatible_release_upper_bound(version: &Version) -> bool {
|
||||
version.dev() == Some(0) && !version.is_pre() && !version.is_post() && !version.is_local()
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct ExcludeNewerVersionDetail {
|
||||
version: Version,
|
||||
|
||||
@@ -34018,6 +34018,45 @@ fn lock_exclude_newer_hint_pinned_version() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test that `~=` requirements don't emit a misleading pre-release hint when the compatible
|
||||
/// release upper bound is excluded by `--exclude-newer`.
|
||||
///
|
||||
/// See: <https://github.com/astral-sh/uv/issues/19266>
|
||||
#[test]
|
||||
fn lock_exclude_newer_hint_compatible_release() -> Result<()> {
|
||||
let context = uv_test::test_context!("3.12");
|
||||
|
||||
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
||||
pyproject_toml.write_str(
|
||||
r#"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["iniconfig~=2.0"]
|
||||
"#,
|
||||
)?;
|
||||
|
||||
// Use a cutoff that excludes `iniconfig 2.0.0` (2023-01-07) but not `1.1.1` (2020-10-18).
|
||||
uv_snapshot!(context.filters(), context
|
||||
.lock()
|
||||
.env_remove(EnvVars::UV_EXCLUDE_NEWER)
|
||||
.arg("--exclude-newer")
|
||||
.arg("2022-01-01T00:00:00Z"), @"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because only iniconfig<=1.1.1 is available and your project depends on iniconfig>=2.0,<3.dev0, we can conclude that your project's requirements are unsatisfiable.
|
||||
|
||||
hint: `iniconfig` was filtered by `exclude-newer` to only include packages uploaded before 2022-01-01T00:00:00Z. The latest version satisfying the requirement is v2.0.0, published at 2023-01-07T11:08:09.864Z. Consider using `exclude-newer-package` to override the cutoff for this package.
|
||||
");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test that lockfile validation includes explicit indexes from path dependencies.
|
||||
/// <https://github.com/astral-sh/uv/issues/11419>
|
||||
#[tokio::test]
|
||||
|
||||
Reference in New Issue
Block a user