From 1c08e6ec54213d8361ceb8e0bff1013d4c76f9f5 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Wed, 11 Sep 2024 15:08:24 -0400 Subject: [PATCH] Avoid enforcing platform compatibility when validating lockfile --- crates/uv-resolver/src/lock/mod.rs | 43 +++++++++++++++++++++++++----- crates/uv/tests/sync.rs | 2 -- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/crates/uv-resolver/src/lock/mod.rs b/crates/uv-resolver/src/lock/mod.rs index a39867c9530e8..3299ec3ca97ea 100644 --- a/crates/uv-resolver/src/lock/mod.rs +++ b/crates/uv-resolver/src/lock/mod.rs @@ -643,7 +643,7 @@ impl Lock { dist.id.name.clone(), ResolvedDist::Installable(dist.to_dist( project.workspace().install_path(), - tags, + TagPolicy::Required(tags), build_options, )?), ); @@ -1088,7 +1088,11 @@ impl Lock { } // Get the metadata for the distribution. - let dist = package.to_dist(workspace.install_path(), tags, build_options)?; + let dist = package.to_dist( + workspace.install_path(), + TagPolicy::Preferred(tags), + build_options, + )?; let Ok(archive) = database .get_or_build_wheel_metadata(&dist, HashPolicy::None) @@ -1201,6 +1205,24 @@ impl Lock { } } +#[derive(Debug, Copy, Clone)] +enum TagPolicy<'tags> { + /// Exclusively consider wheels that match the specified platform tags. + Required(&'tags Tags), + /// Prefer wheels that match the specified platform tags, but fall back to incompatible wheels + /// if necessary. + Preferred(&'tags Tags), +} + +impl<'tags> TagPolicy<'tags> { + /// Returns the platform tags to consider. + fn tags(&self) -> &'tags Tags { + match self { + TagPolicy::Required(tags) | TagPolicy::Preferred(tags) => tags, + } + } +} + /// The result of checking if a lockfile satisfies a set of requirements. #[derive(Debug)] pub enum SatisfiesResult<'lock> { @@ -1595,14 +1617,14 @@ impl Package { fn to_dist( &self, workspace_root: &Path, - tags: &Tags, + tag_policy: TagPolicy<'_>, build_options: &BuildOptions, ) -> Result { let no_binary = build_options.no_binary_package(&self.id.name); let no_build = build_options.no_build_package(&self.id.name); if !no_binary { - if let Some(best_wheel_index) = self.find_best_wheel(tags) { + if let Some(best_wheel_index) = self.find_best_wheel(tag_policy) { return match &self.id.source { Source::Registry(source) => { let wheels = self @@ -2016,10 +2038,12 @@ impl Package { Ok(table) } - fn find_best_wheel(&self, tags: &Tags) -> Option { + fn find_best_wheel(&self, tag_policy: TagPolicy<'_>) -> Option { let mut best: Option<(TagPriority, usize)> = None; for (i, wheel) in self.wheels.iter().enumerate() { - let TagCompatibility::Compatible(priority) = wheel.filename.compatibility(tags) else { + let TagCompatibility::Compatible(priority) = + wheel.filename.compatibility(tag_policy.tags()) + else { continue; }; match best { @@ -2033,7 +2057,12 @@ impl Package { } } } - best.map(|(_, i)| i) + + let best = best.map(|(_, i)| i); + match tag_policy { + TagPolicy::Required(_) => best, + TagPolicy::Preferred(_) => best.or_else(|| self.wheels.first().map(|_| 0)), + } } /// Returns the [`PackageName`] of the package. diff --git a/crates/uv/tests/sync.rs b/crates/uv/tests/sync.rs index ed2d47b32c1e7..e3d43d193d206 100644 --- a/crates/uv/tests/sync.rs +++ b/crates/uv/tests/sync.rs @@ -2194,7 +2194,6 @@ fn sync_wheel_url_source_error() -> Result<()> { ----- stdout ----- ----- stderr ----- - warning: Failed to validate existing lockfile: distribution cffi==1.17.1 @ direct+https://files.pythonhosted.org/packages/08/fd/cc2fedbd887223f9f5d170c96e57cbf655df9831a6546c1727ae13fa977a/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl can't be installed because it doesn't have a source distribution or wheel for the current platform Resolved 3 packages in [TIME] error: distribution cffi==1.17.1 @ direct+https://files.pythonhosted.org/packages/08/fd/cc2fedbd887223f9f5d170c96e57cbf655df9831a6546c1727ae13fa977a/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl can't be installed because it doesn't have a source distribution or wheel for the current platform "###); @@ -2243,7 +2242,6 @@ fn sync_wheel_path_source_error() -> Result<()> { ----- stdout ----- ----- stderr ----- - warning: Failed to validate existing lockfile: distribution cffi==1.17.1 @ path+cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl can't be installed because it doesn't have a source distribution or wheel for the current platform Resolved 3 packages in [TIME] error: distribution cffi==1.17.1 @ path+cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl can't be installed because it doesn't have a source distribution or wheel for the current platform "###);