Make MarkerTree Copy (#9542)
Some checks are pending
CI / check system | python on macos aarch64 (push) Blocked by required conditions
CI / build binary | macos aarch64 (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / lint (push) Waiting to run
CI / cargo clippy | ubuntu (push) Blocked by required conditions
CI / cargo clippy | windows (push) Blocked by required conditions
CI / cargo dev generate-all (push) Blocked by required conditions
CI / cargo shear (push) Waiting to run
CI / check windows trampoline | i686 (push) Blocked by required conditions
CI / cargo test | ubuntu (push) Blocked by required conditions
CI / cargo test | macos (push) Blocked by required conditions
CI / cargo test | windows (push) Blocked by required conditions
CI / integration test | uv publish (push) Blocked by required conditions
CI / check cache | ubuntu (push) Blocked by required conditions
CI / check cache | macos aarch64 (push) Blocked by required conditions
CI / check system | python on debian (push) Blocked by required conditions
CI / check system | python on fedora (push) Blocked by required conditions
CI / check system | python on ubuntu (push) Blocked by required conditions
CI / check system | python on opensuse (push) Blocked by required conditions
CI / check system | python on rocky linux 8 (push) Blocked by required conditions
CI / check system | python on rocky linux 9 (push) Blocked by required conditions
CI / check system | pypy on ubuntu (push) Blocked by required conditions
CI / check system | pyston (push) Blocked by required conditions
CI / check system | homebrew python on macos aarch64 (push) Blocked by required conditions
CI / check system | python on macos x86_64 (push) Blocked by required conditions
CI / check system | python3.10 on windows (push) Blocked by required conditions
CI / check system | python3.10 on windows x86 (push) Blocked by required conditions
CI / check system | python3.13 on windows (push) Blocked by required conditions
CI / check system | python3.12 via chocolatey (push) Blocked by required conditions
CI / check system | python3.9 via pyenv (push) Blocked by required conditions
CI / check system | python3.13 (push) Blocked by required conditions
CI / check system | conda3.11 on linux (push) Blocked by required conditions
CI / check system | conda3.8 on linux (push) Blocked by required conditions
CI / check system | conda3.11 on macos (push) Blocked by required conditions
CI / check system | conda3.8 on macos (push) Blocked by required conditions
CI / check system | conda3.11 on windows (push) Blocked by required conditions
CI / check windows trampoline | aarch64 (push) Blocked by required conditions
CI / check windows trampoline | x86_64 (push) Blocked by required conditions
CI / test windows trampoline | i686 (push) Blocked by required conditions
CI / test windows trampoline | x86_64 (push) Blocked by required conditions
CI / typos (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / build binary | linux (push) Blocked by required conditions
CI / build binary | macos x86_64 (push) Blocked by required conditions
CI / build binary | windows (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / build binary | freebsd (push) Blocked by required conditions
CI / ecosystem test | prefecthq/prefect (push) Blocked by required conditions
CI / ecosystem test | pallets/flask (push) Blocked by required conditions
CI / integration test | conda on ubuntu (push) Blocked by required conditions
CI / integration test | free-threaded on linux (push) Blocked by required conditions
CI / integration test | free-threaded on windows (push) Blocked by required conditions
CI / integration test | pypy on ubuntu (push) Blocked by required conditions
CI / integration test | pypy on windows (push) Blocked by required conditions
CI / integration test | graalpy on ubuntu (push) Blocked by required conditions
CI / integration test | graalpy on windows (push) Blocked by required conditions
CI / integration test | github actions (push) Blocked by required conditions
CI / integration test | determine publish changes (push) Blocked by required conditions
CI / check system | alpine (push) Blocked by required conditions
CI / check system | conda3.8 on windows (push) Blocked by required conditions
CI / check system | amazonlinux (push) Blocked by required conditions
CI / check system | embedded python3.10 on windows (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions

## Summary

It's just a `usize`. It seems simpler and perhaps even more performant
(?) to make it `Copy`.
This commit is contained in:
Charlie Marsh 2024-11-30 14:07:07 -05:00 committed by GitHub
parent 6bebf79ac3
commit 8126a5ed32
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 171 additions and 189 deletions

View file

@ -75,7 +75,7 @@ impl Constraints {
constraints.iter().cloned().map(move |constraint| {
// Add the extra to the override marker.
let mut joint_marker = MarkerTree::expression(extra_expression.clone());
joint_marker.and(constraint.marker.clone());
joint_marker.and(constraint.marker);
Cow::Owned(Requirement {
marker: joint_marker,
..constraint

View file

@ -63,7 +63,7 @@ impl Overrides {
move |override_requirement| {
// Add the extra to the override marker.
let mut joint_marker = MarkerTree::expression(extra_expression.clone());
joint_marker.and(override_requirement.marker.clone());
joint_marker.and(override_requirement.marker);
Cow::Owned(Requirement {
marker: joint_marker,
..override_requirement.clone()

View file

@ -158,12 +158,12 @@ impl LoweredRequirement {
// Determine the space covered by the sources.
let mut total = MarkerTree::FALSE;
for source in sources.iter() {
total.or(source.marker().clone());
total.or(source.marker());
}
// Determine the space covered by the requirement.
let mut remaining = total.negate();
remaining.and(requirement.marker.clone());
remaining.and(requirement.marker);
LoweredRequirement(Requirement {
marker: remaining,
@ -349,7 +349,7 @@ impl LoweredRequirement {
}
};
marker.and(requirement.marker.clone());
marker.and(requirement.marker);
Ok(Self(Requirement {
name: requirement.name.clone(),
@ -403,12 +403,12 @@ impl LoweredRequirement {
// Determine the space covered by the sources.
let mut total = MarkerTree::FALSE;
for source in source.iter() {
total.or(source.marker().clone());
total.or(source.marker());
}
// Determine the space covered by the requirement.
let mut remaining = total.negate();
remaining.and(requirement.marker.clone());
remaining.and(requirement.marker);
LoweredRequirement(Requirement {
marker: remaining,
@ -501,7 +501,7 @@ impl LoweredRequirement {
}
};
marker.and(requirement.marker.clone());
marker.and(requirement.marker);
Ok(Self(Requirement {
name: requirement.name.clone(),

View file

@ -17,7 +17,7 @@ use crate::{ExtraOperator, MarkerExpression, MarkerOperator, MarkerTree, MarkerT
/// which can be used to create a CNF expression.
///
/// We choose DNF as it is easier to simplify for user-facing output.
pub(crate) fn to_dnf(tree: &MarkerTree) -> Vec<Vec<MarkerExpression>> {
pub(crate) fn to_dnf(tree: MarkerTree) -> Vec<Vec<MarkerExpression>> {
let mut dnf = Vec::new();
collect_dnf(tree, &mut dnf, &mut Vec::new());
simplify(&mut dnf);
@ -31,7 +31,7 @@ pub(crate) fn to_dnf(tree: &MarkerTree) -> Vec<Vec<MarkerExpression>> {
///
/// `path` is the list of marker expressions traversed on the current path.
fn collect_dnf(
tree: &MarkerTree,
tree: MarkerTree,
dnf: &mut Vec<Vec<MarkerExpression>>,
path: &mut Vec<MarkerExpression>,
) {
@ -56,7 +56,7 @@ fn collect_dnf(
});
}
collect_dnf(&tree, dnf, path);
collect_dnf(tree, dnf, path);
path.truncate(current);
continue;
}
@ -68,7 +68,7 @@ fn collect_dnf(
specifier,
});
collect_dnf(&tree, dnf, path);
collect_dnf(tree, dnf, path);
path.pop();
continue;
}
@ -82,7 +82,7 @@ fn collect_dnf(
});
}
collect_dnf(&tree, dnf, path);
collect_dnf(tree, dnf, path);
path.truncate(current);
}
}
@ -100,7 +100,7 @@ fn collect_dnf(
});
}
collect_dnf(&tree, dnf, path);
collect_dnf(tree, dnf, path);
path.truncate(current);
continue;
}
@ -115,7 +115,7 @@ fn collect_dnf(
});
}
collect_dnf(&tree, dnf, path);
collect_dnf(tree, dnf, path);
path.truncate(current);
}
}
@ -135,7 +135,7 @@ fn collect_dnf(
};
path.push(expr);
collect_dnf(&tree, dnf, path);
collect_dnf(tree, dnf, path);
path.pop();
}
}
@ -154,7 +154,7 @@ fn collect_dnf(
};
path.push(expr);
collect_dnf(&tree, dnf, path);
collect_dnf(tree, dnf, path);
path.pop();
}
}
@ -172,7 +172,7 @@ fn collect_dnf(
};
path.push(expr);
collect_dnf(&tree, dnf, path);
collect_dnf(tree, dnf, path);
path.pop();
}
}

View file

@ -611,8 +611,7 @@ impl Display for MarkerExpression {
/// Marker trees are canonical, meaning any two functionally equivalent markers
/// will compare equally. Markers also support efficient polynomial-time operations,
/// such as conjunction and disjunction.
// TODO(ibraheem): decide whether we want to implement `Copy` for marker trees
#[derive(Clone, Eq, Hash, PartialEq)]
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
pub struct MarkerTree(NodeId);
impl Default for MarkerTree {
@ -670,7 +669,7 @@ impl MarkerTree {
/// evaluate to `true` in any environment. However, this method may return false
/// negatives, i.e. it may not be able to detect that a marker is always true for
/// complex expressions.
pub fn is_true(&self) -> bool {
pub fn is_true(self) -> bool {
self.0.is_true()
}
@ -681,13 +680,13 @@ impl MarkerTree {
/// evaluate to `false` in any environment. However, this method may return false
/// negatives, i.e. it may not be able to detect that a marker is unsatisfiable
/// for complex expressions.
pub fn is_false(&self) -> bool {
pub fn is_false(self) -> bool {
self.0.is_false()
}
/// Returns a new marker tree that is the negation of this one.
#[must_use]
pub fn negate(&self) -> MarkerTree {
pub fn negate(self) -> MarkerTree {
MarkerTree(self.0.not())
}
@ -723,7 +722,7 @@ impl MarkerTree {
/// never both evaluate to `true` in a given environment. However, this method may return
/// false negatives, i.e. it may not be able to detect that two markers are disjoint for
/// complex expressions.
pub fn is_disjoint(&self, other: &MarkerTree) -> bool {
pub fn is_disjoint(self, other: MarkerTree) -> bool {
INTERNER.lock().is_disjoint(self.0, other.0)
}
@ -733,12 +732,12 @@ impl MarkerTree {
/// If the marker is `false`, the marker is represented as the normalized expression, `python_version < '0'`.
///
/// The returned type implements [`Display`] and [`serde::Serialize`].
pub fn contents(&self) -> Option<MarkerTreeContents> {
pub fn contents(self) -> Option<MarkerTreeContents> {
if self.is_true() {
return None;
}
Some(MarkerTreeContents(self.clone()))
Some(MarkerTreeContents(self))
}
/// Returns a simplified string representation of this marker, if it contains at least one
@ -746,7 +745,7 @@ impl MarkerTree {
///
/// If the marker is `true`, this method will return `None`.
/// If the marker is `false`, the marker is represented as the normalized expression, `python_version < '0'`.
pub fn try_to_string(&self) -> Option<String> {
pub fn try_to_string(self) -> Option<String> {
self.contents().map(|contents| contents.to_string())
}
@ -818,12 +817,12 @@ impl MarkerTree {
}
/// Returns a simplified DNF expression for this marker tree.
pub fn to_dnf(&self) -> Vec<Vec<MarkerExpression>> {
pub fn to_dnf(self) -> Vec<Vec<MarkerExpression>> {
simplify::to_dnf(self)
}
/// Does this marker apply in the given environment?
pub fn evaluate(&self, env: &MarkerEnvironment, extras: &[ExtraName]) -> bool {
pub fn evaluate(self, env: &MarkerEnvironment, extras: &[ExtraName]) -> bool {
self.evaluate_reporter_impl(env, extras, &mut TracingReporter)
}
@ -835,7 +834,7 @@ impl MarkerTree {
/// independent marker evaluation. In practice, this means only the extras
/// are evaluated when an environment is not provided.
pub fn evaluate_optional_environment(
&self,
self,
env: Option<&MarkerEnvironment>,
extras: &[ExtraName],
) -> bool {
@ -848,7 +847,7 @@ impl MarkerTree {
/// Same as [`Self::evaluate`], but instead of using logging to warn, you can pass your own
/// handler for warnings
pub fn evaluate_reporter(
&self,
self,
env: &MarkerEnvironment,
extras: &[ExtraName],
reporter: &mut impl Reporter,
@ -857,7 +856,7 @@ impl MarkerTree {
}
fn evaluate_reporter_impl(
&self,
self,
env: &MarkerEnvironment,
extras: &[ExtraName],
reporter: &mut impl Reporter,
@ -924,7 +923,7 @@ impl MarkerTree {
/// Checks if the requirement should be activated with the given set of active extras without evaluating
/// the remaining environment markers, i.e. if there is potentially an environment that could activate this
/// requirement.
pub fn evaluate_extras(&self, extras: &[ExtraName]) -> bool {
pub fn evaluate_extras(self, extras: &[ExtraName]) -> bool {
match self.kind() {
MarkerTreeKind::True => true,
MarkerTreeKind::False => false,
@ -950,7 +949,7 @@ impl MarkerTree {
///
/// ASSUMPTION: There is one `extra = "..."`, and it's either the only marker or part of the
/// main conjunction.
pub fn top_level_extra(&self) -> Option<MarkerExpression> {
pub fn top_level_extra(self) -> Option<MarkerExpression> {
let mut extra_expression = None;
for conjunction in self.to_dnf() {
let found = conjunction.iter().find(|expression| {
@ -983,7 +982,7 @@ impl MarkerTree {
///
/// ASSUMPTION: There is one `extra = "..."`, and it's either the only marker or part of the
/// main conjunction.
pub fn top_level_extra_name(&self) -> Option<ExtraName> {
pub fn top_level_extra_name(self) -> Option<ExtraName> {
let extra_expression = self.top_level_extra()?;
match extra_expression {
@ -1122,7 +1121,7 @@ impl MarkerTree {
MarkerTreeDebugRaw { marker: self }
}
fn fmt_graph(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
fn fmt_graph(self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
match self.kind() {
MarkerTreeKind::True => return write!(f, "true"),
MarkerTreeKind::False => return write!(f, "false"),
@ -2044,9 +2043,7 @@ mod test {
// Given `os_name == "nt" and extra == "test"`, don't simplify.
let markers = MarkerTree::from_str(r#"os_name == "nt" and extra == "test""#).unwrap();
let simplified = markers
.clone()
.simplify_extras(&[ExtraName::from_str("dev").unwrap()]);
let simplified = markers.simplify_extras(&[ExtraName::from_str("dev").unwrap()]);
assert_eq!(simplified, markers);
// Given `os_name == "nt" and (python_version == "3.7" or extra == "dev")`, simplify to
@ -2703,8 +2700,8 @@ mod test {
fn is_disjoint_commutative() {
let m1 = m("extra == 'Linux' and extra != 'OSX'");
let m2 = m("extra == 'Linux'");
assert!(!m2.is_disjoint(&m1));
assert!(!m1.is_disjoint(&m2));
assert!(!m2.is_disjoint(m1));
assert!(!m1.is_disjoint(m2));
}
#[test]
@ -2836,7 +2833,7 @@ mod test {
fn is_disjoint(left: impl AsRef<str>, right: impl AsRef<str>) -> bool {
let (left, right) = (m(left.as_ref()), m(right.as_ref()));
left.is_disjoint(&right) && right.is_disjoint(&left)
left.is_disjoint(right) && right.is_disjoint(left)
}
fn implies(antecedent: &str, consequent: &str) -> bool {

View file

@ -96,7 +96,7 @@ impl RequiresTxt {
// Add the markers and extra, if necessary.
requires_dist.push(Requirement {
marker: current_marker.clone(),
marker: current_marker,
..requirement
});
}

View file

@ -119,11 +119,11 @@ impl<'a, Context: BuildContext> SourceTreeResolver<'a, Context> {
req.extras
.iter()
.cloned()
.map(|extra| (extra, req.marker.clone().simplify_extras(&extras)))
.map(|extra| (extra, req.marker.simplify_extras(&extras)))
})
.collect();
while let Some((extra, marker)) = queue.pop_front() {
if !seen.insert((extra.clone(), marker.clone())) {
if !seen.insert((extra.clone(), marker)) {
continue;
}
@ -131,8 +131,8 @@ impl<'a, Context: BuildContext> SourceTreeResolver<'a, Context> {
for requirement in &dependencies {
if requirement.marker.top_level_extra_name().as_ref() == Some(&extra) {
let requirement = {
let mut marker = marker.clone();
marker.and(requirement.marker.clone());
let mut marker = marker;
marker.and(requirement.marker);
Requirement {
name: requirement.name.clone(),
extras: requirement.extras.clone(),
@ -148,7 +148,7 @@ impl<'a, Context: BuildContext> SourceTreeResolver<'a, Context> {
.extras
.iter()
.cloned()
.map(|extra| (extra, requirement.marker.clone())),
.map(|extra| (extra, requirement.marker)),
);
} else {
// Add the requirements for that extra.

View file

@ -43,34 +43,34 @@ pub(crate) fn marker_reachability<T>(
fork_markers
.iter()
.fold(UniversalMarker::FALSE, |mut acc, marker| {
acc.or(marker.clone());
acc.or(*marker);
acc
})
};
for root_index in &queue {
reachability.insert(*root_index, root_markers.clone());
reachability.insert(*root_index, root_markers);
}
// Propagate all markers through the graph, so that the eventual marker for each node is the
// union of the markers of each path we can reach the node by.
while let Some(parent_index) = queue.pop() {
let marker = reachability[&parent_index].clone();
let marker = reachability[&parent_index];
for child_edge in graph.edges_directed(parent_index, Direction::Outgoing) {
// The marker for all paths to the child through the parent.
let mut child_marker = child_edge.weight().clone();
child_marker.and(marker.clone());
let mut child_marker = *child_edge.weight();
child_marker.and(marker);
match reachability.entry(child_edge.target()) {
Entry::Occupied(mut existing) => {
// If the marker is a subset of the existing marker (A ⊆ B exactly if
// A B = A), updating the child wouldn't change child's marker.
child_marker.or(existing.get().clone());
child_marker.or(*existing.get());
if &child_marker != existing.get() {
existing.insert(child_marker);
queue.push(child_edge.target());
}
}
Entry::Vacant(vacant) => {
vacant.insert(child_marker.clone());
vacant.insert(child_marker);
queue.push(child_edge.target());
}
}

View file

@ -148,7 +148,7 @@ impl Lock {
.fork_markers
.iter()
.filter(|fork_markers| !fork_markers.is_disjoint(&dist.marker))
.cloned()
.copied()
.collect()
} else {
vec![]
@ -163,7 +163,7 @@ impl Lock {
else {
continue;
};
let marker = edge.weight().clone();
let marker = *edge.weight();
package.add_dependency(&requires_python, dependency_dist, marker, root)?;
}
@ -196,7 +196,7 @@ impl Lock {
else {
continue;
};
let marker = edge.weight().clone();
let marker = *edge.weight();
package.add_optional_dependency(
&requires_python,
extra.clone(),
@ -221,7 +221,7 @@ impl Lock {
else {
continue;
};
let marker = edge.weight().clone();
let marker = *edge.weight();
package.add_group_dependency(
&requires_python,
group.clone(),
@ -588,7 +588,7 @@ impl Lock {
pub fn simplified_supported_environments(&self) -> Vec<MarkerTree> {
self.supported_environments()
.iter()
.cloned()
.copied()
.map(|marker| self.simplify_environment(marker))
.collect()
}
@ -623,9 +623,9 @@ impl Lock {
// include conflicting marker info. In which case, we should serialize
// the entire `UniversalMarker` (taking care to still make the PEP 508
// simplified).
SimplifiedMarkerTree::new(&self.requires_python, marker.pep508().clone())
SimplifiedMarkerTree::new(&self.requires_python, marker.pep508())
})
.filter_map(|marker| marker.try_to_string()),
.filter_map(super::requires_python::SimplifiedMarkerTree::try_to_string),
);
doc.insert("resolution-markers", value(fork_markers));
}
@ -634,8 +634,9 @@ impl Lock {
let supported_environments = each_element_on_its_line_array(
self.supported_environments
.iter()
.map(|marker| SimplifiedMarkerTree::new(&self.requires_python, marker.clone()))
.filter_map(|marker| marker.try_to_string()),
.copied()
.map(|marker| SimplifiedMarkerTree::new(&self.requires_python, marker))
.filter_map(super::requires_python::SimplifiedMarkerTree::try_to_string),
);
doc.insert("supported-markers", value(supported_environments));
}
@ -1974,10 +1975,8 @@ impl Package {
// include conflicting marker info. In which case, we should serialize
// the entire `UniversalMarker` (taking care to still make the PEP 508
// simplified).
.map(|marker| {
SimplifiedMarkerTree::new(requires_python, marker.pep508().clone())
})
.filter_map(|marker| marker.try_to_string()),
.map(|marker| SimplifiedMarkerTree::new(requires_python, marker.pep508()))
.filter_map(super::requires_python::SimplifiedMarkerTree::try_to_string),
);
table.insert("resolution-markers", value(wheels));
}
@ -3535,7 +3534,7 @@ impl Dependency {
complexified_marker: UniversalMarker,
) -> Dependency {
let simplified_marker =
SimplifiedMarkerTree::new(requires_python, complexified_marker.pep508().clone());
SimplifiedMarkerTree::new(requires_python, complexified_marker.pep508());
Dependency {
package_id,
extra,
@ -3624,7 +3623,7 @@ impl DependencyWire {
requires_python: &RequiresPython,
unambiguous_package_ids: &FxHashMap<PackageName, PackageId>,
) -> Result<Dependency, LockError> {
let complexified_marker = self.marker.clone().into_marker(requires_python);
let complexified_marker = self.marker.into_marker(requires_python);
Ok(Dependency {
package_id: self.package_id.unwire(unambiguous_package_ids)?,
extra: self.extra,

View file

@ -114,7 +114,7 @@ impl<'lock> RequirementsTxtExport<'lock> {
root,
dep_index,
UniversalMarker::new(
dep.simplified_marker.as_simplified_marker_tree().clone(),
dep.simplified_marker.as_simplified_marker_tree(),
// OK because we've verified above that we do not have any
// conflicting extras/groups.
//
@ -172,7 +172,7 @@ impl<'lock> RequirementsTxtExport<'lock> {
index,
dep_index,
UniversalMarker::new(
dep.simplified_marker.as_simplified_marker_tree().clone(),
dep.simplified_marker.as_simplified_marker_tree(),
// See note above for other `UniversalMarker::new` for
// why this is OK.
MarkerTree::TRUE,
@ -211,11 +211,7 @@ impl<'lock> RequirementsTxtExport<'lock> {
package,
// As above, we've verified that there are no conflicting extras/groups
// specified, so it's safe to completely ignore the conflict marker.
marker: reachability
.remove(&index)
.unwrap_or_default()
.pep508()
.clone(),
marker: reachability.remove(&index).unwrap_or_default().pep508(),
})
.collect::<Vec<_>>();

View file

@ -257,7 +257,7 @@ impl<'env> InstallTarget<'env> {
//
// FIXME: Make the above true. We aren't actually checking
// the conflict marker yet.
Edge::Dev(group.clone(), dep.complexified_marker.pep508().clone()),
Edge::Dev(group.clone(), dep.complexified_marker.pep508()),
);
// Push its dependencies on the queue.
@ -329,11 +329,7 @@ impl<'env> InstallTarget<'env> {
};
// Add the edge.
petgraph.add_edge(
root,
index,
Edge::Dev(group.clone(), dependency.marker.clone()),
);
petgraph.add_edge(root, index, Edge::Dev(group.clone(), dependency.marker));
// Push its dependencies on the queue.
if seen.insert((&dist.id, None)) {
@ -392,9 +388,9 @@ impl<'env> InstallTarget<'env> {
index,
dep_index,
if let Some(extra) = extra {
Edge::Optional(extra.clone(), dep.complexified_marker.pep508().clone())
Edge::Optional(extra.clone(), dep.complexified_marker.pep508())
} else {
Edge::Prod(dep.complexified_marker.pep508().clone())
Edge::Prod(dep.complexified_marker.pep508())
},
);

View file

@ -5,8 +5,8 @@ use uv_pep508::{CanonicalMarkerValueVersion, 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<RequiresPythonRange> {
fn collect_python_markers(tree: &MarkerTree, markers: &mut Vec<Range<Version>>) {
pub(crate) fn requires_python(tree: MarkerTree) -> Option<RequiresPythonRange> {
fn collect_python_markers(tree: MarkerTree, markers: &mut Vec<Range<Version>>) {
match tree.kind() {
MarkerTreeKind::True | MarkerTreeKind::False => {}
MarkerTreeKind::Version(marker) => match marker.key() {
@ -19,28 +19,28 @@ pub(crate) fn requires_python(tree: &MarkerTree) -> Option<RequiresPythonRange>
}
CanonicalMarkerValueVersion::ImplementationVersion => {
for (_, tree) in marker.edges() {
collect_python_markers(&tree, markers);
collect_python_markers(tree, markers);
}
}
},
MarkerTreeKind::String(marker) => {
for (_, tree) in marker.children() {
collect_python_markers(&tree, markers);
collect_python_markers(tree, markers);
}
}
MarkerTreeKind::In(marker) => {
for (_, tree) in marker.children() {
collect_python_markers(&tree, markers);
collect_python_markers(tree, markers);
}
}
MarkerTreeKind::Contains(marker) => {
for (_, tree) in marker.children() {
collect_python_markers(&tree, markers);
collect_python_markers(tree, markers);
}
}
MarkerTreeKind::Extra(marker) => {
for (_, tree) in marker.children() {
collect_python_markers(&tree, markers);
collect_python_markers(tree, markers);
}
}
}

View file

@ -156,7 +156,7 @@ impl PubGrubRequirement {
package: PubGrubPackage::from_package(
requirement.name.clone(),
extra,
requirement.marker.clone(),
requirement.marker,
),
version: Ranges::full(),
url: Some(VerbatimParsedUrl {
@ -175,7 +175,7 @@ impl PubGrubRequirement {
package: PubGrubPackage::from_package(
requirement.name.clone(),
extra,
requirement.marker.clone(),
requirement.marker,
),
url: None,
version: Ranges::from(specifier.clone()),

View file

@ -152,15 +152,15 @@ impl PubGrubPackage {
/// Returns the marker expression associated with this PubGrub package, if
/// it has one.
pub(crate) fn marker(&self) -> Option<&MarkerTree> {
pub(crate) fn marker(&self) -> Option<MarkerTree> {
match &**self {
// A root can never be a dependency of another package, and a `Python` pubgrub
// package is never returned by `get_dependencies`. So these cases never occur.
PubGrubPackageInner::Root(_) | PubGrubPackageInner::Python(_) => None,
PubGrubPackageInner::Package { marker, .. }
| PubGrubPackageInner::Extra { marker, .. }
| PubGrubPackageInner::Dev { marker, .. } => Some(marker),
PubGrubPackageInner::Marker { marker, .. } => Some(marker),
| PubGrubPackageInner::Dev { marker, .. } => Some(*marker),
PubGrubPackageInner::Marker { marker, .. } => Some(*marker),
}
}
@ -253,7 +253,7 @@ impl PubGrubPackage {
| PubGrubPackageInner::Extra { ref mut marker, .. }
| PubGrubPackageInner::Dev { ref mut marker, .. }
| PubGrubPackageInner::Marker { ref mut marker, .. } => {
*marker = python_requirement.simplify_markers(marker.clone());
*marker = python_requirement.simplify_markers(*marker);
}
}
}

View file

@ -542,7 +542,7 @@ impl From<RequiresPythonRange> for Range<Version> {
/// setting can be assumed. In order to get a "normal" marker out of
/// a simplified marker, one must re-contextualize it by adding the
/// `requires-python` constraint back to the marker.
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord, serde::Deserialize)]
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, PartialOrd, Ord, serde::Deserialize)]
pub(crate) struct SimplifiedMarkerTree(MarkerTree);
impl SimplifiedMarkerTree {
@ -565,13 +565,13 @@ impl SimplifiedMarkerTree {
///
/// This only returns `None` when the underlying marker is always true,
/// i.e., it matches all possible marker environments.
pub(crate) fn try_to_string(&self) -> Option<String> {
pub(crate) fn try_to_string(self) -> Option<String> {
self.0.try_to_string()
}
/// Returns the underlying marker tree without re-complexifying them.
pub(crate) fn as_simplified_marker_tree(&self) -> &MarkerTree {
&self.0
pub(crate) fn as_simplified_marker_tree(self) -> MarkerTree {
self.0
}
}

View file

@ -332,9 +332,7 @@ type RequirementsTxtGraph<'dist> = Graph<RequirementsTxtDist<'dist>, (), Directe
/// We also remove the root node, to simplify the graph structure.
fn combine_extras<'dist>(graph: &IntermediatePetGraph<'dist>) -> RequirementsTxtGraph<'dist> {
/// Return the key for a node.
fn version_marker<'dist>(
dist: &'dist RequirementsTxtDist,
) -> (&'dist PackageName, &'dist MarkerTree) {
fn version_marker<'dist>(dist: &'dist RequirementsTxtDist) -> (&'dist PackageName, MarkerTree) {
(dist.name(), dist.markers)
}

View file

@ -147,12 +147,12 @@ impl ResolverOutput {
// Add every edge to the graph, propagating the marker for the current fork, if
// necessary.
for edge in &resolution.edges {
if !seen.insert((edge, marker.clone())) {
if !seen.insert((edge, marker)) {
// Insert each node only once.
continue;
}
Self::add_edge(&mut graph, &mut inverse, root_index, edge, marker.clone());
Self::add_edge(&mut graph, &mut inverse, root_index, edge, marker);
}
}
@ -603,32 +603,32 @@ impl ResolverOutput {
}
/// Add all marker parameters from the given tree to the given set.
fn add_marker_params_from_tree(marker_tree: &MarkerTree, set: &mut IndexSet<MarkerParam>) {
fn add_marker_params_from_tree(marker_tree: MarkerTree, set: &mut IndexSet<MarkerParam>) {
match marker_tree.kind() {
MarkerTreeKind::True => {}
MarkerTreeKind::False => {}
MarkerTreeKind::Version(marker) => {
set.insert(MarkerParam::Version(marker.key()));
for (_, tree) in marker.edges() {
add_marker_params_from_tree(&tree, set);
add_marker_params_from_tree(tree, set);
}
}
MarkerTreeKind::String(marker) => {
set.insert(MarkerParam::String(marker.key()));
for (_, tree) in marker.children() {
add_marker_params_from_tree(&tree, set);
add_marker_params_from_tree(tree, set);
}
}
MarkerTreeKind::In(marker) => {
set.insert(MarkerParam::String(marker.key()));
for (_, tree) in marker.children() {
add_marker_params_from_tree(&tree, set);
add_marker_params_from_tree(tree, set);
}
}
MarkerTreeKind::Contains(marker) => {
set.insert(MarkerParam::String(marker.key()));
for (_, tree) in marker.children() {
add_marker_params_from_tree(&tree, set);
add_marker_params_from_tree(tree, set);
}
}
// We specifically don't care about these for the
@ -638,7 +638,7 @@ impl ResolverOutput {
// interested in which markers are used.
MarkerTreeKind::Extra(marker) => {
for (_, tree) in marker.children() {
add_marker_params_from_tree(&tree, set);
add_marker_params_from_tree(tree, set);
}
}
}
@ -669,7 +669,7 @@ impl ResolverOutput {
.constraints
.apply(self.overrides.apply(archive.metadata.requires_dist.iter()))
{
add_marker_params_from_tree(&req.marker, &mut seen_marker_values);
add_marker_params_from_tree(req.marker, &mut seen_marker_values);
}
}
@ -678,7 +678,7 @@ impl ResolverOutput {
.constraints
.apply(self.overrides.apply(self.requirements.iter()))
{
add_marker_params_from_tree(&direct_req.marker, &mut seen_marker_values);
add_marker_params_from_tree(direct_req.marker, &mut seen_marker_values);
}
// Generate the final marker expression as a conjunction of
@ -740,8 +740,8 @@ impl ResolverOutput {
name: name.clone(),
version1: (*version1).clone(),
version2: (*version2).clone(),
marker1: (*marker1).clone(),
marker2: (*marker2).clone(),
marker1: *(*marker1),
marker2: *(*marker2),
});
}
}
@ -841,7 +841,7 @@ impl From<ResolverOutput> for uv_distribution_types::Resolution {
// above that we aren't in universal mode. If we aren't in
// universal mode, then there can be no conflicts since
// conflicts imply forks and forks imply universal mode.
let marker = graph[edge].pep508().clone();
let marker = graph[edge].pep508();
match (&graph[source], &graph[target]) {
(ResolutionGraphNode::Root, ResolutionGraphNode::Dist(target_dist)) => {

View file

@ -21,7 +21,7 @@ pub(crate) struct RequirementsTxtDist<'dist> {
pub(crate) dist: &'dist ResolvedDist,
pub(crate) version: &'dist Version,
pub(crate) hashes: &'dist [HashDigest],
pub(crate) markers: &'dist MarkerTree,
pub(crate) markers: MarkerTree,
pub(crate) extras: Vec<ExtraName>,
}
@ -94,7 +94,7 @@ impl<'dist> RequirementsTxtDist<'dist> {
};
if let Some(given) = given {
return if let Some(markers) =
SimplifiedMarkerTree::new(requires_python, self.markers.clone())
SimplifiedMarkerTree::new(requires_python, self.markers)
.try_to_string()
.filter(|_| include_markers)
{
@ -107,7 +107,7 @@ impl<'dist> RequirementsTxtDist<'dist> {
}
if self.extras.is_empty() {
if let Some(markers) = SimplifiedMarkerTree::new(requires_python, self.markers.clone())
if let Some(markers) = SimplifiedMarkerTree::new(requires_python, self.markers)
.try_to_string()
.filter(|_| include_markers)
{
@ -119,7 +119,7 @@ impl<'dist> RequirementsTxtDist<'dist> {
let mut extras = self.extras.clone();
extras.sort_unstable();
extras.dedup();
if let Some(markers) = SimplifiedMarkerTree::new(requires_python, self.markers.clone())
if let Some(markers) = SimplifiedMarkerTree::new(requires_python, self.markers)
.try_to_string()
.filter(|_| include_markers)
{

View file

@ -168,7 +168,7 @@ impl ResolverEnvironment {
/// Returns `false` only when this environment is a fork and it is disjoint
/// with the given marker.
pub(crate) fn included_by_marker(&self, marker: &MarkerTree) -> bool {
pub(crate) fn included_by_marker(&self, marker: MarkerTree) -> bool {
match self.kind {
Kind::Specific { .. } => true,
Kind::Universal { ref markers, .. } => !markers.is_disjoint(marker),
@ -188,7 +188,7 @@ impl ResolverEnvironment {
/// resolver environment's marker, if it's constrained.
pub(crate) fn requires_python(&self) -> Option<RequiresPythonRange> {
let Kind::Universal {
markers: ref pep508_marker,
markers: pep508_marker,
..
} = self.kind
else {
@ -219,7 +219,7 @@ impl ResolverEnvironment {
ref include,
ref exclude,
} => {
let mut markers = lhs.clone();
let mut markers = *lhs;
markers.and(rhs);
let kind = Kind::Universal {
initial_forks: Arc::clone(initial_forks),
@ -285,7 +285,7 @@ impl ResolverEnvironment {
}
let kind = Kind::Universal {
initial_forks: Arc::clone(initial_forks),
markers: markers.clone(),
markers: *markers,
include: Arc::new(include),
exclude: Arc::new(exclude),
};
@ -320,7 +320,7 @@ impl ResolverEnvironment {
.rev()
.map(|initial_fork| {
init.clone()
.with_env(self.narrow_environment(initial_fork.clone()))
.with_env(self.narrow_environment(*initial_fork))
})
.collect()
}
@ -398,7 +398,7 @@ impl ResolverEnvironment {
conflict_marker.and(exclude_extra_marker);
}
}
Some(UniversalMarker::new(markers.clone(), conflict_marker))
Some(UniversalMarker::new(*markers, conflict_marker))
}
}
}
@ -445,7 +445,7 @@ impl<'d> ForkingPossibility<'d> {
env: &ResolverEnvironment,
dep: &'d PubGrubDependency,
) -> ForkingPossibility<'d> {
let marker = dep.package.marker().unwrap_or(&MarkerTree::TRUE);
let marker = dep.package.marker().unwrap_or(MarkerTree::TRUE);
if !env.included_by_marker(marker) {
ForkingPossibility::DependencyAlwaysExcluded
} else if marker.is_true() {
@ -453,7 +453,7 @@ impl<'d> ForkingPossibility<'d> {
} else {
let forker = Forker {
package: &dep.package,
marker: marker.clone(),
marker,
};
ForkingPossibility::Possible(forker)
}
@ -479,7 +479,7 @@ impl<'d> Forker<'d> {
&self,
env: &ResolverEnvironment,
) -> Option<(Forker<'d>, Vec<ResolverEnvironment>)> {
if !env.included_by_marker(&self.marker) {
if !env.included_by_marker(self.marker) {
return None;
}
@ -494,7 +494,7 @@ impl<'d> Forker<'d> {
let mut envs = vec![];
{
let not_marker = self.marker.negate();
if !env_marker.is_disjoint(&not_marker) {
if !env_marker.is_disjoint(not_marker) {
envs.push(env.narrow_environment(not_marker));
}
}
@ -502,9 +502,9 @@ impl<'d> Forker<'d> {
// Changing the order of forks can change the output in some
// ways. While it's probably fine, we try to avoid changing the
// output.
envs.push(env.narrow_environment(self.marker.clone()));
envs.push(env.narrow_environment(self.marker));
let mut remaining_marker = self.marker.clone();
let mut remaining_marker = self.marker;
remaining_marker.and(env_marker.negate());
let remaining_forker = Forker {
package: self.package,
@ -516,7 +516,7 @@ impl<'d> Forker<'d> {
/// Returns true if the dependency represented by this forker may be
/// included in the given resolver environment.
pub(crate) fn included(&self, env: &ResolverEnvironment) -> bool {
let marker = self.package.marker().unwrap_or(&MarkerTree::TRUE);
let marker = self.package.marker().unwrap_or(MarkerTree::TRUE);
env.included_by_marker(marker)
}
}

View file

@ -29,7 +29,7 @@ impl<T> ForkMap<T> {
pub(crate) fn add(&mut self, requirement: &Requirement, value: T) {
let entry = Entry {
value,
marker: requirement.marker.clone(),
marker: requirement.marker,
};
self.0
@ -60,7 +60,7 @@ impl<T> ForkMap<T> {
};
values
.iter()
.filter(|entry| env.included_by_marker(&entry.marker))
.filter(|entry| env.included_by_marker(entry.marker))
.map(|entry| &entry.value)
.collect()
}

View file

@ -1475,7 +1475,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
package: PubGrubPackage::from(PubGrubPackageInner::Dev {
name: name.clone(),
dev: group.clone(),
marker: marker.clone(),
marker: *marker,
}),
version: Range::singleton(version.clone()),
url: None,
@ -1490,7 +1490,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
// Add a dependency on both the marker and base package.
PubGrubPackageInner::Marker { name, marker } => {
return Ok(Dependencies::Unforkable(
[MarkerTree::TRUE, marker.clone()]
[MarkerTree::TRUE, *marker]
.into_iter()
.map(move |marker| PubGrubDependency {
package: PubGrubPackage::from(PubGrubPackageInner::Package {
@ -1524,7 +1524,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
name: name.clone(),
extra: extra.cloned(),
dev: None,
marker: marker.clone(),
marker: *marker,
}),
version: Range::singleton(version.clone()),
url: None,
@ -1549,7 +1549,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
name: name.clone(),
extra: None,
dev: dev.cloned(),
marker: marker.clone(),
marker: *marker,
}),
version: Range::singleton(version.clone()),
url: None,
@ -1607,15 +1607,10 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
let mut queue: VecDeque<_> = requirements
.iter()
.filter(|req| name == Some(&req.name))
.flat_map(|req| {
req.extras
.iter()
.cloned()
.map(|extra| (extra, req.marker.clone()))
})
.flat_map(|req| req.extras.iter().cloned().map(|extra| (extra, req.marker)))
.collect();
while let Some((extra, marker)) = queue.pop_front() {
if !seen.insert((extra.clone(), marker.clone())) {
if !seen.insert((extra.clone(), marker)) {
continue;
}
for requirement in
@ -1623,12 +1618,12 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
{
let requirement = match requirement {
Cow::Owned(mut requirement) => {
requirement.marker.and(marker.clone());
requirement.marker.and(marker);
requirement
}
Cow::Borrowed(requirement) => {
let mut marker = marker.clone();
marker.and(requirement.marker.clone());
let mut marker = marker;
marker.and(requirement.marker);
Requirement {
name: requirement.name.clone(),
extras: requirement.extras.clone(),
@ -1645,7 +1640,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
.extras
.iter()
.cloned()
.map(|extra| (extra, requirement.marker.clone())),
.map(|extra| (extra, requirement.marker)),
);
} else {
// Add the requirements for that extra.
@ -1678,7 +1673,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
let python_marker = python_requirement.to_marker_tree();
// If the requirement would not be selected with any Python version
// supported by the root, skip it.
if python_marker.is_disjoint(&requirement.marker) {
if python_marker.is_disjoint(requirement.marker) {
trace!(
"skipping {requirement} because of Requires-Python: {requires_python}",
requires_python = python_requirement.target(),
@ -1688,7 +1683,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
// If we're in a fork in universal mode, ignore any dependency that isn't part of
// this fork (but will be part of another fork).
if !env.included_by_marker(&requirement.marker) {
if !env.included_by_marker(requirement.marker) {
trace!("skipping {requirement} because of {env}");
return None;
}
@ -1737,8 +1732,8 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
if requirement.marker.is_true() {
Cow::Borrowed(constraint)
} else {
let mut marker = constraint.marker.clone();
marker.and(requirement.marker.clone());
let mut marker = constraint.marker;
marker.and(requirement.marker);
if marker.is_false() {
trace!(
@ -1761,8 +1756,8 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
let requires_python = python_requirement.target();
let python_marker = python_requirement.to_marker_tree();
let mut marker = constraint.marker.clone();
marker.and(requirement.marker.clone());
let mut marker = constraint.marker;
marker.and(requirement.marker);
if marker.is_false() {
trace!(
@ -1776,7 +1771,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
// Additionally, if the requirement is `requests ; sys_platform == 'darwin'`
// and the constraint is `requests ; python_version == '3.6'`, the
// constraint should only apply when _both_ markers are true.
if python_marker.is_disjoint(&marker) {
if python_marker.is_disjoint(marker) {
trace!(
"skipping constraint {requirement} because of Requires-Python: {requires_python}"
);
@ -1798,7 +1793,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
// If we're in a fork in universal mode, ignore any dependency that isn't part of
// this fork (but will be part of another fork).
if !env.included_by_marker(&constraint.marker) {
if !env.included_by_marker(constraint.marker) {
trace!("skipping {constraint} because of {env}");
return None;
}
@ -2524,7 +2519,7 @@ impl ForkState {
to_index: to_index.cloned(),
to_extra: None,
to_dev: None,
marker: dependency_marker.clone(),
marker: *dependency_marker,
};
edges.insert(edge);
}
@ -2555,7 +2550,7 @@ impl ForkState {
to_index: to_index.cloned(),
to_extra: Some(dependency_extra.clone()),
to_dev: None,
marker: dependency_marker.clone(),
marker: *dependency_marker,
};
edges.insert(edge);
}
@ -2586,7 +2581,7 @@ impl ForkState {
to_index: to_index.cloned(),
to_extra: None,
to_dev: Some(dependency_dev.clone()),
marker: dependency_marker.clone(),
marker: *dependency_marker,
};
edges.insert(edge);
}
@ -2681,7 +2676,7 @@ pub(crate) struct ResolutionDependencyEdge {
impl ResolutionDependencyEdge {
pub(crate) fn universal_marker(&self) -> UniversalMarker {
// FIXME: Account for extras and groups here.
UniversalMarker::new(self.marker.clone(), MarkerTree::TRUE)
UniversalMarker::new(self.marker, MarkerTree::TRUE)
}
}
@ -2919,9 +2914,9 @@ impl Forks {
.is_some_and(|bound| python_requirement.raises(&bound))
{
let dep = deps.pop().unwrap();
let markers = dep.package.marker().cloned().unwrap_or(MarkerTree::TRUE);
let markers = dep.package.marker().unwrap_or(MarkerTree::TRUE);
for fork in &mut forks {
if fork.env.included_by_marker(&markers) {
if fork.env.included_by_marker(markers) {
fork.add_dependency(dep.clone());
}
}
@ -2968,7 +2963,7 @@ impl Forks {
}
// Filter out any forks we created that are disjoint with our
// Python requirement.
if new_fork.env.included_by_marker(&python_marker) {
if new_fork.env.included_by_marker(python_marker) {
new.push(new_fork);
}
}

View file

@ -13,7 +13,7 @@ use uv_pep508::{MarkerEnvironment, MarkerTree};
///
/// A universal marker evaluates to true only when *both* its PEP 508 marker
/// and its conflict marker evaluate to true.
#[derive(Debug, Default, Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
#[derive(Debug, Default, Copy, Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct UniversalMarker {
pep508_marker: MarkerTree,
conflict_marker: MarkerTree,
@ -70,16 +70,16 @@ impl UniversalMarker {
///
/// Two universal markers are disjoint when it is impossible for them both
/// to evaluate to `true` simultaneously.
pub(crate) fn is_disjoint(&self, other: &UniversalMarker) -> bool {
self.pep508_marker.is_disjoint(&other.pep508_marker)
|| self.conflict_marker.is_disjoint(&other.conflict_marker)
pub(crate) fn is_disjoint(self, other: &UniversalMarker) -> bool {
self.pep508_marker.is_disjoint(other.pep508_marker)
|| self.conflict_marker.is_disjoint(other.conflict_marker)
}
/// Returns true if this universal marker is satisfied by the given
/// marker environment and list of activated extras.
///
/// FIXME: This also needs to accept a list of groups.
pub(crate) fn evaluate(&self, env: &MarkerEnvironment, extras: &[ExtraName]) -> bool {
pub(crate) fn evaluate(self, env: &MarkerEnvironment, extras: &[ExtraName]) -> bool {
self.pep508_marker.evaluate(env, extras) && self.conflict_marker.evaluate(env, extras)
}
@ -91,8 +91,8 @@ impl UniversalMarker {
/// producing different versions of the same package), then one should
/// always use a universal marker since it accounts for all possible ways
/// for a package to be installed.
pub fn pep508(&self) -> &MarkerTree {
&self.pep508_marker
pub fn pep508(self) -> MarkerTree {
self.pep508_marker
}
/// Returns the non-PEP 508 marker expression that represents conflicting
@ -106,8 +106,8 @@ impl UniversalMarker {
/// of non-trivial conflict markers and fails if any are found. (Because
/// conflict markers cannot be represented in the `requirements.txt`
/// format.)
pub fn conflict(&self) -> &MarkerTree {
&self.conflict_marker
pub fn conflict(self) -> MarkerTree {
self.conflict_marker
}
}

View file

@ -819,7 +819,7 @@ impl TryFrom<SourcesWire> for Sources {
};
let mut hint = lhs.negate();
hint.and(rhs.clone());
hint.and(rhs);
let hint = hint
.contents()
.map(|contents| contents.to_string())
@ -1415,13 +1415,13 @@ impl Source {
}
/// Return the [`MarkerTree`] for the source.
pub fn marker(&self) -> &MarkerTree {
pub fn marker(&self) -> MarkerTree {
match self {
Source::Git { marker, .. } => marker,
Source::Url { marker, .. } => marker,
Source::Path { marker, .. } => marker,
Source::Registry { marker, .. } => marker,
Source::Workspace { marker, .. } => marker,
Source::Git { marker, .. } => *marker,
Source::Url { marker, .. } => *marker,
Source::Path { marker, .. } => *marker,
Source::Registry { marker, .. } => *marker,
Source::Workspace { marker, .. } => *marker,
}
}

View file

@ -1105,7 +1105,7 @@ fn update_requirement(old: &mut Requirement, new: &Requirement, has_source: bool
// Update the marker expression.
if new.marker.contents().is_some() {
old.marker = new.marker.clone();
old.marker = new.marker;
}
}

View file

@ -361,9 +361,9 @@ async fn do_lock(
.iter()
.zip(environments.as_markers().iter().skip(1))
{
if !lhs.is_disjoint(rhs) {
if !lhs.is_disjoint(*rhs) {
let mut hint = lhs.negate();
hint.and(rhs.clone());
hint.and(*rhs);
let lhs = lhs
.contents()
@ -413,6 +413,7 @@ async fn do_lock(
.map(SupportedEnvironments::as_markers)
.into_iter()
.flatten()
.copied()
{
if requires_python.to_marker_tree().is_disjoint(environment) {
return if let Some(contents) = environment.contents() {
@ -604,8 +605,8 @@ async fn do_lock(
// `ResolverEnvironment`.
lock.fork_markers()
.iter()
.copied()
.map(UniversalMarker::pep508)
.cloned()
.collect()
})
.unwrap_or_else(|| {
@ -814,7 +815,7 @@ impl ValidatedLock {
.map(SupportedEnvironments::as_markers)
.unwrap_or_default()
.iter()
.cloned()
.copied()
.map(|marker| lock.simplify_environment(marker))
.collect::<Vec<_>>();
if expected != actual {

View file

@ -325,7 +325,7 @@ pub(super) async fn do_sync(
target
.lock()
.simplified_supported_environments()
.iter()
.into_iter()
.filter_map(MarkerTree::contents)
.map(|env| format!("`{env}`"))
.join(", "),