From 47cb7a53caf7a7c418a1b26a82589d574ca718c8 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Sun, 24 Nov 2024 22:41:45 -0500 Subject: [PATCH] Add a lowered representation for markers (#9341) ## Summary This PR introduces a set of parallel structs to `MarkerValueString`, `MarkerValueExtra`, and `MarkerValueVersion` that remove various pieces of information and representations that shouldn't be available in the marker algebra. To start, I've _just_ removed the invalid extra component from `MarkerValueExtra` -- there are no other changes to the representation. So, throughout the marker algebra, we can't represent and thus don't have to worry about clauses with invalid extras. The subsequent changes I plan to make are: 1. Removing `python_version`, since we exclusively use `python_version_full` in the algebra. 2. Removing the deprecated aliases, such that we re-map to the correct marker value. 3. Consolidating `sys_platform` and `platform_release` (the original motivation). --- crates/uv-pep508/src/lib.rs | 3 +- crates/uv-pep508/src/marker/algebra.rs | 90 +++++++--- crates/uv-pep508/src/marker/environment.rs | 43 ++--- crates/uv-pep508/src/marker/lowering.rs | 186 ++++++++++++++++++++ crates/uv-pep508/src/marker/mod.rs | 2 + crates/uv-pep508/src/marker/simplify.rs | 16 +- crates/uv-pep508/src/marker/tree.rs | 61 +++---- crates/uv-resolver/src/marker.rs | 10 +- crates/uv-resolver/src/resolution/output.rs | 11 +- 9 files changed, 320 insertions(+), 102 deletions(-) create mode 100644 crates/uv-pep508/src/marker/lowering.rs diff --git a/crates/uv-pep508/src/lib.rs b/crates/uv-pep508/src/lib.rs index 493746c124b0..338c4e146e29 100644 --- a/crates/uv-pep508/src/lib.rs +++ b/crates/uv-pep508/src/lib.rs @@ -28,7 +28,8 @@ use url::Url; use cursor::Cursor; pub use marker::{ - ContainsMarkerTree, ExtraMarkerTree, ExtraOperator, InMarkerTree, MarkerEnvironment, + ContainsMarkerTree, ExtraMarkerTree, ExtraOperator, InMarkerTree, LoweredMarkerValueExtra, + LoweredMarkerValueString, LoweredMarkerValueVersion, MarkerEnvironment, MarkerEnvironmentBuilder, MarkerExpression, MarkerOperator, MarkerTree, MarkerTreeContents, MarkerTreeKind, MarkerValue, MarkerValueExtra, MarkerValueString, MarkerValueVersion, MarkerWarningKind, StringMarkerTree, StringVersion, VersionMarkerTree, diff --git a/crates/uv-pep508/src/marker/algebra.rs b/crates/uv-pep508/src/marker/algebra.rs index 773d822c3f7c..4a18acd2fff0 100644 --- a/crates/uv-pep508/src/marker/algebra.rs +++ b/crates/uv-pep508/src/marker/algebra.rs @@ -56,9 +56,12 @@ use std::sync::LazyLock; use uv_pep440::{release_specifier_to_range, Operator, Version, VersionSpecifier}; use version_ranges::Ranges; +use crate::marker::lowering::{ + LoweredMarkerValueExtra, LoweredMarkerValueString, LoweredMarkerValueVersion, +}; use crate::marker::MarkerValueExtra; use crate::ExtraOperator; -use crate::{MarkerExpression, MarkerOperator, MarkerValueString, MarkerValueVersion}; +use crate::{MarkerExpression, MarkerOperator, MarkerValueVersion}; /// The global node interner. pub(crate) static INTERNER: LazyLock = LazyLock::new(Interner::default); @@ -161,7 +164,7 @@ impl InternerGuard<'_> { specifier, } => match python_version_to_full_version(normalize_specifier(specifier)) { Ok(specifier) => ( - Variable::Version(MarkerValueVersion::PythonFullVersion), + Variable::Version(LoweredMarkerValueVersion::PythonFullVersion), Edges::from_specifier(specifier), ), Err(node) => return node, @@ -172,16 +175,17 @@ impl InternerGuard<'_> { negated, } => match Edges::from_python_versions(versions, negated) { Ok(edges) => ( - Variable::Version(MarkerValueVersion::PythonFullVersion), + Variable::Version(LoweredMarkerValueVersion::PythonFullVersion), edges, ), Err(node) => return node, }, // A variable representing the output of a version key. Edges correspond // to disjoint version ranges. - MarkerExpression::Version { key, specifier } => { - (Variable::Version(key), Edges::from_specifier(specifier)) - } + MarkerExpression::Version { key, specifier } => ( + Variable::Version(key.into()), + Edges::from_specifier(specifier), + ), // A variable representing the output of a version key. Edges correspond // to disjoint version ranges. MarkerExpression::VersionIn { @@ -189,7 +193,7 @@ impl InternerGuard<'_> { versions, negated, } => ( - Variable::Version(key), + Variable::Version(key.into()), Edges::from_versions(&versions, negated), ), // The `in` and `contains` operators are a bit different than other operators. @@ -206,38 +210,76 @@ impl InternerGuard<'_> { key, operator: MarkerOperator::In, value, - } => (Variable::In { key, value }, Edges::from_bool(true)), + } => ( + Variable::In { + key: key.into(), + value, + }, + Edges::from_bool(true), + ), MarkerExpression::String { key, operator: MarkerOperator::NotIn, value, - } => (Variable::In { key, value }, Edges::from_bool(false)), + } => ( + Variable::In { + key: key.into(), + value, + }, + Edges::from_bool(false), + ), MarkerExpression::String { key, operator: MarkerOperator::Contains, value, - } => (Variable::Contains { key, value }, Edges::from_bool(true)), + } => ( + Variable::Contains { + key: key.into(), + value, + }, + Edges::from_bool(true), + ), MarkerExpression::String { key, operator: MarkerOperator::NotContains, value, - } => (Variable::Contains { key, value }, Edges::from_bool(false)), + } => ( + Variable::Contains { + key: key.into(), + value, + }, + Edges::from_bool(false), + ), // A variable representing the output of a string key. Edges correspond // to disjoint string ranges. MarkerExpression::String { key, operator, value, - } => (Variable::String(key), Edges::from_string(operator, value)), + } => ( + Variable::String(key.into()), + Edges::from_string(operator, value), + ), // A variable representing the existence or absence of a particular extra. MarkerExpression::Extra { - name, + name: MarkerValueExtra::Extra(extra), operator: ExtraOperator::Equal, - } => (Variable::Extra(name), Edges::from_bool(true)), + } => ( + Variable::Extra(LoweredMarkerValueExtra::Extra(extra)), + Edges::from_bool(true), + ), MarkerExpression::Extra { - name, + name: MarkerValueExtra::Extra(extra), operator: ExtraOperator::NotEqual, - } => (Variable::Extra(name), Edges::from_bool(false)), + } => ( + Variable::Extra(LoweredMarkerValueExtra::Extra(extra)), + Edges::from_bool(false), + ), + // Invalid extras are always `false`. + MarkerExpression::Extra { + name: MarkerValueExtra::Arbitrary(_), + .. + } => return NodeId::FALSE, }; self.create_node(var, children) @@ -391,7 +433,7 @@ impl InternerGuard<'_> { // Look for a `python_full_version` expression, otherwise // we recursively simplify. let Node { - var: Variable::Version(MarkerValueVersion::PythonFullVersion), + var: Variable::Version(LoweredMarkerValueVersion::PythonFullVersion), children: Edges::Version { ref edges }, } = node else { @@ -464,7 +506,7 @@ impl InternerGuard<'_> { return NodeId::FALSE; } if matches!(i, NodeId::TRUE) { - let var = Variable::Version(MarkerValueVersion::PythonFullVersion); + let var = Variable::Version(LoweredMarkerValueVersion::PythonFullVersion); let edges = Edges::Version { edges: Edges::from_range(&py_range), }; @@ -473,7 +515,7 @@ impl InternerGuard<'_> { let node = self.shared.node(i); let Node { - var: Variable::Version(MarkerValueVersion::PythonFullVersion), + var: Variable::Version(LoweredMarkerValueVersion::PythonFullVersion), children: Edges::Version { ref edges }, } = node else { @@ -569,26 +611,26 @@ pub(crate) enum Variable { /// /// This is the highest order variable as it typically contains the most complex /// ranges, allowing us to merge ranges at the top-level. - Version(MarkerValueVersion), + Version(LoweredMarkerValueVersion), /// A string marker, such as `os_name`. - String(MarkerValueString), + String(LoweredMarkerValueString), /// A variable representing a ` in ` expression for a particular /// string marker and value. In { - key: MarkerValueString, + key: LoweredMarkerValueString, value: String, }, /// A variable representing a ` in ` expression for a particular /// string marker and value. Contains { - key: MarkerValueString, + key: LoweredMarkerValueString, value: String, }, /// A variable representing the existence or absence of a given extra. /// /// We keep extras at the leaves of the tree, so when simplifying extras we can /// trivially remove the leaves without having to reconstruct the entire tree. - Extra(MarkerValueExtra), + Extra(LoweredMarkerValueExtra), } /// A decision node in an Algebraic Decision Diagram. diff --git a/crates/uv-pep508/src/marker/environment.rs b/crates/uv-pep508/src/marker/environment.rs index 6cdfe88257b2..de0fbe8fff64 100644 --- a/crates/uv-pep508/src/marker/environment.rs +++ b/crates/uv-pep508/src/marker/environment.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use uv_pep440::{Version, VersionParseError}; -use crate::{MarkerValueString, MarkerValueVersion, StringVersion}; +use crate::{LoweredMarkerValueString, LoweredMarkerValueVersion, StringVersion}; /// The marker values for a python interpreter, normally the current one /// @@ -33,35 +33,36 @@ struct MarkerEnvironmentInner { impl MarkerEnvironment { /// Returns of the PEP 440 version typed value of the key in the current environment - pub fn get_version(&self, key: MarkerValueVersion) -> &Version { + pub fn get_version(&self, key: LoweredMarkerValueVersion) -> &Version { match key { - MarkerValueVersion::ImplementationVersion => &self.implementation_version().version, - MarkerValueVersion::PythonFullVersion => &self.python_full_version().version, - MarkerValueVersion::PythonVersion => &self.python_version().version, + LoweredMarkerValueVersion::ImplementationVersion => { + &self.implementation_version().version + } + LoweredMarkerValueVersion::PythonFullVersion => &self.python_full_version().version, + LoweredMarkerValueVersion::PythonVersion => &self.python_version().version, } } /// Returns of the stringly typed value of the key in the current environment - pub fn get_string(&self, key: MarkerValueString) -> &str { + pub fn get_string(&self, key: LoweredMarkerValueString) -> &str { match key { - MarkerValueString::ImplementationName => self.implementation_name(), - MarkerValueString::OsName | MarkerValueString::OsNameDeprecated => self.os_name(), - MarkerValueString::PlatformMachine | MarkerValueString::PlatformMachineDeprecated => { - self.platform_machine() + LoweredMarkerValueString::ImplementationName => self.implementation_name(), + LoweredMarkerValueString::OsName | LoweredMarkerValueString::OsNameDeprecated => { + self.os_name() } - MarkerValueString::PlatformPythonImplementation - | MarkerValueString::PlatformPythonImplementationDeprecated - | MarkerValueString::PythonImplementationDeprecated => { + LoweredMarkerValueString::PlatformMachine + | LoweredMarkerValueString::PlatformMachineDeprecated => self.platform_machine(), + LoweredMarkerValueString::PlatformPythonImplementation + | LoweredMarkerValueString::PlatformPythonImplementationDeprecated + | LoweredMarkerValueString::PythonImplementationDeprecated => { self.platform_python_implementation() } - MarkerValueString::PlatformRelease => self.platform_release(), - MarkerValueString::PlatformSystem => self.platform_system(), - MarkerValueString::PlatformVersion | MarkerValueString::PlatformVersionDeprecated => { - self.platform_version() - } - MarkerValueString::SysPlatform | MarkerValueString::SysPlatformDeprecated => { - self.sys_platform() - } + LoweredMarkerValueString::PlatformRelease => self.platform_release(), + LoweredMarkerValueString::PlatformSystem => self.platform_system(), + LoweredMarkerValueString::PlatformVersion + | LoweredMarkerValueString::PlatformVersionDeprecated => self.platform_version(), + LoweredMarkerValueString::SysPlatform + | LoweredMarkerValueString::SysPlatformDeprecated => self.sys_platform(), } } } diff --git a/crates/uv-pep508/src/marker/lowering.rs b/crates/uv-pep508/src/marker/lowering.rs new file mode 100644 index 000000000000..056135278019 --- /dev/null +++ b/crates/uv-pep508/src/marker/lowering.rs @@ -0,0 +1,186 @@ +use std::fmt::{Display, Formatter}; + +use uv_normalize::ExtraName; + +use crate::{MarkerValueExtra, MarkerValueString, MarkerValueVersion}; + +/// Those environment markers with a PEP 440 version as value such as `python_version` +#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] +#[allow(clippy::enum_variant_names)] +pub enum LoweredMarkerValueVersion { + /// `implementation_version` + ImplementationVersion, + /// `python_full_version` + PythonFullVersion, + /// `python_version` + PythonVersion, +} + +impl Display for LoweredMarkerValueVersion { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Self::ImplementationVersion => f.write_str("implementation_version"), + Self::PythonFullVersion => f.write_str("python_full_version"), + Self::PythonVersion => f.write_str("python_version"), + } + } +} + +impl From for LoweredMarkerValueVersion { + fn from(value: MarkerValueVersion) -> Self { + match value { + MarkerValueVersion::ImplementationVersion => Self::ImplementationVersion, + MarkerValueVersion::PythonFullVersion => Self::PythonFullVersion, + MarkerValueVersion::PythonVersion => Self::PythonVersion, + } + } +} + +impl From for MarkerValueVersion { + fn from(value: LoweredMarkerValueVersion) -> Self { + match value { + LoweredMarkerValueVersion::ImplementationVersion => Self::ImplementationVersion, + LoweredMarkerValueVersion::PythonFullVersion => Self::PythonFullVersion, + LoweredMarkerValueVersion::PythonVersion => Self::PythonVersion, + } + } +} + +/// Those environment markers with an arbitrary string as value such as `sys_platform` +#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] +pub enum LoweredMarkerValueString { + /// `implementation_name` + ImplementationName, + /// `os_name` + OsName, + /// Deprecated `os.name` from + OsNameDeprecated, + /// `platform_machine` + PlatformMachine, + /// Deprecated `platform.machine` from + PlatformMachineDeprecated, + /// `platform_python_implementation` + PlatformPythonImplementation, + /// Deprecated `platform.python_implementation` from + PlatformPythonImplementationDeprecated, + /// Deprecated `python_implementation` from + PythonImplementationDeprecated, + /// `platform_release` + PlatformRelease, + /// `platform_system` + PlatformSystem, + /// `platform_version` + PlatformVersion, + /// Deprecated `platform.version` from + PlatformVersionDeprecated, + /// `sys_platform` + SysPlatform, + /// Deprecated `sys.platform` from + SysPlatformDeprecated, +} + +impl From for LoweredMarkerValueString { + fn from(value: MarkerValueString) -> Self { + match value { + MarkerValueString::ImplementationName => Self::ImplementationName, + MarkerValueString::OsName => Self::OsName, + MarkerValueString::OsNameDeprecated => Self::OsNameDeprecated, + MarkerValueString::PlatformMachine => Self::PlatformMachine, + MarkerValueString::PlatformMachineDeprecated => Self::PlatformMachineDeprecated, + MarkerValueString::PlatformPythonImplementation => Self::PlatformPythonImplementation, + MarkerValueString::PlatformPythonImplementationDeprecated => { + Self::PlatformPythonImplementationDeprecated + } + MarkerValueString::PythonImplementationDeprecated => { + Self::PythonImplementationDeprecated + } + MarkerValueString::PlatformRelease => Self::PlatformRelease, + MarkerValueString::PlatformSystem => Self::PlatformSystem, + MarkerValueString::PlatformVersion => Self::PlatformVersion, + MarkerValueString::PlatformVersionDeprecated => Self::PlatformVersionDeprecated, + MarkerValueString::SysPlatform => Self::SysPlatform, + MarkerValueString::SysPlatformDeprecated => Self::SysPlatformDeprecated, + } + } +} + +impl From for MarkerValueString { + fn from(value: LoweredMarkerValueString) -> Self { + match value { + LoweredMarkerValueString::ImplementationName => Self::ImplementationName, + LoweredMarkerValueString::OsName => Self::OsName, + LoweredMarkerValueString::OsNameDeprecated => Self::OsNameDeprecated, + LoweredMarkerValueString::PlatformMachine => Self::PlatformMachine, + LoweredMarkerValueString::PlatformMachineDeprecated => Self::PlatformMachineDeprecated, + LoweredMarkerValueString::PlatformPythonImplementation => { + Self::PlatformPythonImplementation + } + LoweredMarkerValueString::PlatformPythonImplementationDeprecated => { + Self::PlatformPythonImplementationDeprecated + } + LoweredMarkerValueString::PythonImplementationDeprecated => { + Self::PythonImplementationDeprecated + } + LoweredMarkerValueString::PlatformRelease => Self::PlatformRelease, + LoweredMarkerValueString::PlatformSystem => Self::PlatformSystem, + LoweredMarkerValueString::PlatformVersion => Self::PlatformVersion, + LoweredMarkerValueString::PlatformVersionDeprecated => Self::PlatformVersionDeprecated, + LoweredMarkerValueString::SysPlatform => Self::SysPlatform, + LoweredMarkerValueString::SysPlatformDeprecated => Self::SysPlatformDeprecated, + } + } +} + +impl Display for LoweredMarkerValueString { + /// Normalizes deprecated names to the proper ones + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Self::ImplementationName => f.write_str("implementation_name"), + Self::OsName | Self::OsNameDeprecated => f.write_str("os_name"), + Self::PlatformMachine | Self::PlatformMachineDeprecated => { + f.write_str("platform_machine") + } + Self::PlatformPythonImplementation + | Self::PlatformPythonImplementationDeprecated + | Self::PythonImplementationDeprecated => f.write_str("platform_python_implementation"), + Self::PlatformRelease => f.write_str("platform_release"), + Self::PlatformSystem => f.write_str("platform_system"), + Self::PlatformVersion | Self::PlatformVersionDeprecated => { + f.write_str("platform_version") + } + Self::SysPlatform | Self::SysPlatformDeprecated => f.write_str("sys_platform"), + } + } +} + +/// The [`ExtraName`] value used in `extra` markers. +#[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] +pub enum LoweredMarkerValueExtra { + /// A valid [`ExtraName`]. + Extra(ExtraName), +} + +impl LoweredMarkerValueExtra { + /// Returns the [`ExtraName`] value. + pub fn extra(&self) -> &ExtraName { + match self { + Self::Extra(extra) => extra, + } + } +} + +impl From for MarkerValueExtra { + fn from(value: LoweredMarkerValueExtra) -> Self { + match value { + LoweredMarkerValueExtra::Extra(extra) => Self::Extra(extra), + } + } +} + +impl Display for LoweredMarkerValueExtra { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Self::Extra(extra) => extra.fmt(f), + } + } +} diff --git a/crates/uv-pep508/src/marker/mod.rs b/crates/uv-pep508/src/marker/mod.rs index 7e8f89184cb3..a6b5236d9ded 100644 --- a/crates/uv-pep508/src/marker/mod.rs +++ b/crates/uv-pep508/src/marker/mod.rs @@ -11,11 +11,13 @@ mod algebra; mod environment; +mod lowering; pub(crate) mod parse; mod simplify; mod tree; pub use environment::{MarkerEnvironment, MarkerEnvironmentBuilder}; +pub use lowering::{LoweredMarkerValueExtra, LoweredMarkerValueString, LoweredMarkerValueVersion}; pub use tree::{ ContainsMarkerTree, ExtraMarkerTree, ExtraOperator, InMarkerTree, MarkerExpression, MarkerOperator, MarkerTree, MarkerTreeContents, MarkerTreeDebugGraph, MarkerTreeKind, diff --git a/crates/uv-pep508/src/marker/simplify.rs b/crates/uv-pep508/src/marker/simplify.rs index 5104da593adf..c3ed04e43fb1 100644 --- a/crates/uv-pep508/src/marker/simplify.rs +++ b/crates/uv-pep508/src/marker/simplify.rs @@ -51,7 +51,7 @@ fn collect_dnf( let current = path.len(); for version in excluded { path.push(MarkerExpression::Version { - key: marker.key(), + key: marker.key().into(), specifier: VersionSpecifier::not_equals_version(version.clone()), }); } @@ -64,7 +64,7 @@ fn collect_dnf( // Detect whether the range for this edge can be simplified as a star inequality. if let Some(specifier) = star_range_inequality(&range) { path.push(MarkerExpression::Version { - key: marker.key(), + key: marker.key().into(), specifier, }); @@ -77,7 +77,7 @@ fn collect_dnf( let current = path.len(); for specifier in VersionSpecifier::from_release_only_bounds(bounds) { path.push(MarkerExpression::Version { - key: marker.key(), + key: marker.key().into(), specifier, }); } @@ -94,7 +94,7 @@ fn collect_dnf( let current = path.len(); for value in excluded { path.push(MarkerExpression::String { - key: marker.key(), + key: marker.key().into(), operator: MarkerOperator::NotEqual, value: value.clone(), }); @@ -109,7 +109,7 @@ fn collect_dnf( let current = path.len(); for (operator, value) in MarkerOperator::from_bounds(bounds) { path.push(MarkerExpression::String { - key: marker.key(), + key: marker.key().into(), operator, value: value.clone(), }); @@ -129,7 +129,7 @@ fn collect_dnf( }; let expr = MarkerExpression::String { - key: marker.key(), + key: marker.key().into(), value: marker.value().to_owned(), operator, }; @@ -148,7 +148,7 @@ fn collect_dnf( }; let expr = MarkerExpression::String { - key: marker.key(), + key: marker.key().into(), value: marker.value().to_owned(), operator, }; @@ -167,7 +167,7 @@ fn collect_dnf( }; let expr = MarkerExpression::Extra { - name: marker.name().clone(), + name: marker.name().clone().into(), operator, }; diff --git a/crates/uv-pep508/src/marker/tree.rs b/crates/uv-pep508/src/marker/tree.rs index 15bdaa7e325b..7697751f72d8 100644 --- a/crates/uv-pep508/src/marker/tree.rs +++ b/crates/uv-pep508/src/marker/tree.rs @@ -10,15 +10,17 @@ use uv_normalize::ExtraName; use uv_pep440::{Version, VersionParseError, VersionSpecifier}; use version_ranges::Ranges; +use super::algebra::{Edges, NodeId, Variable, INTERNER}; +use super::simplify; use crate::cursor::Cursor; +use crate::marker::lowering::{ + LoweredMarkerValueExtra, LoweredMarkerValueString, LoweredMarkerValueVersion, +}; use crate::marker::parse; use crate::{ MarkerEnvironment, Pep508Error, Pep508ErrorSource, Pep508Url, Reporter, TracingReporter, }; -use super::algebra::{Edges, NodeId, Variable, INTERNER}; -use super::simplify; - /// Ways in which marker evaluation can fail #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] pub enum MarkerWarningKind { @@ -912,12 +914,7 @@ impl MarkerTree { } MarkerTreeKind::Extra(marker) => { return marker - .edge( - marker - .name() - .as_extra() - .is_some_and(|extra| extras.contains(extra)), - ) + .edge(extras.contains(marker.name().extra())) .evaluate_reporter_impl(env, extras, reporter); } } @@ -942,7 +939,7 @@ impl MarkerTree { MarkerTreeKind::True => true, MarkerTreeKind::False => false, MarkerTreeKind::Version(marker) => marker.edges().any(|(range, tree)| { - if marker.key() == MarkerValueVersion::PythonVersion { + if marker.key() == LoweredMarkerValueVersion::PythonVersion { if !python_versions .iter() .any(|version| range.contains(version)) @@ -963,12 +960,7 @@ impl MarkerTree { .children() .any(|(_, tree)| tree.evaluate_extras_and_python_version(extras, python_versions)), MarkerTreeKind::Extra(marker) => marker - .edge( - marker - .name() - .as_extra() - .is_some_and(|extra| extras.contains(extra)), - ) + .edge(extras.contains(marker.name().extra())) .evaluate_extras_and_python_version(extras, python_versions), } } @@ -993,12 +985,7 @@ impl MarkerTree { .children() .any(|(_, tree)| tree.evaluate_extras(extras)), MarkerTreeKind::Extra(marker) => marker - .edge( - marker - .name() - .as_extra() - .is_some_and(|extra| extras.contains(extra)), - ) + .edge(extras.contains(marker.name().extra())) .evaluate_extras(extras), } } @@ -1141,13 +1128,9 @@ impl MarkerTree { } fn simplify_extras_with_impl(self, is_extra: &impl Fn(&ExtraName) -> bool) -> MarkerTree { - MarkerTree(INTERNER.lock().restrict(self.0, &|var| { - match var { - Variable::Extra(name) => name - .as_extra() - .and_then(|name| is_extra(name).then_some(true)), - _ => None, - } + MarkerTree(INTERNER.lock().restrict(self.0, &|var| match var { + Variable::Extra(name) => is_extra(name.extra()).then_some(true), + _ => None, })) } } @@ -1331,13 +1314,13 @@ pub enum MarkerTreeKind<'a> { #[derive(PartialEq, Eq, Clone, Debug)] pub struct VersionMarkerTree<'a> { id: NodeId, - key: MarkerValueVersion, + key: LoweredMarkerValueVersion, map: &'a [(Ranges, NodeId)], } impl VersionMarkerTree<'_> { /// The key for this node. - pub fn key(&self) -> MarkerValueVersion { + pub fn key(&self) -> LoweredMarkerValueVersion { self.key } @@ -1367,13 +1350,13 @@ impl Ord for VersionMarkerTree<'_> { #[derive(PartialEq, Eq, Clone, Debug)] pub struct StringMarkerTree<'a> { id: NodeId, - key: MarkerValueString, + key: LoweredMarkerValueString, map: &'a [(Ranges, NodeId)], } impl StringMarkerTree<'_> { /// The key for this node. - pub fn key(&self) -> MarkerValueString { + pub fn key(&self) -> LoweredMarkerValueString { self.key } @@ -1402,7 +1385,7 @@ impl Ord for StringMarkerTree<'_> { /// A string marker node with the `in` operator, such as `os_name in 'WindowsLinux'`. #[derive(PartialEq, Eq, Clone, Debug)] pub struct InMarkerTree<'a> { - key: MarkerValueString, + key: LoweredMarkerValueString, value: &'a str, high: NodeId, low: NodeId, @@ -1410,7 +1393,7 @@ pub struct InMarkerTree<'a> { impl InMarkerTree<'_> { /// The key (LHS) for this expression. - pub fn key(&self) -> MarkerValueString { + pub fn key(&self) -> LoweredMarkerValueString { self.key } @@ -1452,7 +1435,7 @@ impl Ord for InMarkerTree<'_> { /// A string marker node with inverse of the `in` operator, such as `'nux' in os_name`. #[derive(PartialEq, Eq, Clone, Debug)] pub struct ContainsMarkerTree<'a> { - key: MarkerValueString, + key: LoweredMarkerValueString, value: &'a str, high: NodeId, low: NodeId, @@ -1460,7 +1443,7 @@ pub struct ContainsMarkerTree<'a> { impl ContainsMarkerTree<'_> { /// The key (LHS) for this expression. - pub fn key(&self) -> MarkerValueString { + pub fn key(&self) -> LoweredMarkerValueString { self.key } @@ -1502,14 +1485,14 @@ impl Ord for ContainsMarkerTree<'_> { /// A node representing the existence or absence of a given extra, such as `extra == 'bar'`. #[derive(PartialEq, Eq, Clone, Debug)] pub struct ExtraMarkerTree<'a> { - name: &'a MarkerValueExtra, + name: &'a LoweredMarkerValueExtra, high: NodeId, low: NodeId, } impl ExtraMarkerTree<'_> { /// Returns the name of the extra in this expression. - pub fn name(&self) -> &MarkerValueExtra { + pub fn name(&self) -> &LoweredMarkerValueExtra { self.name } diff --git a/crates/uv-resolver/src/marker.rs b/crates/uv-resolver/src/marker.rs index 842f004b0d40..9e141ef78095 100644 --- a/crates/uv-resolver/src/marker.rs +++ b/crates/uv-resolver/src/marker.rs @@ -1,7 +1,8 @@ -use crate::requires_python::{LowerBound, RequiresPythonRange, UpperBound}; use pubgrub::Range; use uv_pep440::Version; -use uv_pep508::{MarkerTree, MarkerTreeKind, MarkerValueVersion}; +use uv_pep508::{LoweredMarkerValueVersion, MarkerTree, MarkerTreeKind}; + +use crate::requires_python::{LowerBound, RequiresPythonRange, UpperBound}; /// Returns the bounding Python versions that can satisfy the [`MarkerTree`], if it's constrained. pub(crate) fn requires_python(tree: &MarkerTree) -> Option { @@ -9,14 +10,15 @@ pub(crate) fn requires_python(tree: &MarkerTree) -> Option match tree.kind() { MarkerTreeKind::True | MarkerTreeKind::False => {} MarkerTreeKind::Version(marker) => match marker.key() { - MarkerValueVersion::PythonVersion | MarkerValueVersion::PythonFullVersion => { + LoweredMarkerValueVersion::PythonVersion + | LoweredMarkerValueVersion::PythonFullVersion => { for (range, tree) in marker.edges() { if !tree.is_false() { markers.push(range.clone()); } } } - MarkerValueVersion::ImplementationVersion => { + LoweredMarkerValueVersion::ImplementationVersion => { for (_, tree) in marker.edges() { collect_python_markers(&tree, markers); } diff --git a/crates/uv-resolver/src/resolution/output.rs b/crates/uv-resolver/src/resolution/output.rs index 3882359517b8..4544d2de6a27 100644 --- a/crates/uv-resolver/src/resolution/output.rs +++ b/crates/uv-resolver/src/resolution/output.rs @@ -587,7 +587,8 @@ impl ResolverOutput { marker_env: &MarkerEnvironment, ) -> Result> { use uv_pep508::{ - MarkerExpression, MarkerOperator, MarkerTree, MarkerValueString, MarkerValueVersion, + LoweredMarkerValueString, LoweredMarkerValueVersion, MarkerExpression, MarkerOperator, + MarkerTree, }; /// A subset of the possible marker values. @@ -597,8 +598,8 @@ impl ResolverOutput { /// values based on the current marker environment. #[derive(Debug, Eq, Hash, PartialEq)] enum MarkerParam { - Version(MarkerValueVersion), - String(MarkerValueString), + Version(LoweredMarkerValueVersion), + String(LoweredMarkerValueString), } /// Add all marker parameters from the given tree to the given set. @@ -688,14 +689,14 @@ impl ResolverOutput { MarkerParam::Version(value_version) => { let from_env = marker_env.get_version(value_version); MarkerExpression::Version { - key: value_version, + key: value_version.into(), specifier: VersionSpecifier::equals_version(from_env.clone()), } } MarkerParam::String(value_string) => { let from_env = marker_env.get_string(value_string); MarkerExpression::String { - key: value_string, + key: value_string.into(), operator: MarkerOperator::Equal, value: from_env.to_string(), }