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