mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 21:35:00 +00:00
Use requires-python
semantics for --universal
(#4701)
## Summary This doesn't actually change any behaviors, but it does make it a bit easier to solve #4669, because we don't have to support "version narrowing" for the non-`RequiresPython` variants in here. Right now, the semantics are kind of muddied, because the `target` variant is _sometimes_ interpreted as an exact version and sometimes as a lower bound.
This commit is contained in:
parent
348efa26ba
commit
f3d1e52e65
5 changed files with 27 additions and 38 deletions
|
@ -831,7 +831,7 @@ impl std::fmt::Display for PubGrubHint {
|
||||||
} => {
|
} => {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}{} The `Requires-Python` requirement ({}) defined in your `pyproject.toml` includes Python versions that are not supported by your dependencies (e.g., {} only supports {}). Consider using a more restrictive `Requires-Python` requirement (like {}).",
|
"{}{} The `Requires-Python` requirement ({}) includes Python versions that are not supported by your dependencies (e.g., {} only supports {}). Consider using a more restrictive `Requires-Python` requirement (like {}).",
|
||||||
"hint".bold().cyan(),
|
"hint".bold().cyan(),
|
||||||
":".bold(),
|
":".bold(),
|
||||||
requires_python.bold(),
|
requires_python.bold(),
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use pep440_rs::{Operator, Version, VersionSpecifier, VersionSpecifiers};
|
use pep440_rs::VersionSpecifiers;
|
||||||
use pep508_rs::{MarkerExpression, MarkerTree, MarkerValueVersion, StringVersion};
|
use pep508_rs::{MarkerTree, StringVersion};
|
||||||
use uv_toolchain::{Interpreter, PythonVersion};
|
use uv_toolchain::{Interpreter, PythonVersion};
|
||||||
|
|
||||||
use crate::RequiresPython;
|
use crate::RequiresPython;
|
||||||
|
@ -62,32 +62,12 @@ impl PythonRequirement {
|
||||||
/// Return a [`MarkerTree`] representing the Python requirement.
|
/// Return a [`MarkerTree`] representing the Python requirement.
|
||||||
///
|
///
|
||||||
/// See: [`RequiresPython::to_marker_tree`]
|
/// See: [`RequiresPython::to_marker_tree`]
|
||||||
pub fn to_marker_tree(&self) -> MarkerTree {
|
pub fn to_marker_tree(&self) -> Option<MarkerTree> {
|
||||||
let version = match &self.target {
|
if let Some(PythonTarget::RequiresPython(requires_python)) = self.target.as_ref() {
|
||||||
None => self.installed.version.clone(),
|
Some(requires_python.to_marker_tree())
|
||||||
Some(PythonTarget::Version(version)) => version.version.clone(),
|
} else {
|
||||||
Some(PythonTarget::RequiresPython(requires_python)) => {
|
None
|
||||||
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::GreaterThanEqual,
|
|
||||||
version_major_minor_only,
|
|
||||||
)
|
|
||||||
.unwrap(),
|
|
||||||
};
|
|
||||||
let expr_python_full_version = MarkerExpression::Version {
|
|
||||||
key: MarkerValueVersion::PythonFullVersion,
|
|
||||||
specifier: VersionSpecifier::from_version(Operator::GreaterThanEqual, version).unwrap(),
|
|
||||||
};
|
|
||||||
MarkerTree::And(vec![
|
|
||||||
MarkerTree::Expression(expr_python_version),
|
|
||||||
MarkerTree::Expression(expr_python_full_version),
|
|
||||||
])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -191,11 +191,6 @@ impl<Provider: ResolverProvider, InstalledPackages: InstalledPackagesProvider>
|
||||||
provider: Provider,
|
provider: Provider,
|
||||||
installed_packages: InstalledPackages,
|
installed_packages: InstalledPackages,
|
||||||
) -> Result<Self, ResolveError> {
|
) -> Result<Self, ResolveError> {
|
||||||
let requires_python = if markers.is_some() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(python_requirement.to_marker_tree())
|
|
||||||
};
|
|
||||||
let state = ResolverState {
|
let state = ResolverState {
|
||||||
index: index.clone(),
|
index: index.clone(),
|
||||||
git: git.clone(),
|
git: git.clone(),
|
||||||
|
@ -214,8 +209,12 @@ impl<Provider: ResolverProvider, InstalledPackages: InstalledPackagesProvider>
|
||||||
exclusions: manifest.exclusions,
|
exclusions: manifest.exclusions,
|
||||||
hasher: hasher.clone(),
|
hasher: hasher.clone(),
|
||||||
markers: markers.cloned(),
|
markers: markers.cloned(),
|
||||||
|
requires_python: if markers.is_some() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
python_requirement.to_marker_tree()
|
||||||
|
},
|
||||||
python_requirement: python_requirement.clone(),
|
python_requirement: python_requirement.clone(),
|
||||||
requires_python,
|
|
||||||
reporter: None,
|
reporter: None,
|
||||||
installed_packages,
|
installed_packages,
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,7 +28,8 @@ use uv_requirements::{
|
||||||
};
|
};
|
||||||
use uv_resolver::{
|
use uv_resolver::{
|
||||||
AnnotationStyle, DependencyMode, DisplayResolutionGraph, ExcludeNewer, FlatIndex,
|
AnnotationStyle, DependencyMode, DisplayResolutionGraph, ExcludeNewer, FlatIndex,
|
||||||
InMemoryIndex, OptionsBuilder, PreReleaseMode, PythonRequirement, ResolutionMode,
|
InMemoryIndex, OptionsBuilder, PreReleaseMode, PythonRequirement, RequiresPython,
|
||||||
|
ResolutionMode,
|
||||||
};
|
};
|
||||||
use uv_toolchain::{
|
use uv_toolchain::{
|
||||||
EnvironmentPreference, PythonEnvironment, PythonVersion, Toolchain, ToolchainPreference,
|
EnvironmentPreference, PythonEnvironment, PythonVersion, Toolchain, ToolchainPreference,
|
||||||
|
@ -212,7 +213,16 @@ pub(crate) async fn pip_compile(
|
||||||
};
|
};
|
||||||
|
|
||||||
// Determine the Python requirement, if the user requested a specific version.
|
// Determine the Python requirement, if the user requested a specific version.
|
||||||
let python_requirement = if let Some(python_version) = python_version.as_ref() {
|
let python_requirement = if universal {
|
||||||
|
let requires_python = RequiresPython::greater_than_equal_version(
|
||||||
|
if let Some(python_version) = python_version.as_ref() {
|
||||||
|
python_version.version.clone()
|
||||||
|
} else {
|
||||||
|
interpreter.python_version().clone()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
PythonRequirement::from_requires_python(&interpreter, &requires_python)
|
||||||
|
} else if let Some(python_version) = python_version.as_ref() {
|
||||||
PythonRequirement::from_python_version(&interpreter, python_version)
|
PythonRequirement::from_python_version(&interpreter, python_version)
|
||||||
} else {
|
} else {
|
||||||
PythonRequirement::from_interpreter(&interpreter)
|
PythonRequirement::from_interpreter(&interpreter)
|
||||||
|
|
|
@ -1650,7 +1650,7 @@ fn lock_requires_python() -> Result<()> {
|
||||||
And because project==0.1.0 depends on pygls>=1.1.0, we can conclude that project==0.1.0 cannot be used.
|
And because project==0.1.0 depends on pygls>=1.1.0, we can conclude that project==0.1.0 cannot be used.
|
||||||
And because only project==0.1.0 is available and you require project, we can conclude that the requirements are unsatisfiable.
|
And because only project==0.1.0 is available and you require project, we can conclude that the requirements are unsatisfiable.
|
||||||
|
|
||||||
hint: The `Requires-Python` requirement (>=3.7) defined in your `pyproject.toml` includes Python versions that are not supported by your dependencies (e.g., pygls>=1.1.0,<=1.2.1 only supports >=3.7.9, <4). Consider using a more restrictive `Requires-Python` requirement (like >=3.7.9, <4).
|
hint: The `Requires-Python` requirement (>=3.7) includes Python versions that are not supported by your dependencies (e.g., pygls>=1.1.0,<=1.2.1 only supports >=3.7.9, <4). Consider using a more restrictive `Requires-Python` requirement (like >=3.7.9, <4).
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
// Require >=3.7, and allow locking to a version of `pygls` that is compatible (==1.0.1).
|
// Require >=3.7, and allow locking to a version of `pygls` that is compatible (==1.0.1).
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue