mirror of
				https://github.com/astral-sh/uv.git
				synced 2025-11-03 21:23:54 +00:00 
			
		
		
		
	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
1394758502
			
			
This commit is contained in:
		
							parent
							
								
									ab2bd0179b
								
							
						
					
					
						commit
						863e73a841
					
				
					 2 changed files with 35 additions and 4 deletions
				
			
		| 
						 | 
					@ -884,6 +884,14 @@ impl Error {
 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
                    false
 | 
					                    false
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                #[cfg(windows)]
 | 
				
			||||||
 | 
					                InterpreterError::CorruptWindowsPackage { path, err } => {
 | 
				
			||||||
 | 
					                    debug!(
 | 
				
			||||||
 | 
					                        "Skipping bad interpreter at {} from {source}: {err}",
 | 
				
			||||||
 | 
					                        path.display()
 | 
				
			||||||
 | 
					                    );
 | 
				
			||||||
 | 
					                    false
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                InterpreterError::NotFound(path)
 | 
					                InterpreterError::NotFound(path)
 | 
				
			||||||
                | InterpreterError::BrokenSymlink(BrokenSymlink { path, .. }) => {
 | 
					                | InterpreterError::BrokenSymlink(BrokenSymlink { path, .. }) => {
 | 
				
			||||||
                    // If the interpreter is from an active, valid virtual environment, we should
 | 
					                    // If the interpreter is from an active, valid virtual environment, we should
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,6 +34,9 @@ use crate::{
 | 
				
			||||||
    VirtualEnvironment,
 | 
					    VirtualEnvironment,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(windows)]
 | 
				
			||||||
 | 
					use windows_sys::Win32::Foundation::{APPMODEL_ERROR_NO_PACKAGE, ERROR_CANT_ACCESS_FILE};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// A Python executable and its associated platform markers.
 | 
					/// A Python executable and its associated platform markers.
 | 
				
			||||||
#[derive(Debug, Clone)]
 | 
					#[derive(Debug, Clone)]
 | 
				
			||||||
pub struct Interpreter {
 | 
					pub struct Interpreter {
 | 
				
			||||||
| 
						 | 
					@ -760,6 +763,13 @@ pub enum Error {
 | 
				
			||||||
        #[source]
 | 
					        #[source]
 | 
				
			||||||
        err: io::Error,
 | 
					        err: io::Error,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    #[cfg(windows)]
 | 
				
			||||||
 | 
					    #[error("Failed to query Python interpreter at `{path}`")]
 | 
				
			||||||
 | 
					    CorruptWindowsPackage {
 | 
				
			||||||
 | 
					        path: PathBuf,
 | 
				
			||||||
 | 
					        #[source]
 | 
				
			||||||
 | 
					        err: io::Error,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    #[error("{0}")]
 | 
					    #[error("{0}")]
 | 
				
			||||||
    UnexpectedResponse(UnexpectedResponseError),
 | 
					    UnexpectedResponse(UnexpectedResponseError),
 | 
				
			||||||
    #[error("{0}")]
 | 
					    #[error("{0}")]
 | 
				
			||||||
| 
						 | 
					@ -872,10 +882,23 @@ impl InterpreterInfo {
 | 
				
			||||||
            .arg("-c")
 | 
					            .arg("-c")
 | 
				
			||||||
            .arg(script)
 | 
					            .arg(script)
 | 
				
			||||||
            .output()
 | 
					            .output()
 | 
				
			||||||
            .map_err(|err| Error::SpawnFailed {
 | 
					            .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(),
 | 
					                            path: interpreter.to_path_buf(),
 | 
				
			||||||
                            err,
 | 
					                            err,
 | 
				
			||||||
            })?;
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    _ => Error::SpawnFailed {
 | 
				
			||||||
 | 
					                        path: interpreter.to_path_buf(),
 | 
				
			||||||
 | 
					                        err,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            )?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if !output.status.success() {
 | 
					        if !output.status.success() {
 | 
				
			||||||
            let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string();
 | 
					            let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue