diff --git a/crates/uv-distribution-types/src/prioritized_distribution.rs b/crates/uv-distribution-types/src/prioritized_distribution.rs index def371bc2..c6261076a 100644 --- a/crates/uv-distribution-types/src/prioritized_distribution.rs +++ b/crates/uv-distribution-types/src/prioritized_distribution.rs @@ -45,7 +45,7 @@ impl Default for PrioritizedDistInner { } /// A distribution that can be used for both resolution and installation. -#[derive(Debug, Clone)] +#[derive(Debug, Copy, Clone)] pub enum CompatibleDist<'a> { /// The distribution is already installed and can be used. InstalledDist(&'a InstalledDist), @@ -314,6 +314,12 @@ impl PrioritizedDist { hashes: impl IntoIterator, compatibility: WheelCompatibility, ) { + // Track the implied markers. + if compatibility.is_compatible() { + if !self.0.markers.is_true() { + self.0.markers.or(implied_markers(&dist.filename)); + } + } // Track the highest-priority wheel. if let Some((.., existing_compatibility)) = self.best_wheel() { if compatibility.is_more_compatible(existing_compatibility) { @@ -323,9 +329,6 @@ impl PrioritizedDist { self.0.best_wheel_index = Some(self.0.wheels.len()); } self.0.hashes.extend(hashes); - if !self.0.markers.is_true() { - self.0.markers.or(implied_markers(&dist.filename)); - } self.0.wheels.push((dist, compatibility)); } @@ -336,6 +339,10 @@ impl PrioritizedDist { hashes: impl IntoIterator, compatibility: SourceDistCompatibility, ) { + // Track the implied markers. + if compatibility.is_compatible() { + self.0.markers = MarkerTree::TRUE; + } // Track the highest-priority source. if let Some((.., existing_compatibility)) = &self.0.source { if compatibility.is_more_compatible(existing_compatibility) { @@ -344,9 +351,6 @@ impl PrioritizedDist { } else { self.0.source = Some((dist, compatibility)); } - if !self.0.markers.is_true() { - self.0.markers.or(MarkerTree::TRUE); - } self.0.hashes.extend(hashes); } @@ -526,6 +530,7 @@ impl<'a> CompatibleDist<'a> { } impl WheelCompatibility { + /// Return `true` if the distribution is compatible. pub fn is_compatible(&self) -> bool { matches!(self, Self::Compatible(_, _, _)) } @@ -552,6 +557,11 @@ impl WheelCompatibility { } impl SourceDistCompatibility { + /// Return `true` if the distribution is compatible. + pub fn is_compatible(&self) -> bool { + matches!(self, Self::Compatible(_)) + } + /// Return the higher priority compatibility. /// /// Compatible source distributions are always higher priority than incompatible source distributions. diff --git a/crates/uv-pep440/src/version.rs b/crates/uv-pep440/src/version.rs index 7eeb2ad19..aaf8dfc1e 100644 --- a/crates/uv-pep440/src/version.rs +++ b/crates/uv-pep440/src/version.rs @@ -1616,7 +1616,7 @@ impl LocalVersionSlice<'_> { /// > should be considered an integer for comparison purposes and if a segment contains any ASCII /// > letters then that segment is compared lexicographically with case insensitivity. When /// > comparing a numeric and lexicographic segment, the numeric section always compares as greater -/// > than the lexicographic segment. Additionally a local version with a great number of segments +/// > than the lexicographic segment. Additionally, a local version with a great number of segments /// > will always compare as greater than a local version with fewer segments, as long as the /// > shorter local version’s segments match the beginning of the longer local version’s segments /// > exactly. diff --git a/crates/uv/tests/it/pip_compile.rs b/crates/uv/tests/it/pip_compile.rs index 0d997d65e..9fc609c56 100644 --- a/crates/uv/tests/it/pip_compile.rs +++ b/crates/uv/tests/it/pip_compile.rs @@ -7629,9 +7629,9 @@ fn universal_transitive_disjoint_locals() -> Result<()> { # -r requirements.in # torchvision # triton - torchvision==0.15.1 ; platform_machine != 'x86_64' or sys_platform == 'darwin' or sys_platform == 'win32' + torchvision==0.15.1 ; platform_machine != 'x86_64' or sys_platform == 'darwin' # via -r requirements.in - torchvision==0.15.1+rocm5.4.2 ; platform_machine == 'x86_64' and sys_platform != 'darwin' and sys_platform != 'win32' + torchvision==0.15.1+rocm5.4.2 ; platform_machine == 'x86_64' and sys_platform != 'darwin' # via -r requirements.in triton==2.0.0 ; platform_machine == 'x86_64' and sys_platform == 'linux' # via torch @@ -8010,7 +8010,7 @@ fn universal_nested_overlapping_local_requirement() -> Result<()> { # via sympy networkx==3.2.1 # via torch - pytorch-triton-rocm==2.3.0 ; (implementation_name != 'cpython' and platform_machine != 'aarch64' and sys_platform == 'linux') or (implementation_name != 'cpython' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32') + pytorch-triton-rocm==2.3.0 ; (implementation_name != 'cpython' and platform_machine != 'aarch64' and sys_platform == 'linux') or (implementation_name != 'cpython' and sys_platform != 'darwin' and sys_platform != 'linux') # via torch sympy==1.12 # via torch @@ -8021,9 +8021,9 @@ fn universal_nested_overlapping_local_requirement() -> Result<()> { # -r requirements.in # example # triton - torch==2.3.0 ; (implementation_name != 'cpython' and platform_machine == 'aarch64' and sys_platform == 'linux') or (implementation_name != 'cpython' and sys_platform == 'darwin') or (implementation_name != 'cpython' and sys_platform == 'win32') + torch==2.3.0 ; (implementation_name != 'cpython' and platform_machine == 'aarch64' and sys_platform == 'linux') or (implementation_name != 'cpython' and sys_platform == 'darwin') # via -r requirements.in - torch==2.3.0+rocm6.0 ; (implementation_name != 'cpython' and platform_machine != 'aarch64' and sys_platform == 'linux') or (implementation_name != 'cpython' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32') + torch==2.3.0+rocm6.0 ; (implementation_name != 'cpython' and platform_machine != 'aarch64' and sys_platform == 'linux') or (implementation_name != 'cpython' and sys_platform != 'darwin' and sys_platform != 'linux') # via -r requirements.in triton==2.0.0 ; implementation_name == 'cpython' and platform_machine == 'x86_64' and sys_platform == 'linux' # via torch @@ -8174,7 +8174,7 @@ fn universal_nested_disjoint_local_requirement() -> Result<()> { # via sympy networkx==3.2.1 # via torch - pytorch-triton-rocm==2.3.0 ; (os_name != 'Linux' and platform_machine != 'aarch64' and sys_platform == 'linux') or (os_name != 'Linux' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32') + pytorch-triton-rocm==2.3.0 ; (os_name != 'Linux' and platform_machine != 'aarch64' and sys_platform == 'linux') or (os_name != 'Linux' and sys_platform != 'darwin' and sys_platform != 'linux') # via torch sympy==1.12 # via torch @@ -8189,9 +8189,9 @@ fn universal_nested_disjoint_local_requirement() -> Result<()> { # -r requirements.in # example # triton - torch==2.3.0 ; (os_name != 'Linux' and platform_machine == 'aarch64' and sys_platform == 'linux') or (os_name != 'Linux' and sys_platform == 'darwin') or (os_name != 'Linux' and sys_platform == 'win32') + torch==2.3.0 ; (os_name != 'Linux' and platform_machine == 'aarch64' and sys_platform == 'linux') or (os_name != 'Linux' and sys_platform == 'darwin') # via -r requirements.in - torch==2.3.0+rocm6.0 ; (os_name != 'Linux' and platform_machine != 'aarch64' and sys_platform == 'linux') or (os_name != 'Linux' and sys_platform != 'darwin' and sys_platform != 'linux' and sys_platform != 'win32') + torch==2.3.0+rocm6.0 ; (os_name != 'Linux' and platform_machine != 'aarch64' and sys_platform == 'linux') or (os_name != 'Linux' and sys_platform != 'darwin' and sys_platform != 'linux') # via -r requirements.in triton==2.0.0 ; implementation_name == 'cpython' and os_name == 'Linux' and platform_machine == 'x86_64' and sys_platform == 'linux' # via torch