mirror of
https://github.com/astral-sh/uv.git
synced 2026-05-06 08:56:53 -04:00
Update packse and remove Python 3.9.20 from test requirements (#17881)
Requires the packse PR to land first.
This commit is contained in:
@@ -15,8 +15,6 @@
|
||||
3.10.16
|
||||
3.9.21
|
||||
3.8.20
|
||||
# The following are required for packse scenarios
|
||||
3.9.20
|
||||
# The following is needed for `==3.13` request tests
|
||||
3.13.0
|
||||
# A pre-release version required for testing
|
||||
|
||||
@@ -36,7 +36,7 @@ use uv_static::EnvVars;
|
||||
// Exclude any packages uploaded after this date.
|
||||
static EXCLUDE_NEWER: &str = "2024-03-25T00:00:00Z";
|
||||
|
||||
pub const PACKSE_VERSION: &str = "0.3.53";
|
||||
pub const PACKSE_VERSION: &str = "0.3.59";
|
||||
pub const DEFAULT_PYTHON_VERSION: &str = "3.12";
|
||||
|
||||
// The expected latest patch version for each Python minor version.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! DO NOT EDIT
|
||||
//!
|
||||
//! Generated with `./scripts/sync_scenarios.sh`
|
||||
//! Scenarios from <https://github.com/astral-sh/packse/tree/0.3.53/scenarios>
|
||||
//! Scenarios from <https://github.com/astral-sh/packse/tree/0.3.59/scenarios>
|
||||
//!
|
||||
#![cfg(all(feature = "test-python", feature = "test-pypi"))]
|
||||
#![allow(clippy::needless_raw_string_hashes)]
|
||||
@@ -5347,6 +5347,106 @@ fn virtual_package_extra_priorities() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// While both Linux and Windows are required and `win-only` has only a Windows wheel, `win-only` is also used only on Windows.
|
||||
///
|
||||
/// ```text
|
||||
/// requires-python-subset
|
||||
/// ├── environment
|
||||
/// │ └── python3.12
|
||||
/// ├── root
|
||||
/// │ └── requires win-only; sys_platform == "win32"
|
||||
/// │ └── satisfied by win-only-1.0.0
|
||||
/// └── win-only
|
||||
/// └── win-only-1.0.0
|
||||
/// ```
|
||||
#[test]
|
||||
fn requires_python_subset() -> Result<()> {
|
||||
let context = uv_test::test_context!("3.12");
|
||||
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = context.filters();
|
||||
filters.push((r"requires-python-subset-", "package-"));
|
||||
|
||||
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
||||
pyproject_toml.write_str(
|
||||
r###"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
'''requires-python-subset-win-only; sys_platform == "win32"''',
|
||||
]
|
||||
requires-python = ">=3.12"
|
||||
[tool.uv]
|
||||
required-environments = [
|
||||
'''sys_platform == "linux"''',
|
||||
'''sys_platform == "win32"''',
|
||||
]
|
||||
"###,
|
||||
)?;
|
||||
|
||||
let mut cmd = context.lock();
|
||||
cmd.env_remove(EnvVars::UV_EXCLUDE_NEWER);
|
||||
cmd.arg("--index-url").arg(packse_index_url());
|
||||
uv_snapshot!(filters, cmd, @"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 2 packages in [TIME]
|
||||
"
|
||||
);
|
||||
|
||||
let lock = context.read("uv.lock");
|
||||
insta::with_settings!({
|
||||
filters => filters,
|
||||
}, {
|
||||
assert_snapshot!(
|
||||
lock, @r#"
|
||||
version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.12"
|
||||
required-markers = [
|
||||
"sys_platform == 'linux'",
|
||||
"sys_platform == 'win32'",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "package-win-only", marker = "sys_platform == 'win32'" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "package-win-only", marker = "sys_platform == 'win32'" }]
|
||||
|
||||
[[package]]
|
||||
name = "package-win-only"
|
||||
version = "1.0.0"
|
||||
source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" }
|
||||
wheels = [
|
||||
{ url = "https://astral-sh.github.io/packse/PACKSE_VERSION/files/requires_python_subset_win_only-1.0.0-cp312-abi3-win_amd64.whl", hash = "sha256:91d59021b1c4aad7449e315ae1248c5c588a7e84cb7592671a41453012302711" },
|
||||
]
|
||||
"#
|
||||
);
|
||||
});
|
||||
|
||||
// Assert the idempotence of `uv lock` when resolving from the lockfile (`--locked`).
|
||||
context
|
||||
.lock()
|
||||
.arg("--locked")
|
||||
.env_remove(EnvVars::UV_EXCLUDE_NEWER)
|
||||
.arg("--index-url")
|
||||
.arg(packse_index_url())
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// When a dependency is only required on a specific platform (like x86_64), omit wheels that target other platforms (like aarch64).
|
||||
///
|
||||
/// ```text
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
//! DO NOT EDIT
|
||||
//!
|
||||
//! Generated with `./scripts/sync_scenarios.sh`
|
||||
//! Scenarios from <https://github.com/astral-sh/packse/tree/0.3.53/scenarios>
|
||||
//! Scenarios from <https://github.com/astral-sh/packse/tree/0.3.59/scenarios>
|
||||
//!
|
||||
#![cfg(all(feature = "test-python", feature = "test-pypi", unix))]
|
||||
|
||||
use std::env;
|
||||
use std::process::Command;
|
||||
|
||||
use anyhow::Result;
|
||||
@@ -352,7 +353,7 @@ fn incompatible_python_compatible_override() -> Result<()> {
|
||||
/// ```text
|
||||
/// python-patch-override-no-patch
|
||||
/// ├── environment
|
||||
/// │ └── python3.9.20
|
||||
/// │ └── python3.9.21
|
||||
/// ├── root
|
||||
/// │ └── requires a==1.0.0
|
||||
/// │ └── satisfied by a-1.0.0
|
||||
@@ -363,7 +364,7 @@ fn incompatible_python_compatible_override() -> Result<()> {
|
||||
#[cfg(feature = "test-python-patch")]
|
||||
#[test]
|
||||
fn python_patch_override_no_patch() -> Result<()> {
|
||||
let context = uv_test::test_context!("3.9.20");
|
||||
let context = uv_test::test_context!("3.9.21");
|
||||
let python_versions = &[];
|
||||
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
@@ -376,18 +377,18 @@ fn python_patch_override_no_patch() -> Result<()> {
|
||||
// Since the resolver is asked to solve with 3.9, the minimum compatible Python requirement is treated as 3.9.0.
|
||||
let output = uv_snapshot!(filters, command(&context, python_versions)
|
||||
.arg("--python-version=3.9")
|
||||
, @r"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
, @"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because the requested Python version (>=3.9) does not satisfy Python>=3.9.4 and package-a==1.0.0 depends on Python>=3.9.4, we can conclude that package-a==1.0.0 cannot be used.
|
||||
And because you require package-a==1.0.0, we can conclude that your requirements are unsatisfiable.
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because the requested Python version (>=3.9) does not satisfy Python>=3.9.4 and package-a==1.0.0 depends on Python>=3.9.4, we can conclude that package-a==1.0.0 cannot be used.
|
||||
And because you require package-a==1.0.0, we can conclude that your requirements are unsatisfiable.
|
||||
|
||||
hint: The `--python-version` value (>=3.9) includes Python versions that are not supported by your dependencies (e.g., package-a==1.0.0 only supports >=3.9.4). Consider using a higher `--python-version` value.
|
||||
"
|
||||
hint: The `--python-version` value (>=3.9) includes Python versions that are not supported by your dependencies (e.g., package-a==1.0.0 only supports >=3.9.4). Consider using a higher `--python-version` value.
|
||||
"
|
||||
);
|
||||
|
||||
output.assert().failure();
|
||||
@@ -400,7 +401,7 @@ fn python_patch_override_no_patch() -> Result<()> {
|
||||
/// ```text
|
||||
/// python-patch-override-patch-compatible
|
||||
/// ├── environment
|
||||
/// │ └── python3.9.20
|
||||
/// │ └── python3.9.21
|
||||
/// ├── root
|
||||
/// │ └── requires a==1.0.0
|
||||
/// │ └── satisfied by a-1.0.0
|
||||
@@ -411,7 +412,7 @@ fn python_patch_override_no_patch() -> Result<()> {
|
||||
#[cfg(feature = "test-python-patch")]
|
||||
#[test]
|
||||
fn python_patch_override_patch_compatible() -> Result<()> {
|
||||
let context = uv_test::test_context!("3.9.20");
|
||||
let context = uv_test::test_context!("3.9.21");
|
||||
let python_versions = &[];
|
||||
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
@@ -423,19 +424,19 @@ fn python_patch_override_patch_compatible() -> Result<()> {
|
||||
|
||||
let output = uv_snapshot!(filters, command(&context, python_versions)
|
||||
.arg("--python-version=3.9.0")
|
||||
, @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile requirements.in --cache-dir [CACHE_DIR] --python-version=3.9.0
|
||||
package-a==1.0.0
|
||||
# via -r requirements.in
|
||||
, @"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile requirements.in --cache-dir [CACHE_DIR] --python-version=3.9.0
|
||||
package-a==1.0.0
|
||||
# via -r requirements.in
|
||||
|
||||
----- stderr -----
|
||||
warning: The requested Python version 3.9.0 is not available; 3.9.20 will be used to build dependencies instead.
|
||||
Resolved 1 package in [TIME]
|
||||
"
|
||||
----- stderr -----
|
||||
warning: The requested Python version 3.9.0 is not available; 3.9.21 will be used to build dependencies instead.
|
||||
Resolved 1 package in [TIME]
|
||||
"
|
||||
);
|
||||
|
||||
output.assert().success().stdout(predicate::str::contains(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! DO NOT EDIT
|
||||
//!
|
||||
//! Generated with `./scripts/sync_scenarios.sh`
|
||||
//! Scenarios from <https://github.com/astral-sh/packse/tree/0.3.53/scenarios>
|
||||
//! Scenarios from <https://github.com/astral-sh/packse/tree/0.3.59/scenarios>
|
||||
//!
|
||||
#![cfg(all(feature = "test-python", feature = "test-pypi", unix))]
|
||||
|
||||
@@ -23,6 +23,119 @@ fn command(context: &TestContext) -> Command {
|
||||
command
|
||||
}
|
||||
|
||||
/// There are two packages, `a` and `b`. All versions of `b` require a specific
|
||||
/// version of `a`, but that version requires a package `c` that does not exist. The resolver
|
||||
/// must backtrack through all versions of `b` and eventually fail because no solution exists.
|
||||
///
|
||||
/// ```text
|
||||
/// backtrack-to-missing-package
|
||||
/// ├── environment
|
||||
/// │ └── python3.12
|
||||
/// ├── root
|
||||
/// │ ├── requires a
|
||||
/// │ │ ├── satisfied by a-2.0.0
|
||||
/// │ │ └── satisfied by a-1.0.0
|
||||
/// │ └── requires b
|
||||
/// │ ├── satisfied by b-1.0.0
|
||||
/// │ ├── satisfied by b-2.0.0
|
||||
/// │ └── satisfied by b-3.0.0
|
||||
/// ├── a
|
||||
/// │ ├── a-2.0.0
|
||||
/// │ └── a-1.0.0
|
||||
/// │ └── requires c
|
||||
/// │ └── unsatisfied: no versions for package
|
||||
/// └── b
|
||||
/// ├── b-1.0.0
|
||||
/// │ └── requires a==1.0.0
|
||||
/// │ └── satisfied by a-1.0.0
|
||||
/// ├── b-2.0.0
|
||||
/// │ └── requires a==1.0.0
|
||||
/// │ └── satisfied by a-1.0.0
|
||||
/// └── b-3.0.0
|
||||
/// └── requires a==1.0.0
|
||||
/// └── satisfied by a-1.0.0
|
||||
/// ```
|
||||
#[test]
|
||||
fn backtrack_to_missing_package() {
|
||||
let context = uv_test::test_context!("3.12");
|
||||
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = context.filters();
|
||||
filters.push((r"backtrack-to-missing-package-", "package-"));
|
||||
|
||||
uv_snapshot!(filters, command(&context)
|
||||
.arg("backtrack-to-missing-package-a")
|
||||
.arg("backtrack-to-missing-package-b")
|
||||
, @"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because package-c was not found in the package registry and package-a==1.0.0 depends on package-c, we can conclude that package-a==1.0.0 cannot be used.
|
||||
And because all versions of package-b depend on package-a==1.0.0 and you require package-b, we can conclude that your requirements are unsatisfiable.
|
||||
");
|
||||
|
||||
context.assert_not_installed("backtrack_to_missing_package_a");
|
||||
context.assert_not_installed("backtrack_to_missing_package_b");
|
||||
}
|
||||
|
||||
/// There are two packages, `a` and `b`. The latest version of `b` requires
|
||||
/// a specific version of `a`. The older version of `b` requires a package `c` that does not
|
||||
/// exist. The resolver should backtrack on `a` (not `b`) to find a solution without needing
|
||||
/// to try `b==1.0.0` which would fail due to the missing package.
|
||||
///
|
||||
/// ```text
|
||||
/// backtrack-with-missing-package
|
||||
/// ├── environment
|
||||
/// │ └── python3.12
|
||||
/// ├── root
|
||||
/// │ ├── requires a
|
||||
/// │ │ ├── satisfied by a-1.0.0
|
||||
/// │ │ └── satisfied by a-2.0.0
|
||||
/// │ └── requires b
|
||||
/// │ ├── satisfied by b-1.0.0
|
||||
/// │ └── satisfied by b-2.0.0
|
||||
/// ├── a
|
||||
/// │ ├── a-1.0.0
|
||||
/// │ └── a-2.0.0
|
||||
/// └── b
|
||||
/// ├── b-1.0.0
|
||||
/// │ └── requires c
|
||||
/// │ └── unsatisfied: no versions for package
|
||||
/// └── b-2.0.0
|
||||
/// └── requires a==1.0.0
|
||||
/// └── satisfied by a-1.0.0
|
||||
/// ```
|
||||
#[test]
|
||||
fn backtrack_with_missing_package() {
|
||||
let context = uv_test::test_context!("3.12");
|
||||
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = context.filters();
|
||||
filters.push((r"backtrack-with-missing-package-", "package-"));
|
||||
|
||||
uv_snapshot!(filters, command(&context)
|
||||
.arg("backtrack-with-missing-package-a")
|
||||
.arg("backtrack-with-missing-package-b")
|
||||
, @"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 2 packages in [TIME]
|
||||
Prepared 2 packages in [TIME]
|
||||
Installed 2 packages in [TIME]
|
||||
+ package-a==1.0.0
|
||||
+ package-b==2.0.0
|
||||
");
|
||||
|
||||
context.assert_installed("backtrack_with_missing_package_a", "1.0.0");
|
||||
context.assert_installed("backtrack_with_missing_package_b", "2.0.0");
|
||||
}
|
||||
|
||||
/// The user requires an exact version of package `a` but only other versions exist
|
||||
///
|
||||
/// ```text
|
||||
@@ -3408,7 +3521,7 @@ fn python_greater_than_current_patch() {
|
||||
|
||||
uv_snapshot!(filters, command(&context)
|
||||
.arg("python-greater-than-current-patch-a==1.0.0")
|
||||
, @r"
|
||||
, @"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
|
||||
@@ -51,7 +51,7 @@ PACKSE = TOOL_ROOT / "packse-scenarios"
|
||||
REQUIREMENTS = TOOL_ROOT / "pylock.toml"
|
||||
PROJECT_ROOT = TOOL_ROOT.parent.parent
|
||||
TESTS = PROJECT_ROOT / "crates" / "uv" / "tests" / "it"
|
||||
TESTS_COMMON_MOD_RS = TESTS / "common" / "mod.rs"
|
||||
TESTS_COMMON_MOD_RS = PROJECT_ROOT / "crates" / "uv-test" / "src" / "lib.rs"
|
||||
|
||||
try:
|
||||
import packse
|
||||
@@ -185,7 +185,7 @@ def main(
|
||||
resolver_options = scenario["resolver_options"] or {}
|
||||
# Avoid writing the empty `required-environments = []`
|
||||
resolver_options["has_required_environments"] = bool(
|
||||
resolver_options["required_environments"]
|
||||
resolver_options.get("required_environments", [])
|
||||
)
|
||||
if resolver_options.get("universal"):
|
||||
lock_scenarios.append(scenario)
|
||||
@@ -259,7 +259,7 @@ def main(
|
||||
"insta",
|
||||
"test",
|
||||
"--features",
|
||||
"pypi,python,python-patch",
|
||||
"test-pypi,test-python,test-python-patch",
|
||||
"--accept",
|
||||
"--test-runner",
|
||||
"nextest",
|
||||
|
||||
@@ -66,9 +66,9 @@ wheels = [{ url = "https://files.pythonhosted.org/packages/20/12/38679034af33278
|
||||
|
||||
[[packages]]
|
||||
name = "packse"
|
||||
version = "0.3.53"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/52/58/373b6281bb741e875893dc351ac5f180c3fdce18a3b889f773725ff964b2/packse-0.3.53.tar.gz", upload-time = 2025-09-16T09:37:55Z, size = 5879063, hashes = { sha256 = "fcdbbb60f8ad4af94901891699a95ade4f15b9e769b4d8f443a2f3ef7aa74067" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/fc/86/d5482bb2933fe47d282b1dae74cc9084b094f28229848ba8ea01a77fe0da/packse-0.3.53-py3-none-any.whl", upload-time = 2025-09-16T09:37:53Z, size = 34039, hashes = { sha256 = "78cf05f5e0b916f4070a66f04f3b371e2d4ac0c3917f38cb692a33fa6e9d764b" } }]
|
||||
version = "0.3.59"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/16/90/51404d8933506bd9554f607f5054f4715e0a5e1d34e4c6542580553e8b75/packse-0.3.59.tar.gz", upload-time = 2026-02-18T17:44:17Z, size = 5880109, hashes = { sha256 = "718bcca5dd1e9321f5c2918d5975ffd772f0c3b150cf29b03979677a003d73d2" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/8d/95/b4a997b57a1f46f0f7575c1c021ee15e8fc1470b6ce74010239079d1d9aa/packse-0.3.59-py3-none-any.whl", upload-time = 2026-02-18T17:44:16Z, size = 34107, hashes = { sha256 = "10a3689ce0c00805cd7f1589862ab2d8f9fd4ab38c117342c351bfb13daa5c69" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "pathspec"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[dependency-groups]
|
||||
packse = [
|
||||
"chevron-blue",
|
||||
"packse>=0.3.53"
|
||||
"packse>=0.3.59"
|
||||
]
|
||||
|
||||
@@ -24,7 +24,7 @@ use uv_test::{
|
||||
fn command(context: &TestContext, python_versions: &[&str]) -> Command {
|
||||
let python_path = python_path_with_versions(&context.temp_dir, python_versions)
|
||||
.expect("Failed to create Python test path");
|
||||
let mut command = Command::new(get_bin());
|
||||
let mut command = Command::new(get_bin!());
|
||||
command
|
||||
.arg("pip")
|
||||
.arg("compile")
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
This script reads the download-metadata.json file and extracts the latest
|
||||
patch version for each minor version (3.15, 3.14, 3.13, 3.12, 3.11, 3.10).
|
||||
It then updates the LATEST_PYTHON_X_Y constants in crates/uv/tests/it/common/mod.rs.
|
||||
It then updates the LATEST_PYTHON_X_Y constants in crates/uv-test/src/lib.rs.
|
||||
|
||||
For minor versions with stable releases, it uses the latest stable version.
|
||||
For minor versions with only prereleases, it uses the latest prerelease.
|
||||
@@ -70,7 +70,7 @@ def main() -> None:
|
||||
if minor not in latest_versions:
|
||||
latest_versions[minor] = prerelease_versions[minor]
|
||||
|
||||
# Update the constants in common/mod.rs
|
||||
# Update the constants in uv-test/src/lib.rs
|
||||
lib_path = ROOT / "crates" / "uv-test" / "src" / "lib.rs"
|
||||
content = lib_path.read_text()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user