Show non-critical Python discovery errors if no other interpreter is found (#10716)

Previously, these errors would only be visible in the debug logs as
"Skipping bad interpreter ..." which can lead us to making some
ridiculous claims like "There is no virtual environment" or "Python is
not installed" when really we just failed to query the interpreter for
some reason.

We show the first error, sort of arbitrarily — but I think it matches
user expectation, i.e., this would be the first Python on your PATH.

Related to #10713
This commit is contained in:
Zanie Blue 2025-01-21 15:11:55 -06:00 committed by GitHub
parent a62b891e6a
commit b543881b1b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 39 additions and 11 deletions

View file

@ -977,9 +977,16 @@ pub(crate) fn find_python_installation(
) -> Result<FindPythonResult, Error> {
let installations = find_python_installations(request, environments, preference, cache);
let mut first_prerelease = None;
let mut first_error = None;
for result in installations {
// Iterate until the first critical error or happy result
if !result.as_ref().err().map_or(true, Error::is_critical) {
// Track the first non-critical error
if first_error.is_none() {
if let Err(err) = result {
first_error = Some(err);
}
}
continue;
}
@ -1032,6 +1039,12 @@ pub(crate) fn find_python_installation(
return Ok(Ok(installation));
}
// If we found a Python, but it was unusable for some reason, report that instead of saying we
// couldn't find any Python interpreters.
if let Some(err) = first_error {
return Err(err);
}
Ok(Err(PythonNotFound {
request: request.clone(),
environment_preference: environments,

View file

@ -111,7 +111,7 @@ mod tests {
use crate::{
discovery::{
find_best_python_installation, find_python_installation, EnvironmentPreference,
self, find_best_python_installation, find_python_installation, EnvironmentPreference,
},
PythonPreference,
};
@ -589,11 +589,10 @@ mod tests {
PythonPreference::default(),
&context.cache,
)
})?;
});
assert!(
matches!(result, Err(PythonNotFound { .. })),
// TODO(zanieb): We could improve the error handling to hint this to the user
"If only Python 2 is available, we should not find a python; got {result:?}"
matches!(result, Err(discovery::Error::Query(..))),
"If only Python 2 is available, we should report the interpreter query error; got {result:?}"
);
Ok(())