Add a universal resolution mode to pip compile (#4505)

## Summary

This needs more tests and a few more changes, but checkpointing it for
now.
This commit is contained in:
Charlie Marsh 2024-06-25 17:28:50 -04:00 committed by GitHub
parent f2f48d339e
commit e1708689a9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 186 additions and 27 deletions

View file

@ -1,5 +1,5 @@
use pep440_rs::VersionSpecifiers;
use pep508_rs::StringVersion;
use pep440_rs::{Operator, Version, VersionSpecifier, VersionSpecifiers};
use pep508_rs::{MarkerExpression, MarkerTree, MarkerValueVersion, StringVersion};
use uv_toolchain::{Interpreter, PythonVersion};
use crate::RequiresPython;
@ -59,10 +59,32 @@ impl PythonRequirement {
self.target.as_ref()
}
/// Return the target version of Python as a "requires python" type,
/// if available.
pub(crate) fn requires_python(&self) -> Option<&RequiresPython> {
self.target().and_then(|target| target.as_requires_python())
/// Return a [`MarkerTree`] representing the Python requirement.
///
/// See: [`RequiresPython::to_marker_tree`]
pub fn to_marker_tree(&self) -> MarkerTree {
let version = match &self.target {
None => self.installed.version.clone(),
Some(PythonTarget::Version(version)) => version.version.clone(),
Some(PythonTarget::RequiresPython(requires_python)) => {
return requires_python.to_marker_tree()
}
};
let version_major_minor_only = Version::new(version.release().iter().take(2));
let expr_python_version = MarkerExpression::Version {
key: MarkerValueVersion::PythonVersion,
specifier: VersionSpecifier::from_version(Operator::Equal, version_major_minor_only)
.unwrap(),
};
let expr_python_full_version = MarkerExpression::Version {
key: MarkerValueVersion::PythonFullVersion,
specifier: VersionSpecifier::from_version(Operator::Equal, version).unwrap(),
};
MarkerTree::And(vec![
MarkerTree::Expression(expr_python_version),
MarkerTree::Expression(expr_python_full_version),
])
}
}

View file

@ -48,7 +48,6 @@ use crate::pubgrub::{
PubGrubPriorities, PubGrubPython, PubGrubSpecifier,
};
use crate::python_requirement::PythonRequirement;
use crate::requires_python::RequiresPython;
use crate::resolution::ResolutionGraph;
pub(crate) use crate::resolver::availability::{
IncompletePackage, ResolverVersion, UnavailablePackage, UnavailableReason, UnavailableVersion,
@ -193,12 +192,7 @@ impl<Provider: ResolverProvider, InstalledPackages: InstalledPackagesProvider>
let requires_python = if markers.is_some() {
None
} else {
Some(
python_requirement
.requires_python()
.map(RequiresPython::to_marker_tree)
.unwrap_or_else(|| MarkerTree::And(vec![])),
)
Some(python_requirement.to_marker_tree())
};
let state = ResolverState {
index: index.clone(),