mirror of
https://github.com/astral-sh/uv.git
synced 2025-09-11 13:06:21 +00:00
Improve error message when requested Python version is unsupported (#7269)
Follows test cases in #7265 and validation removal in https://github.com/astral-sh/uv/pull/7264 It turns out we don't have good error messages for these as-is.
This commit is contained in:
parent
948071b2f2
commit
0dc1f5db21
2 changed files with 134 additions and 56 deletions
|
@ -776,19 +776,24 @@ pub fn find_python_installations<'a>(
|
|||
.map(FindPythonResult::Ok)
|
||||
})
|
||||
}),
|
||||
PythonRequest::Version(version) => Box::new({
|
||||
debug!("Searching for {request} in {preference}");
|
||||
python_interpreters(Some(version), None, environments, preference, cache)
|
||||
.filter(|result| match result {
|
||||
Err(_) => true,
|
||||
Ok((_source, interpreter)) => version.matches_interpreter(interpreter),
|
||||
})
|
||||
.map(|result| {
|
||||
result
|
||||
.map(PythonInstallation::from_tuple)
|
||||
.map(FindPythonResult::Ok)
|
||||
})
|
||||
}),
|
||||
PythonRequest::Version(version) => {
|
||||
if let Err(err) = version.check_supported() {
|
||||
return Box::new(std::iter::once(Err(Error::InvalidVersionRequest(err))));
|
||||
};
|
||||
Box::new({
|
||||
debug!("Searching for {request} in {preference}");
|
||||
python_interpreters(Some(version), None, environments, preference, cache)
|
||||
.filter(|result| match result {
|
||||
Err(_) => true,
|
||||
Ok((_source, interpreter)) => version.matches_interpreter(interpreter),
|
||||
})
|
||||
.map(|result| {
|
||||
result
|
||||
.map(PythonInstallation::from_tuple)
|
||||
.map(FindPythonResult::Ok)
|
||||
})
|
||||
})
|
||||
}
|
||||
PythonRequest::Implementation(implementation) => Box::new({
|
||||
debug!("Searching for a {request} interpreter in {preference}");
|
||||
python_interpreters(None, Some(implementation), environments, preference, cache)
|
||||
|
@ -804,49 +809,61 @@ pub fn find_python_installations<'a>(
|
|||
.map(FindPythonResult::Ok)
|
||||
})
|
||||
}),
|
||||
PythonRequest::ImplementationVersion(implementation, version) => Box::new({
|
||||
debug!("Searching for {request} in {preference}");
|
||||
python_interpreters(
|
||||
Some(version),
|
||||
Some(implementation),
|
||||
environments,
|
||||
preference,
|
||||
cache,
|
||||
)
|
||||
.filter(|result| match result {
|
||||
Err(_) => true,
|
||||
Ok((_source, interpreter)) => {
|
||||
version.matches_interpreter(interpreter)
|
||||
&& interpreter
|
||||
.implementation_name()
|
||||
.eq_ignore_ascii_case(implementation.into())
|
||||
}
|
||||
PythonRequest::ImplementationVersion(implementation, version) => {
|
||||
if let Err(err) = version.check_supported() {
|
||||
return Box::new(std::iter::once(Err(Error::InvalidVersionRequest(err))));
|
||||
};
|
||||
Box::new({
|
||||
debug!("Searching for {request} in {preference}");
|
||||
python_interpreters(
|
||||
Some(version),
|
||||
Some(implementation),
|
||||
environments,
|
||||
preference,
|
||||
cache,
|
||||
)
|
||||
.filter(|result| match result {
|
||||
Err(_) => true,
|
||||
Ok((_source, interpreter)) => {
|
||||
version.matches_interpreter(interpreter)
|
||||
&& interpreter
|
||||
.implementation_name()
|
||||
.eq_ignore_ascii_case(implementation.into())
|
||||
}
|
||||
})
|
||||
.map(|result| {
|
||||
result
|
||||
.map(PythonInstallation::from_tuple)
|
||||
.map(FindPythonResult::Ok)
|
||||
})
|
||||
})
|
||||
.map(|result| {
|
||||
result
|
||||
.map(PythonInstallation::from_tuple)
|
||||
.map(FindPythonResult::Ok)
|
||||
}
|
||||
PythonRequest::Key(request) => {
|
||||
if let Some(version) = request.version() {
|
||||
if let Err(err) = version.check_supported() {
|
||||
return Box::new(std::iter::once(Err(Error::InvalidVersionRequest(err))));
|
||||
};
|
||||
};
|
||||
Box::new({
|
||||
debug!("Searching for {request} in {preference}");
|
||||
python_interpreters(
|
||||
request.version(),
|
||||
request.implementation(),
|
||||
environments,
|
||||
preference,
|
||||
cache,
|
||||
)
|
||||
.filter(|result| match result {
|
||||
Err(_) => true,
|
||||
Ok((_source, interpreter)) => request.satisfied_by_interpreter(interpreter),
|
||||
})
|
||||
.map(|result| {
|
||||
result
|
||||
.map(PythonInstallation::from_tuple)
|
||||
.map(FindPythonResult::Ok)
|
||||
})
|
||||
})
|
||||
}),
|
||||
PythonRequest::Key(request) => Box::new({
|
||||
debug!("Searching for {request} in {preference}");
|
||||
python_interpreters(
|
||||
request.version(),
|
||||
request.implementation(),
|
||||
environments,
|
||||
preference,
|
||||
cache,
|
||||
)
|
||||
.filter(|result| match result {
|
||||
Err(_) => true,
|
||||
Ok((_source, interpreter)) => request.satisfied_by_interpreter(interpreter),
|
||||
})
|
||||
.map(|result| {
|
||||
result
|
||||
.map(PythonInstallation::from_tuple)
|
||||
.map(FindPythonResult::Ok)
|
||||
})
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1446,6 +1463,37 @@ impl VersionRequest {
|
|||
.flatten()
|
||||
}
|
||||
|
||||
pub(crate) fn check_supported(&self) -> Result<(), String> {
|
||||
match self {
|
||||
Self::Any => (),
|
||||
Self::Major(major) => {
|
||||
if *major < 3 {
|
||||
return Err(format!(
|
||||
"Python <3 is not supported but {major} was requested."
|
||||
));
|
||||
}
|
||||
}
|
||||
Self::MajorMinor(major, minor) => {
|
||||
if (*major, *minor) < (3, 7) {
|
||||
return Err(format!(
|
||||
"Python <3.7 is not supported but {major}.{minor} was requested."
|
||||
));
|
||||
}
|
||||
}
|
||||
Self::MajorMinorPatch(major, minor, patch) => {
|
||||
if (*major, *minor) < (3, 7) {
|
||||
return Err(format!(
|
||||
"Python <3.7 is not supported but {major}.{minor}.{patch} was requested."
|
||||
));
|
||||
}
|
||||
}
|
||||
// TODO(zanieb): We could do some checking here to see if the range can be satisfied
|
||||
Self::Range(_) => (),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Check if a interpreter matches the requested Python version.
|
||||
pub(crate) fn matches_interpreter(&self, interpreter: &Interpreter) -> bool {
|
||||
match self {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue