Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 4 additions & 13 deletions crates/uv-python/src/discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ fn python_executables_from_installed<'a>(
})
.flatten();

let from_windows = std::iter::once_with(move || {
let from_windows_registry = std::iter::once_with(move || {
#[cfg(windows)]
{
// Skip interpreter probing if we already know the version doesn't match.
Expand Down Expand Up @@ -376,14 +376,14 @@ fn python_executables_from_installed<'a>(
PythonPreference::Managed => Box::new(
from_managed_installations
.chain(from_search_path)
.chain(from_windows),
.chain(from_windows_registry),
),
PythonPreference::System => Box::new(
from_search_path
.chain(from_windows)
.chain(from_windows_registry)
.chain(from_managed_installations),
),
PythonPreference::OnlySystem => Box::new(from_search_path.chain(from_windows)),
PythonPreference::OnlySystem => Box::new(from_search_path.chain(from_windows_registry)),
}
}

Expand Down Expand Up @@ -1522,15 +1522,6 @@ impl PythonPreference {
}
}

/// Return the default [`PythonPreference`], respecting the `UV_TEST_PYTHON_PATH` variable.
pub fn default_from_env() -> Self {
if env::var_os("UV_TEST_PYTHON_PATH").is_some() {
Self::OnlySystem
} else {
Self::default()
}
}

pub(crate) fn allows_managed(self) -> bool {
matches!(self, Self::Managed | Self::OnlyManaged)
}
Expand Down
2 changes: 1 addition & 1 deletion crates/uv/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ impl GlobalSettings {
python_preference: args
.python_preference
.combine(workspace.and_then(|workspace| workspace.globals.python_preference))
.unwrap_or_else(PythonPreference::default_from_env),
.unwrap_or_default(),
python_downloads: flag(args.allow_python_downloads, args.no_python_downloads)
.map(PythonDownloads::from)
.combine(env(env::UV_PYTHON_DOWNLOADS))
Expand Down
15 changes: 15 additions & 0 deletions crates/uv/tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,21 @@ impl TestContext {
self
}

/// Add extra standard filtering for executable suffixes on the current platform e.g.
/// drops `.exe` on Windows.
#[must_use]
pub fn with_filtered_python_sources(mut self) -> Self {
self.filters.push((
"managed installations or system path".to_string(),
"[PYTHON SOURCES]".to_string(),
));
self.filters.push((
"managed installations, system path, or `py` launcher".to_string(),
"[PYTHON SOURCES]".to_string(),
));
self
}

/// Add extra standard filtering for Python executable names, e.g., stripping version number
/// and `.exe` suffixes.
#[must_use]
Expand Down
14 changes: 3 additions & 11 deletions crates/uv/tests/lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3347,19 +3347,11 @@ fn lock_requires_python() -> Result<()> {
});

// Validate that attempting to install with an unsupported Python version raises an error.
let context38 = TestContext::new("3.8");
let context38 = TestContext::new("3.8").with_filtered_python_sources();

fs_err::copy(pyproject_toml, context38.temp_dir.join("pyproject.toml"))?;
fs_err::copy(&lockfile, context38.temp_dir.join("uv.lock"))?;

let filters: Vec<_> = context38
.filters()
.into_iter()
.chain(context.filters())
// Platform independent message for the missing Python installation
.chain([(" or `py` launcher", "")])
.collect();

// Re-run with `--locked`.
uv_snapshot!(context.filters(), context.lock().arg("--locked"), @r###"
success: true
Expand All @@ -3372,13 +3364,13 @@ fn lock_requires_python() -> Result<()> {

// Install from the lockfile.
// Note we need to disable Python fetches or we'll just download 3.12
uv_snapshot!(filters, context38.sync().arg("--frozen").arg("--no-python-downloads"), @r###"
uv_snapshot!(context38.filters(), context38.sync().arg("--frozen").arg("--no-python-downloads"), @r###"
success: false
exit_code: 2
----- stdout -----

----- stderr -----
error: No interpreter found for Python >=3.12 in system path
error: No interpreter found for Python >=3.12 in [PYTHON SOURCES]
"###);

Ok(())
Expand Down
12 changes: 6 additions & 6 deletions crates/uv/tests/python_find.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ fn python_find() {
----- stdout -----

----- stderr -----
error: No interpreter found in virtual environments, system path, or `py` launcher
error: No interpreter found in virtual environments, managed installations, system path, or `py` launcher
"###);
} else {
uv_snapshot!(context.filters(), context.python_find().env("UV_TEST_PYTHON_PATH", ""), @r###"
Expand All @@ -31,7 +31,7 @@ fn python_find() {
----- stdout -----

----- stderr -----
error: No interpreter found in virtual environments or system path
error: No interpreter found in virtual environments, managed installations, or system path
"###);
}

Expand Down Expand Up @@ -118,7 +118,7 @@ fn python_find() {
----- stdout -----

----- stderr -----
error: No interpreter found for PyPy in virtual environments, system path, or `py` launcher
error: No interpreter found for PyPy in virtual environments, managed installations, system path, or `py` launcher
"###);
} else {
uv_snapshot!(context.filters(), context.python_find().arg("pypy"), @r###"
Expand All @@ -127,7 +127,7 @@ fn python_find() {
----- stdout -----

----- stderr -----
error: No interpreter found for PyPy in virtual environments or system path
error: No interpreter found for PyPy in virtual environments, managed installations, or system path
"###);
}

Expand Down Expand Up @@ -443,7 +443,7 @@ fn python_find_unsupported_version() {
----- stdout -----

----- stderr -----
error: No interpreter found for Python 4.2 in virtual environments or system path
error: No interpreter found for Python 4.2 in virtual environments, managed installations, or system path
"###);

// Request a low version with a range
Expand All @@ -453,7 +453,7 @@ fn python_find_unsupported_version() {
----- stdout -----

----- stderr -----
error: No interpreter found for Python <3.0 in virtual environments or system path
error: No interpreter found for Python <3.0 in virtual environments, managed installations, or system path
"###);

// Request free-threaded Python on unsupported version
Expand Down
18 changes: 9 additions & 9 deletions crates/uv/tests/python_pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ fn python_pin() {
Updated `.python-version` from `[PYTHON-3.11]` -> `pypy`

----- stderr -----
warning: No interpreter found for PyPy in system path
warning: No interpreter found for PyPy in managed installations or system path
"###);

let python_version = context.read(PYTHON_VERSION_FILENAME);
Expand All @@ -192,7 +192,7 @@ fn python_pin() {
Updated `.python-version` from `pypy` -> `3.7`

----- stderr -----
warning: No interpreter found for Python 3.7 in system path
warning: No interpreter found for Python 3.7 in managed installations or system path
"###);

let python_version = context.read(PYTHON_VERSION_FILENAME);
Expand All @@ -216,7 +216,7 @@ fn python_pin_no_python() {
Pinned `.python-version` to `3.12`

----- stderr -----
warning: No interpreter found for Python 3.12 in system path
warning: No interpreter found for Python 3.12 in managed installations or system path
"###);
}

Expand Down Expand Up @@ -403,7 +403,7 @@ fn warning_pinned_python_version_not_installed() -> anyhow::Result<()> {
3.12

----- stderr -----
warning: Failed to resolve pinned Python version `3.12`: No interpreter found for Python 3.12 in system path or `py` launcher
warning: Failed to resolve pinned Python version `3.12`: No interpreter found for Python 3.12 in managed installations, system path, or `py` launcher
"###);
} else {
uv_snapshot!(context.filters(), context.python_pin(), @r###"
Expand All @@ -413,7 +413,7 @@ fn warning_pinned_python_version_not_installed() -> anyhow::Result<()> {
3.12

----- stderr -----
warning: Failed to resolve pinned Python version `3.12`: No interpreter found for Python 3.12 in system path
warning: Failed to resolve pinned Python version `3.12`: No interpreter found for Python 3.12 in managed installations or system path
"###);
}

Expand All @@ -432,7 +432,7 @@ fn python_pin_resolve_no_python() {
----- stdout -----

----- stderr -----
error: No interpreter found for Python 3.12 in system path or `py` launcher
error: No interpreter found for Python 3.12 in managed installations, system path, or `py` launcher
"###);
} else {
uv_snapshot!(context.filters(), context.python_pin().arg("--resolved").arg("3.12"), @r###"
Expand All @@ -441,7 +441,7 @@ fn python_pin_resolve_no_python() {
----- stdout -----

----- stderr -----
error: No interpreter found for Python 3.12 in system path
error: No interpreter found for Python 3.12 in managed installations or system path
"###);
}
}
Expand Down Expand Up @@ -597,7 +597,7 @@ fn python_pin_resolve() {
----- stdout -----

----- stderr -----
error: No interpreter found for PyPy in system path
error: No interpreter found for PyPy in managed installations or system path
"###);

let python_version = context.read(PYTHON_VERSION_FILENAME);
Expand All @@ -618,7 +618,7 @@ fn python_pin_resolve() {
----- stdout -----

----- stderr -----
error: No interpreter found for Python 3.7 in system path
error: No interpreter found for Python 3.7 in managed installations or system path
"###);

let python_version = context.read(PYTHON_VERSION_FILENAME);
Expand Down
Loading