mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 10:58:28 +00:00
Improve interpreter discovery logging (#1909)
We had several cases where interpreter discovery fails. This PR improves the verbose output to ensure interpreter discovery is debuggable for a user. In the process, i removed the custom gourgeist logic for the uv_interpreter logic. **venv creation** ``` $ uv venv -v -p 3.10 uv_interpreter::python_query::find_requested_python request=3.10 0.002389s 0ms DEBUG uv_interpreter::python_query Starting interpreter discovery for Python 3.10 uv_interpreter::python_query::windows::py_list_paths 0.016288s 14ms DEBUG uv_interpreter::interpreter Probing interpreter info for: C:\Users\Ferris\AppData\Local\Programs\Python\Python312\python.exe 0.072860s 70ms DEBUG uv_interpreter::interpreter Found Python 3.12.1 for: C:\Users\Ferris\AppData\Local\Programs\Python\Python312\python.exe 0.074303s 72ms DEBUG uv_interpreter::interpreter Probing interpreter info for: C:\Users\Ferris\AppData\Local\Programs\Python\Python38\python.exe 0.134311s 132ms DEBUG uv_interpreter::interpreter Found Python 3.8.10 for: C:\Users\Ferris\AppData\Local\Programs\Python\Python38\python.exe x No Python 3.10 found through `py --list-paths` or in `PATH`. Is Python 3.10 installed? error: process didn't exit successfully: `target\debug\uv.exe venv -v -p 3.10` (exit code: 1) ``` ``` $ uv venv -v -p 3.10 uv_interpreter::python_query::find_requested_python request=3.10 0.001889s 0ms DEBUG uv_interpreter::python_query Starting interpreter discovery for Python 3.10 uv_interpreter::python_query::windows::py_list_paths 0.021488s 19ms DEBUG uv_interpreter::interpreter Cached interpreter info for Python 3.12.1, skipping probing: C:\Users\Ferris\AppData\Local\Programs\Python\Python312\python.exe 0.021945s 20ms DEBUG uv_interpreter::interpreter Cached interpreter info for Python 3.8.10, skipping probing: C:\Users\Ferris\AppData\Local\Programs\Python\Python38\python.exe x No Python 3.10 found through `py --list-paths` or in `PATH`. Is Python 3.10 installed? error: process didn't exit successfully: `target\debug\uv.exe venv -v -p 3.10` (exit code: 1) ``` ``` $ uv venv -v -p 3.8 uv_interpreter::python_query::find_requested_python request=3.8 0.001896s 0ms DEBUG uv_interpreter::python_query Starting interpreter discovery for Python 3.8 uv_interpreter::python_query::windows::py_list_paths 0.013541s 11ms DEBUG uv_interpreter::interpreter Cached interpreter info for Python 3.8.10, skipping probing: C:\Users\Ferris\AppData\Local\Programs\Python\Python38\python.exe Using Python 3.8.10 interpreter at C:\Users\Ferris\AppData\Local\Programs\Python\Python38\python.exe Creating virtualenv at: .venv Activate with: .venv\Scripts\activate ``` ``` $ uv venv -v -p 3.12 uv_interpreter::python_query::find_requested_python request=3.12 0.001741s 0ms DEBUG uv_interpreter::python_query Starting interpreter discovery for Python 3.12 uv_interpreter::python_query::windows::py_list_paths 0.012807s 11ms DEBUG uv_interpreter::interpreter Cached interpreter info for Python 3.12.1, skipping probing: C:\Users\Ferris\AppData\Local\Programs\Python\Python312\python.exe Using Python 3.12.1 interpreter at C:\Users\Ferris\AppData\Local\Programs\Python\Python312\python.exe Creating virtualenv at: .venv Activate with: .venv\Scripts\activate ``` **pip compile** ``` $ uv pip compile -v .\scripts\requirements\black.in uv::requirements::from_source source=.\scripts\requirements\black.in uv_interpreter::interpreter::find_best python_version=None 0.002071s 0ms DEBUG uv_interpreter::interpreter Starting interpreter discovery for active Python 0.002220s 0ms DEBUG uv_interpreter::virtual_env Found a virtualenv named .venv at: C:\Users\Ferris\projects\uv\.venv 0.002483s 0ms DEBUG uv_interpreter::interpreter Cached interpreter info for Python 3.12.1, skipping probing: C:\Users\Ferris\projects\uv\.venv\Scripts\python.exe 0.002581s DEBUG uv::commands::pip_compile Using Python 3.12.1 interpreter at C:\Users\Ferris\projects\uv\.venv\Scripts\python.exe for builds ``` ``` $ uv pip compile -p 3.8 -v .\scripts\requirements\black.in uv::requirements::from_source source=.\scripts\requirements\black.in uv_interpreter::interpreter::find_best python_version=Some(PythonVersion(StringVersion { string: "3.8", version: "3.8" })) 0.002001s 0ms DEBUG uv_interpreter::interpreter Starting interpreter discovery for Python 3.8 0.002146s 0ms DEBUG uv_interpreter::virtual_env Found a virtualenv named .venv at: C:\Users\Ferris\projects\uv\.venv 0.002378s 0ms DEBUG uv_interpreter::interpreter Cached interpreter info for Python 3.12.1, skipping probing: C:\Users\Ferris\projects\uv\.venv\Scripts\python.exe uv_interpreter::python_query::find_requested_python request=3.8 0.002509s 0ms DEBUG uv_interpreter::python_query Starting interpreter discovery for Python 3.8 uv_interpreter::python_query::windows::py_list_paths 0.015989s 13ms DEBUG uv_interpreter::interpreter Cached interpreter info for Python 3.8.10, skipping probing: C:\Users\Ferris\AppData\Local\Programs\Python\Python38\python.exe 0.016144s DEBUG uv::commands::pip_compile Using Python 3.8.10 interpreter at C:\Users\Ferris\AppData\Local\Programs\Python\Python38\python.exe for builds ``` ``` $ uv pip compile -p 3.10 -v .\scripts\requirements\black.in uv::requirements::from_source source=.\scripts\requirements\black.in uv_interpreter::interpreter::find_best python_version=Some(PythonVersion(StringVersion { string: "3.10", version: "3.10" })) 0.002086s 0ms DEBUG uv_interpreter::interpreter Starting interpreter discovery for Python 3.10 0.002234s 0ms DEBUG uv_interpreter::virtual_env Found a virtualenv named .venv at: C:\Users\Ferris\projects\uv\.venv 0.002462s 0ms DEBUG uv_interpreter::interpreter Cached interpreter info for Python 3.12.1, skipping probing: C:\Users\Ferris\projects\uv\.venv\Scripts\python.exe uv_interpreter::python_query::find_requested_python request=3.10 0.002589s 0ms DEBUG uv_interpreter::python_query Starting interpreter discovery for Python 3.10 uv_interpreter::python_query::windows::py_list_paths 0.017299s 14ms DEBUG uv_interpreter::interpreter Cached interpreter info for Python 3.12.1, skipping probing: C:\Users\Ferris\AppData\Local\Programs\Python\Python312\python.exe 0.018135s 15ms DEBUG uv_interpreter::interpreter Cached interpreter info for Python 3.8.10, skipping probing: C:\Users\Ferris\AppData\Local\Programs\Python\Python38\python.exe 0.020176s 18ms DEBUG uv_interpreter::virtual_env Found a virtualenv named .venv at: C:\Users\Ferris\projects\uv\.venv 0.020873s 18ms DEBUG uv_interpreter::interpreter Cached interpreter info for Python 3.12.1, skipping probing: C:\Users\Ferris\projects\uv\.venv\Scripts\python.exe 0.021116s DEBUG uv::commands::pip_compile Using Python 3.12.1 interpreter at C:\Users\Ferris\projects\uv\.venv\Scripts\python.exe for builds warning: The requested Python version 3.10 is not available; 3.12.1 will be used to build dependencies instead. ```
This commit is contained in:
parent
11ed4f7183
commit
9cf7d113bc
8 changed files with 64 additions and 69 deletions
|
@ -6,7 +6,7 @@ use std::process::Command;
|
|||
use fs_err as fs;
|
||||
use once_cell::sync::OnceCell;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::{debug, warn};
|
||||
use tracing::{debug, instrument, warn};
|
||||
|
||||
use cache_key::digest;
|
||||
use pep440_rs::Version;
|
||||
|
@ -35,7 +35,11 @@ pub struct Interpreter {
|
|||
|
||||
impl Interpreter {
|
||||
/// Detect the interpreter info for the given Python executable.
|
||||
pub fn query(executable: &Path, platform: &Platform, cache: &Cache) -> Result<Self, Error> {
|
||||
pub(crate) fn query(
|
||||
executable: &Path,
|
||||
platform: &Platform,
|
||||
cache: &Cache,
|
||||
) -> Result<Self, Error> {
|
||||
let info = InterpreterInfo::query_cached(executable, cache)?;
|
||||
|
||||
debug_assert!(
|
||||
|
@ -77,7 +81,7 @@ impl Interpreter {
|
|||
|
||||
/// Return a new [`Interpreter`] with the given base prefix.
|
||||
#[must_use]
|
||||
pub fn with_base_prefix(self, base_prefix: PathBuf) -> Self {
|
||||
pub(crate) fn with_base_prefix(self, base_prefix: PathBuf) -> Self {
|
||||
Self {
|
||||
base_prefix,
|
||||
..self
|
||||
|
@ -94,11 +98,21 @@ impl Interpreter {
|
|||
/// the first available version.
|
||||
///
|
||||
/// See [`Self::find_version`] for details on the precedence of Python lookup locations.
|
||||
#[instrument(skip_all, fields(?python_version))]
|
||||
pub fn find_best(
|
||||
python_version: Option<&PythonVersion>,
|
||||
platform: &Platform,
|
||||
cache: &Cache,
|
||||
) -> Result<Self, Error> {
|
||||
if let Some(python_version) = python_version {
|
||||
debug!(
|
||||
"Starting interpreter discovery for Python {}",
|
||||
python_version
|
||||
);
|
||||
} else {
|
||||
debug!("Starting interpreter discovery for active Python");
|
||||
}
|
||||
|
||||
// First, check for an exact match (or the first available version if no Python version was provided)
|
||||
if let Some(interpreter) = Self::find_version(python_version, platform, cache)? {
|
||||
return Ok(interpreter);
|
||||
|
@ -139,7 +153,7 @@ impl Interpreter {
|
|||
///
|
||||
/// If a version is provided and an interpreter cannot be found with the given version,
|
||||
/// we will return [`None`].
|
||||
pub fn find_version(
|
||||
pub(crate) fn find_version(
|
||||
python_version: Option<&PythonVersion>,
|
||||
platform: &Platform,
|
||||
cache: &Cache,
|
||||
|
@ -184,7 +198,7 @@ impl Interpreter {
|
|||
/// Find the Python interpreter in `PATH`, respecting `UV_PYTHON_PATH`.
|
||||
///
|
||||
/// Returns `Ok(None)` if not found.
|
||||
pub fn find_executable<R: AsRef<OsStr> + Into<OsString> + Copy>(
|
||||
pub(crate) fn find_executable<R: AsRef<OsStr> + Into<OsString> + Copy>(
|
||||
requested: R,
|
||||
) -> Result<Option<PathBuf>, Error> {
|
||||
let result = if let Some(isolated) = std::env::var_os("UV_TEST_PYTHON_PATH") {
|
||||
|
@ -403,7 +417,11 @@ impl InterpreterInfo {
|
|||
match rmp_serde::from_slice::<CachedByTimestamp<Self>>(&data) {
|
||||
Ok(cached) => {
|
||||
if cached.timestamp == modified {
|
||||
debug!("Using cached markers for: {}", executable.display());
|
||||
debug!(
|
||||
"Cached interpreter info for Python {}, skipping probing: {}",
|
||||
cached.data.markers.python_full_version,
|
||||
executable.display()
|
||||
);
|
||||
return Ok(cached.data);
|
||||
}
|
||||
|
||||
|
@ -424,8 +442,13 @@ impl InterpreterInfo {
|
|||
}
|
||||
|
||||
// Otherwise, run the Python script.
|
||||
debug!("Detecting markers for: {}", executable.display());
|
||||
debug!("Probing interpreter info for: {}", executable.display());
|
||||
let info = Self::query(executable)?;
|
||||
debug!(
|
||||
"Found Python {} for: {}",
|
||||
info.markers.python_full_version,
|
||||
executable.display()
|
||||
);
|
||||
|
||||
// If `executable` is a pyenv shim, a bash script that redirects to the activated
|
||||
// python executable at another path, we're not allowed to cache the interpreter info.
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::borrow::Cow;
|
|||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use tracing::instrument;
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use platform_host::Platform;
|
||||
use uv_cache::Cache;
|
||||
|
@ -23,11 +23,13 @@ use crate::{Error, Interpreter};
|
|||
/// version (e.g. `python3.12` on unix) and error when the version mismatches, as a binary with the
|
||||
/// patch version (e.g. `python3.12.1`) is often not in `PATH` and we make the simplifying
|
||||
/// assumption that the user has only this one patch version installed.
|
||||
#[instrument(skip_all, fields(%request))]
|
||||
pub fn find_requested_python(
|
||||
request: &str,
|
||||
platform: &Platform,
|
||||
cache: &Cache,
|
||||
) -> Result<Option<Interpreter>, Error> {
|
||||
debug!("Starting interpreter discovery for Python {}", request);
|
||||
let versions = request
|
||||
.splitn(3, '.')
|
||||
.map(str::parse::<u8>)
|
||||
|
@ -70,7 +72,9 @@ pub fn find_requested_python(
|
|||
///
|
||||
/// We prefer the test overwrite `UV_TEST_PYTHON_PATH` if it is set, otherwise `python3`/`python` or
|
||||
/// `python.exe` respectively.
|
||||
#[instrument(skip_all)]
|
||||
pub fn find_default_python(platform: &Platform, cache: &Cache) -> Result<Interpreter, Error> {
|
||||
debug!("Starting interpreter discovery for default Python");
|
||||
try_find_default_python(platform, cache)?.ok_or(if cfg!(windows) {
|
||||
Error::NoPythonInstalledWindows
|
||||
} else if cfg!(unix) {
|
||||
|
@ -100,7 +104,6 @@ pub(crate) fn try_find_default_python(
|
|||
/// * (windows): For each of the above, test for the existence of `python.bat` shim (pyenv-windows) last.
|
||||
///
|
||||
/// (Windows): Filter out the windows store shim (Enabled in Settings/Apps/Advanced app settings/App execution aliases).
|
||||
#[instrument(skip_all, fields(? selector))]
|
||||
fn find_python(
|
||||
selector: PythonVersionSelector,
|
||||
platform: &Platform,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use pep440_rs::Version;
|
||||
use pep508_rs::{MarkerEnvironment, StringVersion};
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::ops::Deref;
|
||||
use std::str::FromStr;
|
||||
|
||||
|
@ -41,6 +42,12 @@ impl FromStr for PythonVersion {
|
|||
}
|
||||
}
|
||||
|
||||
impl Display for PythonVersion {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl PythonVersion {
|
||||
/// Return a [`MarkerEnvironment`] compatible with the given [`PythonVersion`], based on
|
||||
/// a base [`MarkerEnvironment`].
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue