mirror of
https://github.com/astral-sh/uv.git
synced 2025-10-29 19:17:26 +00:00
Skip Python 2 versions when locating Python (#3476)
## Summary Unfortunately, the `-I` flag was added in Python 3.4. So if we query a Python version prior to 3.4 (e.g., Python 2.7), we can't run our script at all, and lose the ability to match against our structured error. This PR adds an additional check against the stderr output for these cases. Closes https://github.com/astral-sh/uv/issues/3474. ## Test Plan Installed Python 2.7, and verified that it was skipped (and that we instead found my `python3`).
This commit is contained in:
parent
bc963d13cb
commit
5ad373b2ec
2 changed files with 70 additions and 19 deletions
|
|
@ -150,19 +150,77 @@ fn find_python(
|
|||
|
||||
let interpreter = match Interpreter::query(&path, cache) {
|
||||
Ok(interpreter) => interpreter,
|
||||
Err(
|
||||
err @ Error::QueryScript {
|
||||
err: InterpreterInfoError::UnsupportedPythonVersion { .. },
|
||||
..
|
||||
},
|
||||
) => {
|
||||
if selector.major() <= Some(2) {
|
||||
return Err(err);
|
||||
|
||||
// If the Python version is < 3.4, the `-I` flag is not supported, so
|
||||
// we can't run the script at all, and need to sniff it from the output.
|
||||
Err(Error::PythonSubcommandOutput { stderr, .. })
|
||||
if stderr.contains("Unknown option: -I")
|
||||
&& stderr.contains("usage: python [option]") =>
|
||||
{
|
||||
// If the user _requested_ a version prior to 3.4, raise an error, as
|
||||
// 3.4 is the minimum supported version for invoking the interpreter
|
||||
// query script at all.
|
||||
match selector {
|
||||
PythonVersionSelector::Major(major) if major < 3 => {
|
||||
return Err(Error::UnsupportedPython(major.to_string()));
|
||||
}
|
||||
// Skip over Python 2 or older installation when querying for a recent python installation.
|
||||
debug!("Found a Python 2 installation that isn't supported by uv, skipping.");
|
||||
PythonVersionSelector::MajorMinor(major, minor)
|
||||
if (major, minor) < (3, 4) =>
|
||||
{
|
||||
return Err(Error::UnsupportedPython(format!(
|
||||
"{major}.{minor}"
|
||||
)));
|
||||
}
|
||||
PythonVersionSelector::MajorMinorPatch(major, minor, patch)
|
||||
if (major, minor) < (3, 4) =>
|
||||
{
|
||||
return Err(Error::UnsupportedPython(format!(
|
||||
"{major}.{minor}.{patch}"
|
||||
)));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
debug!(
|
||||
"Found a Python installation that isn't supported by uv, skipping."
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
Err(Error::QueryScript {
|
||||
err: InterpreterInfoError::UnsupportedPythonVersion { .. },
|
||||
..
|
||||
}) => {
|
||||
// If the user _requested_ a version prior to 3.7, raise an error, as
|
||||
// 3.7 is the minimum supported version for running the interpreter
|
||||
// query script.
|
||||
match selector {
|
||||
PythonVersionSelector::Major(major) if major < 3 => {
|
||||
return Err(Error::UnsupportedPython(major.to_string()));
|
||||
}
|
||||
PythonVersionSelector::MajorMinor(major, minor)
|
||||
if (major, minor) < (3, 7) =>
|
||||
{
|
||||
return Err(Error::UnsupportedPython(format!(
|
||||
"{major}.{minor}"
|
||||
)));
|
||||
}
|
||||
PythonVersionSelector::MajorMinorPatch(major, minor, patch)
|
||||
if (major, minor) < (3, 7) =>
|
||||
{
|
||||
return Err(Error::UnsupportedPython(format!(
|
||||
"{major}.{minor}.{patch}"
|
||||
)));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
debug!(
|
||||
"Found a Python installation that isn't supported by uv, skipping."
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
Err(error) => return Err(error),
|
||||
};
|
||||
|
||||
|
|
@ -400,15 +458,6 @@ impl PythonVersionSelector {
|
|||
],
|
||||
}
|
||||
}
|
||||
|
||||
fn major(self) -> Option<u8> {
|
||||
match self {
|
||||
Self::Default => None,
|
||||
Self::Major(major) => Some(major),
|
||||
Self::MajorMinor(major, _) => Some(major),
|
||||
Self::MajorMinorPatch(major, _, _) => Some(major),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn warn_on_unsupported_python(interpreter: &Interpreter) {
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ pub enum Error {
|
|||
stdout: String,
|
||||
stderr: String,
|
||||
},
|
||||
#[error("Requested Python version ({0}) is unsupported")]
|
||||
UnsupportedPython(String),
|
||||
#[error("Failed to write to cache")]
|
||||
Encode(#[from] rmp_serde::encode::Error),
|
||||
#[error("Broken virtualenv: Failed to parse pyvenv.cfg")]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue