Skip Windows Python interpreters that return a broken MSIX package code (#14636)
Currently we treat all spawn failures as fatal, because they indicate a broken interpreter. In this case, I think we should just skip these broken interpreters — though I don't know the root cause of why it's broken yet. Closes https://github.com/astral-sh/uv/issues/14637 See https://discord.com/channels/1039017663004942429/1039017663512449056/1394758502647333025
This commit is contained in:
@@ -884,6 +884,14 @@ impl Error {
|
||||
);
|
||||
false
|
||||
}
|
||||
#[cfg(windows)]
|
||||
InterpreterError::CorruptWindowsPackage { path, err } => {
|
||||
debug!(
|
||||
"Skipping bad interpreter at {} from {source}: {err}",
|
||||
path.display()
|
||||
);
|
||||
false
|
||||
}
|
||||
InterpreterError::NotFound(path)
|
||||
| InterpreterError::BrokenSymlink(BrokenSymlink { path, .. }) => {
|
||||
// If the interpreter is from an active, valid virtual environment, we should
|
||||
|
||||
@@ -34,6 +34,9 @@ use crate::{
|
||||
VirtualEnvironment,
|
||||
};
|
||||
|
||||
#[cfg(windows)]
|
||||
use windows_sys::Win32::Foundation::{APPMODEL_ERROR_NO_PACKAGE, ERROR_CANT_ACCESS_FILE};
|
||||
|
||||
/// A Python executable and its associated platform markers.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Interpreter {
|
||||
@@ -760,6 +763,13 @@ pub enum Error {
|
||||
#[source]
|
||||
err: io::Error,
|
||||
},
|
||||
#[cfg(windows)]
|
||||
#[error("Failed to query Python interpreter at `{path}`")]
|
||||
CorruptWindowsPackage {
|
||||
path: PathBuf,
|
||||
#[source]
|
||||
err: io::Error,
|
||||
},
|
||||
#[error("{0}")]
|
||||
UnexpectedResponse(UnexpectedResponseError),
|
||||
#[error("{0}")]
|
||||
@@ -872,10 +882,23 @@ impl InterpreterInfo {
|
||||
.arg("-c")
|
||||
.arg(script)
|
||||
.output()
|
||||
.map_err(|err| Error::SpawnFailed {
|
||||
path: interpreter.to_path_buf(),
|
||||
err,
|
||||
})?;
|
||||
.map_err(
|
||||
|err| match err.raw_os_error().and_then(|code| u32::try_from(code).ok()) {
|
||||
// These error codes are returned if the Python interpreter is a corrupt MSIX
|
||||
// package, which we want to differentiate from a typical spawn failure.
|
||||
#[cfg(windows)]
|
||||
Some(APPMODEL_ERROR_NO_PACKAGE | ERROR_CANT_ACCESS_FILE) => {
|
||||
Error::CorruptWindowsPackage {
|
||||
path: interpreter.to_path_buf(),
|
||||
err,
|
||||
}
|
||||
}
|
||||
_ => Error::SpawnFailed {
|
||||
path: interpreter.to_path_buf(),
|
||||
err,
|
||||
},
|
||||
},
|
||||
)?;
|
||||
|
||||
if !output.status.success() {
|
||||
let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string();
|
||||
|
||||
Reference in New Issue
Block a user