Add hint when Python downloads are disabled (#14522)

Follow-up to https://github.com/astral-sh/uv/pull/14509 to provide the
_reason_ downloads are disabled and surface it as a hint rather than a
debug log.

e.g.,

```
❯ cargo run -q -- run --no-managed-python -p 3.13.4 python
error: No interpreter found for Python 3.13.4 in virtual environments or search path

hint: A managed Python download is available for Python 3.13.4, but the Python preference is set to 'only system'
```
This commit is contained in:
Zanie Blue 2025-07-10 12:06:24 -05:00 committed by GitHub
parent 1dff18897a
commit 02345a5a7d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 187 additions and 59 deletions

View file

@ -1,4 +1,5 @@
//! Find requested Python interpreters and query interpreters for information.
use owo_colors::OwoColorize;
use thiserror::Error;
#[cfg(test)]
@ -93,8 +94,8 @@ pub enum Error {
#[error(transparent)]
KeyError(#[from] installation::PythonInstallationKeyError),
#[error(transparent)]
MissingPython(#[from] PythonNotFound),
#[error("{}{}", .0, if let Some(hint) = .1 { format!("\n\n{}{} {hint}", "hint".bold().cyan(), ":".bold()) } else { String::new() })]
MissingPython(PythonNotFound, Option<String>),
#[error(transparent)]
MissingEnvironment(#[from] environment::EnvironmentNotFound),
@ -103,6 +104,21 @@ pub enum Error {
InvalidEnvironment(#[from] environment::InvalidEnvironment),
}
impl Error {
pub(crate) fn with_missing_python_hint(self, hint: String) -> Self {
match self {
Error::MissingPython(err, _) => Error::MissingPython(err, Some(hint)),
_ => self,
}
}
}
impl From<PythonNotFound> for Error {
fn from(err: PythonNotFound) -> Self {
Error::MissingPython(err, None)
}
}
// The mock interpreters are not valid on Windows so we don't have unit test coverage there
// TODO(zanieb): We should write a mock interpreter script that works on Windows
#[cfg(all(test, unix))]