From e3f6b9c5f30c11fc17bc56d613b641cae721e330 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 14 Jan 2025 09:39:21 -0500 Subject: [PATCH] Filter wheels from lockfile based on architecture (#10584) ## Summary After we resolve, we filter out any wheels that aren't applicable for the target platforms. So, e.g., we remove macOS wheels if we find that the user only asked to solve for Windows. This PR extends the same logic to architectures, so that we filter out ARM-only wheels when the user is only solving for x86, etc. Closes #10571. --- crates/uv-platform-tags/src/platform_tag.rs | 107 +++++++- crates/uv-platform-tags/src/tags.rs | 2 +- crates/uv-resolver/src/lock/mod.rs | 84 ++++++- crates/uv/tests/it/common/mod.rs | 2 +- crates/uv/tests/it/lock.rs | 233 ++++++++++++++++++ crates/uv/tests/it/lock_scenarios.rs | 142 ++++++++++- crates/uv/tests/it/pip_compile_scenarios.rs | 2 +- crates/uv/tests/it/pip_install_scenarios.rs | 2 +- ...it__ecosystem__transformers-lock-file.snap | 2 - scripts/scenarios/requirements.txt | 2 +- 10 files changed, 550 insertions(+), 28 deletions(-) diff --git a/crates/uv-platform-tags/src/platform_tag.rs b/crates/uv-platform-tags/src/platform_tag.rs index 5d65ba5b7..b74bec83d 100644 --- a/crates/uv-platform-tags/src/platform_tag.rs +++ b/crates/uv-platform-tags/src/platform_tag.rs @@ -72,8 +72,8 @@ pub enum PlatformTag { } impl PlatformTag { - /// Returns `true` if the platform is manylinux-compatible. - pub fn is_manylinux_compatible(&self) -> bool { + /// Returns `true` if the platform is manylinux-only. + pub fn is_manylinux(&self) -> bool { matches!( self, Self::Manylinux { .. } @@ -83,8 +83,8 @@ impl PlatformTag { ) } - /// Returns `true` if the platform is Linux-compatible. - pub fn is_linux_compatible(&self) -> bool { + /// Returns `true` if the platform is Linux-only. + pub fn is_linux(&self) -> bool { matches!( self, Self::Manylinux { .. } @@ -96,15 +96,106 @@ impl PlatformTag { ) } - /// Returns `true` if the platform is macOS-compatible. - pub fn is_macos_compatible(&self) -> bool { + /// Returns `true` if the platform is macOS-only. + pub fn is_macos(&self) -> bool { matches!(self, Self::Macos { .. }) } - /// Returns `true` if the platform is Windows-compatible. - pub fn is_windows_compatible(&self) -> bool { + /// Returns `true` if the platform is Windows-only. + pub fn is_windows(&self) -> bool { matches!(self, Self::Win32 | Self::WinAmd64 | Self::WinArm64) } + + /// Returns `true` if the tag is only applicable on ARM platforms. + pub fn is_arm(&self) -> bool { + matches!( + self, + Self::Manylinux { + arch: Arch::Aarch64, + .. + } | Self::Manylinux1 { + arch: Arch::Aarch64, + .. + } | Self::Manylinux2010 { + arch: Arch::Aarch64, + .. + } | Self::Manylinux2014 { + arch: Arch::Aarch64, + .. + } | Self::Linux { + arch: Arch::Aarch64, + .. + } | Self::Musllinux { + arch: Arch::Aarch64, + .. + } | Self::Macos { + binary_format: BinaryFormat::Arm64, + .. + } | Self::WinArm64 + | Self::Android { + arch: Arch::Aarch64, + .. + } + ) + } + + /// Returns `true` if the tag is only applicable on `x86_64` platforms. + pub fn is_x86_64(&self) -> bool { + matches!( + self, + Self::Manylinux { + arch: Arch::X86_64, + .. + } | Self::Manylinux1 { + arch: Arch::X86_64, + .. + } | Self::Manylinux2010 { + arch: Arch::X86_64, + .. + } | Self::Manylinux2014 { + arch: Arch::X86_64, + .. + } | Self::Linux { + arch: Arch::X86_64, + .. + } | Self::Musllinux { + arch: Arch::X86_64, + .. + } | Self::Macos { + binary_format: BinaryFormat::X86_64, + .. + } | Self::WinAmd64 + ) + } + + /// Returns `true` if the tag is only applicable on x86 platforms. + pub fn is_x86(&self) -> bool { + matches!( + self, + Self::Manylinux { + arch: Arch::X86, + .. + } | Self::Manylinux1 { + arch: Arch::X86, + .. + } | Self::Manylinux2010 { + arch: Arch::X86, + .. + } | Self::Manylinux2014 { + arch: Arch::X86, + .. + } | Self::Linux { + arch: Arch::X86, + .. + } | Self::Musllinux { + arch: Arch::X86, + .. + } | Self::Macos { + binary_format: BinaryFormat::I386, + .. + } | Self::Win32 + ) + } } impl std::fmt::Display for PlatformTag { diff --git a/crates/uv-platform-tags/src/tags.rs b/crates/uv-platform-tags/src/tags.rs index 78ee6da4f..73a70a0f4 100644 --- a/crates/uv-platform-tags/src/tags.rs +++ b/crates/uv-platform-tags/src/tags.rs @@ -123,7 +123,7 @@ impl Tags { let platform_tags = { let mut platform_tags = compatible_tags(platform)?; if matches!(platform.os(), Os::Manylinux { .. }) && !manylinux_compatible { - platform_tags.retain(|tag| !tag.is_manylinux_compatible()); + platform_tags.retain(|tag| !tag.is_manylinux()); } platform_tags }; diff --git a/crates/uv-resolver/src/lock/mod.rs b/crates/uv-resolver/src/lock/mod.rs index 267640d70..c9faf4a22 100644 --- a/crates/uv-resolver/src/lock/mod.rs +++ b/crates/uv-resolver/src/lock/mod.rs @@ -73,6 +73,25 @@ static MAC_MARKERS: LazyLock = LazyLock::new(|| { let pep508 = MarkerTree::from_str("os_name == 'posix' and sys_platform == 'darwin'").unwrap(); UniversalMarker::new(pep508, ConflictMarker::TRUE) }); +static ARM_MARKERS: LazyLock = LazyLock::new(|| { + let pep508 = + MarkerTree::from_str("platform_machine == 'aarch64' or platform_machine == 'arm64'") + .unwrap(); + UniversalMarker::new(pep508, ConflictMarker::TRUE) +}); +static X86_64_MARKERS: LazyLock = LazyLock::new(|| { + let pep508 = + MarkerTree::from_str("platform_machine == 'x86_64' or platform_machine == 'amd64'") + .unwrap(); + UniversalMarker::new(pep508, ConflictMarker::TRUE) +}); +static X86_MARKERS: LazyLock = LazyLock::new(|| { + let pep508 = MarkerTree::from_str( + "platform_machine == 'i686' or platform_machine == 'i386' or platform_machine == 'win32' or platform_machine == 'x86'", + ) + .unwrap(); + UniversalMarker::new(pep508, ConflictMarker::TRUE) +}); #[derive(Clone, Debug, serde::Deserialize)] #[serde(try_from = "LockWire")] @@ -275,25 +294,66 @@ impl Lock { let platform_tags = &wheel.filename.platform_tag; if platform_tags .iter() - .all(uv_platform_tags::PlatformTag::is_linux_compatible) + .all(uv_platform_tags::PlatformTag::is_linux) { - !graph.graph[node_index].marker().is_disjoint(*LINUX_MARKERS) - } else if platform_tags + if graph.graph[node_index].marker().is_disjoint(*LINUX_MARKERS) { + return false; + } + } + + if platform_tags .iter() - .all(uv_platform_tags::PlatformTag::is_windows_compatible) + .all(uv_platform_tags::PlatformTag::is_windows) { // TODO(charlie): This omits `win_ia64`, which is accepted by Warehouse. - !graph.graph[node_index] + if graph.graph[node_index] .marker() .is_disjoint(*WINDOWS_MARKERS) - } else if platform_tags - .iter() - .all(uv_platform_tags::PlatformTag::is_macos_compatible) - { - !graph.graph[node_index].marker().is_disjoint(*MAC_MARKERS) - } else { - true + { + return false; + } } + + if platform_tags + .iter() + .all(uv_platform_tags::PlatformTag::is_macos) + { + if graph.graph[node_index].marker().is_disjoint(*MAC_MARKERS) { + return false; + } + } + + if platform_tags + .iter() + .all(uv_platform_tags::PlatformTag::is_arm) + { + if graph.graph[node_index].marker().is_disjoint(*ARM_MARKERS) { + return false; + } + } + + if platform_tags + .iter() + .all(uv_platform_tags::PlatformTag::is_x86_64) + { + if graph.graph[node_index] + .marker() + .is_disjoint(*X86_64_MARKERS) + { + return false; + } + } + + if platform_tags + .iter() + .all(uv_platform_tags::PlatformTag::is_x86) + { + if graph.graph[node_index].marker().is_disjoint(*X86_MARKERS) { + return false; + } + } + + true }); } diff --git a/crates/uv/tests/it/common/mod.rs b/crates/uv/tests/it/common/mod.rs index 6a20c930e..16eb660c9 100644 --- a/crates/uv/tests/it/common/mod.rs +++ b/crates/uv/tests/it/common/mod.rs @@ -32,7 +32,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.44"; +pub const PACKSE_VERSION: &str = "0.3.45"; /// Using a find links url allows using `--index-url` instead of `--extra-index-url` in tests /// to prevent dependency confusion attacks against our test suite. diff --git a/crates/uv/tests/it/lock.rs b/crates/uv/tests/it/lock.rs index 891754656..0c6883fd9 100644 --- a/crates/uv/tests/it/lock.rs +++ b/crates/uv/tests/it/lock.rs @@ -21362,6 +21362,239 @@ fn lock_missing_git_prefix() -> Result<()> { Ok(()) } +#[test] +fn lock_arm() -> Result<()> { + let context = TestContext::new("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 = ["numpy"] + + [tool.uv] + environments = ["platform_machine == 'arm64'"] + + [build-system] + requires = ["setuptools>=42"] + build-backend = "setuptools.build_meta" + "#, + )?; + + uv_snapshot!(context.filters(), context.lock(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 2 packages in [TIME] + "###); + + let lock = context.read("uv.lock"); + + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" + resolution-markers = [ + "platform_machine == 'arm64'", + ] + supported-markers = [ + "platform_machine == 'arm64'", + ] + + [options] + exclude-newer = "2024-03-25T00:00:00Z" + + [[package]] + name = "numpy" + version = "1.26.4" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/65/6e/09db70a523a96d25e115e71cc56a6f9031e7b8cd166c1ac8438307c14058/numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", size = 15786129 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/75/5b/ca6c8bd14007e5ca171c7c03102d17b4f4e0ceb53957e8c44343a9546dcc/numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", size = 13685868 }, + { url = "https://files.pythonhosted.org/packages/79/f8/97f10e6755e2a7d027ca783f63044d5b1bc1ae7acb12afe6a9b4286eac17/numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", size = 13925109 }, + { url = "https://files.pythonhosted.org/packages/4c/0c/9c603826b6465e82591e05ca230dfc13376da512b25ccd0894709b054ed0/numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a", size = 13572172 }, + ] + + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "numpy", marker = "platform_machine == 'arm64'" }, + ] + + [package.metadata] + requires-dist = [{ name = "numpy" }] + "### + ); + }); + + Ok(()) +} + +#[test] +fn lock_x86_64() -> Result<()> { + let context = TestContext::new("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 = ["numpy"] + + [tool.uv] + environments = ["platform_machine == 'x86_64'"] + + [build-system] + requires = ["setuptools>=42"] + build-backend = "setuptools.build_meta" + "#, + )?; + + uv_snapshot!(context.filters(), context.lock(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 2 packages in [TIME] + "###); + + let lock = context.read("uv.lock"); + + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" + resolution-markers = [ + "platform_machine == 'x86_64'", + ] + supported-markers = [ + "platform_machine == 'x86_64'", + ] + + [options] + exclude-newer = "2024-03-25T00:00:00Z" + + [[package]] + name = "numpy" + version = "1.26.4" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/65/6e/09db70a523a96d25e115e71cc56a6f9031e7b8cd166c1ac8438307c14058/numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", size = 15786129 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/95/12/8f2020a8e8b8383ac0177dc9570aad031a3beb12e38847f7129bacd96228/numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", size = 20335901 }, + { url = "https://files.pythonhosted.org/packages/0f/50/de23fde84e45f5c4fda2488c759b69990fd4512387a8632860f3ac9cd225/numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed", size = 17950613 }, + { url = "https://files.pythonhosted.org/packages/76/8c/2ba3902e1a0fc1c74962ea9bb33a534bb05984ad7ff9515bf8d07527cadd/numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0", size = 17786643 }, + { url = "https://files.pythonhosted.org/packages/16/2e/86f24451c2d530c88daf997cb8d6ac622c1d40d19f5a031ed68a4b73a374/numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", size = 15517754 }, + ] + + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "numpy", marker = "platform_machine == 'x86_64'" }, + ] + + [package.metadata] + requires-dist = [{ name = "numpy" }] + "### + ); + }); + + Ok(()) +} + +#[test] +fn lock_x86() -> Result<()> { + let context = TestContext::new("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 = ["numpy"] + + [tool.uv] + environments = ["platform_machine == 'i686'"] + + [build-system] + requires = ["setuptools>=42"] + build-backend = "setuptools.build_meta" + "#, + )?; + + uv_snapshot!(context.filters(), context.lock(), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 2 packages in [TIME] + "###); + + let lock = context.read("uv.lock"); + + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.12" + resolution-markers = [ + "platform_machine == 'i686'", + ] + supported-markers = [ + "platform_machine == 'i686'", + ] + + [options] + exclude-newer = "2024-03-25T00:00:00Z" + + [[package]] + name = "numpy" + version = "1.26.4" + source = { registry = "https://pypi.org/simple" } + sdist = { url = "https://files.pythonhosted.org/packages/65/6e/09db70a523a96d25e115e71cc56a6f9031e7b8cd166c1ac8438307c14058/numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", size = 15786129 } + wheels = [ + { url = "https://files.pythonhosted.org/packages/28/4a/46d9e65106879492374999e76eb85f87b15328e06bd1550668f79f7b18c6/numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110", size = 5677803 }, + ] + + [[package]] + name = "project" + version = "0.1.0" + source = { editable = "." } + dependencies = [ + { name = "numpy", marker = "platform_machine == 'i686'" }, + ] + + [package.metadata] + requires-dist = [{ name = "numpy" }] + "### + ); + }); + + Ok(()) +} + #[test] fn lock_script() -> Result<()> { let context = TestContext::new("3.12"); diff --git a/crates/uv/tests/it/lock_scenarios.rs b/crates/uv/tests/it/lock_scenarios.rs index a645f4f0f..0f4d5c267 100644 --- a/crates/uv/tests/it/lock_scenarios.rs +++ b/crates/uv/tests/it/lock_scenarios.rs @@ -1,7 +1,7 @@ //! DO NOT EDIT //! //! Generated with `./scripts/sync_scenarios.sh` -//! Scenarios from +//! Scenarios from //! #![cfg(all(feature = "python", feature = "pypi"))] #![allow(clippy::needless_raw_string_hashes)] @@ -4875,3 +4875,143 @@ fn unreachable_wheels() -> Result<()> { Ok(()) } + +/// When a dependency is only required on a specific platform (like x86_64), omit wheels that target other platforms (like aarch64). +/// +/// ```text +/// specific-architecture +/// ├── environment +/// │ └── python3.8 +/// ├── root +/// │ └── requires a +/// │ └── satisfied by a-1.0.0 +/// ├── a +/// │ └── a-1.0.0 +/// │ ├── requires b; platform_machine == "x86_64" +/// │ │ └── satisfied by b-1.0.0 +/// │ ├── requires c; platform_machine == "aarch64" +/// │ │ └── satisfied by c-1.0.0 +/// │ └── requires d; platform_machine == "i686" +/// │ └── satisfied by d-1.0.0 +/// ├── b +/// │ └── b-1.0.0 +/// ├── c +/// │ └── c-1.0.0 +/// └── d +/// └── d-1.0.0 +/// ``` +#[test] +fn specific_architecture() -> Result<()> { + let context = TestContext::new("3.8"); + + // In addition to the standard filters, swap out package names for shorter messages + let mut filters = context.filters(); + filters.push((r"specific-architecture-", "package-")); + + let pyproject_toml = context.temp_dir.child("pyproject.toml"); + pyproject_toml.write_str( + r###" + [project] + name = "project" + version = "0.1.0" + dependencies = [ + '''specific-architecture-a''', + ] + requires-python = ">=3.8" + "###, + )?; + + let mut cmd = context.lock(); + cmd.env_remove(EnvVars::UV_EXCLUDE_NEWER); + cmd.arg("--index-url").arg(packse_index_url()); + uv_snapshot!(filters, cmd, @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 5 packages in [TIME] + "### + ); + + let lock = context.read("uv.lock"); + insta::with_settings!({ + filters => filters, + }, { + assert_snapshot!( + lock, @r###" + version = 1 + requires-python = ">=3.8" + + [[package]] + name = "project" + version = "0.1.0" + source = { virtual = "." } + dependencies = [ + { name = "package-a" }, + ] + + [package.metadata] + requires-dist = [{ name = "package-a" }] + + [[package]] + name = "package-a" + version = "1.0.0" + source = { registry = "https://astral-sh.github.io/packse/PACKSE_VERSION/simple-html/" } + dependencies = [ + { name = "package-b", marker = "platform_machine == 'x86_64'" }, + { name = "package-c", marker = "platform_machine == 'aarch64'" }, + { name = "package-d", marker = "platform_machine == 'i686'" }, + ] + sdist = { url = "https://astral-sh.github.io/packse/PACKSE_VERSION/files/specific_architecture_a-1.0.0.tar.gz", hash = "sha256:3543f7e4bc8aaf16a9705e07df1521f40a77407c7a33a82424b35ef63df8224a" } + wheels = [ + { url = "https://astral-sh.github.io/packse/PACKSE_VERSION/files/specific_architecture_a-1.0.0-py3-none-any.whl", hash = "sha256:cd2f9894093805af0749592e8239d62e7a724476a74c4cb65da30bc6a3900046" }, + ] + + [[package]] + name = "package-b" + 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/specific_architecture_b-1.0.0-cp313-cp313-freebsd_13_aarch64.whl", hash = "sha256:4ce70a68440d4aaa31cc1c6174b83b741e9b8f3074ad0f3ef41c572795378999" }, + { url = "https://astral-sh.github.io/packse/PACKSE_VERSION/files/specific_architecture_b-1.0.0-cp313-cp313-freebsd_13_x86_64.whl", hash = "sha256:4ce70a68440d4aaa31cc1c6174b83b741e9b8f3074ad0f3ef41c572795378999" }, + { url = "https://astral-sh.github.io/packse/PACKSE_VERSION/files/specific_architecture_b-1.0.0-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:4ce70a68440d4aaa31cc1c6174b83b741e9b8f3074ad0f3ef41c572795378999" }, + { url = "https://astral-sh.github.io/packse/PACKSE_VERSION/files/specific_architecture_b-1.0.0-cp313-cp313-manylinux2010_x86_64.whl", hash = "sha256:4ce70a68440d4aaa31cc1c6174b83b741e9b8f3074ad0f3ef41c572795378999" }, + ] + + [[package]] + name = "package-c" + 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/specific_architecture_c-1.0.0-cp313-cp313-freebsd_13_aarch64.whl", hash = "sha256:b028c88fe496724cea4a7d95eb789a000b7f000067f95c922b09461be2746a3d" }, + { url = "https://astral-sh.github.io/packse/PACKSE_VERSION/files/specific_architecture_c-1.0.0-cp313-cp313-freebsd_13_x86_64.whl", hash = "sha256:b028c88fe496724cea4a7d95eb789a000b7f000067f95c922b09461be2746a3d" }, + { url = "https://astral-sh.github.io/packse/PACKSE_VERSION/files/specific_architecture_c-1.0.0-cp313-cp313-macosx_10_9_arm64.whl", hash = "sha256:b028c88fe496724cea4a7d95eb789a000b7f000067f95c922b09461be2746a3d" }, + { url = "https://astral-sh.github.io/packse/PACKSE_VERSION/files/specific_architecture_c-1.0.0-cp313-cp313-manylinux2010_aarch64.whl", hash = "sha256:b028c88fe496724cea4a7d95eb789a000b7f000067f95c922b09461be2746a3d" }, + ] + + [[package]] + name = "package-d" + 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/specific_architecture_d-1.0.0-cp313-cp313-freebsd_13_aarch64.whl", hash = "sha256:842864c1348694fab33199eb05921602c2abfc77844a81085a55db02edd30da4" }, + { url = "https://astral-sh.github.io/packse/PACKSE_VERSION/files/specific_architecture_d-1.0.0-cp313-cp313-freebsd_13_x86_64.whl", hash = "sha256:842864c1348694fab33199eb05921602c2abfc77844a81085a55db02edd30da4" }, + { url = "https://astral-sh.github.io/packse/PACKSE_VERSION/files/specific_architecture_d-1.0.0-cp313-cp313-manylinux2010_i686.whl", hash = "sha256:842864c1348694fab33199eb05921602c2abfc77844a81085a55db02edd30da4" }, + ] + "### + ); + }); + + // 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(()) +} diff --git a/crates/uv/tests/it/pip_compile_scenarios.rs b/crates/uv/tests/it/pip_compile_scenarios.rs index a49792c87..be3e26872 100644 --- a/crates/uv/tests/it/pip_compile_scenarios.rs +++ b/crates/uv/tests/it/pip_compile_scenarios.rs @@ -1,7 +1,7 @@ //! DO NOT EDIT //! //! Generated with `./scripts/sync_scenarios.sh` -//! Scenarios from +//! Scenarios from //! #![cfg(all(feature = "python", feature = "pypi", unix))] diff --git a/crates/uv/tests/it/pip_install_scenarios.rs b/crates/uv/tests/it/pip_install_scenarios.rs index 9dd647c7d..e777439ca 100644 --- a/crates/uv/tests/it/pip_install_scenarios.rs +++ b/crates/uv/tests/it/pip_install_scenarios.rs @@ -1,7 +1,7 @@ //! DO NOT EDIT //! //! Generated with `./scripts/sync_scenarios.sh` -//! Scenarios from +//! Scenarios from //! #![cfg(all(feature = "python", feature = "pypi", unix))] diff --git a/crates/uv/tests/it/snapshots/it__ecosystem__transformers-lock-file.snap b/crates/uv/tests/it/snapshots/it__ecosystem__transformers-lock-file.snap index 2ed54f7ce..3674a0095 100644 --- a/crates/uv/tests/it/snapshots/it__ecosystem__transformers-lock-file.snap +++ b/crates/uv/tests/it/snapshots/it__ecosystem__transformers-lock-file.snap @@ -2511,7 +2511,6 @@ name = "nvidia-nccl-cu12" version = "2.20.5" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/bb/d09dda47c881f9ff504afd6f9ca4f502ded6d8fc2f572cacc5e39da91c28/nvidia_nccl_cu12-2.20.5-py3-none-manylinux2014_aarch64.whl", hash = "sha256:1fc150d5c3250b170b29410ba682384b14581db722b2531b0d8d33c595f33d01", size = 176238458 }, { url = "https://files.pythonhosted.org/packages/4b/2a/0a131f572aa09f741c30ccd45a8e56316e8be8dfc7bc19bf0ab7cfef7b19/nvidia_nccl_cu12-2.20.5-py3-none-manylinux2014_x86_64.whl", hash = "sha256:057f6bf9685f75215d0c53bf3ac4a10b3e6578351de307abad9e18a99182af56", size = 176249402 }, ] @@ -2520,7 +2519,6 @@ name = "nvidia-nvjitlink-cu12" version = "12.6.20" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/81/b3/e456a1b2d499bb84bdc6670bfbcf41ff3bac58bd2fae6880d62834641558/nvidia_nvjitlink_cu12-12.6.20-py3-none-manylinux2014_aarch64.whl", hash = "sha256:84fb38465a5bc7c70cbc320cfd0963eb302ee25a5e939e9f512bbba55b6072fb", size = 19252608 }, { url = "https://files.pythonhosted.org/packages/59/65/7ff0569494fbaea45ad2814972cc88da843d53cc96eb8554fcd0908941d9/nvidia_nvjitlink_cu12-12.6.20-py3-none-manylinux2014_x86_64.whl", hash = "sha256:562ab97ea2c23164823b2a89cb328d01d45cb99634b8c65fe7cd60d14562bd79", size = 19724950 }, ] diff --git a/scripts/scenarios/requirements.txt b/scripts/scenarios/requirements.txt index 733e9ea67..09e4fcf19 100644 --- a/scripts/scenarios/requirements.txt +++ b/scripts/scenarios/requirements.txt @@ -10,7 +10,7 @@ msgspec==0.18.6 # via packse packaging==24.2 # via hatchling -packse==0.3.44 +packse==0.3.45 # via -r scripts/scenarios/requirements.in pathspec==0.12.1 # via hatchling