diff --git a/crates/uv-python/src/discovery.rs b/crates/uv-python/src/discovery.rs index ab4735208..8a1cda526 100644 --- a/crates/uv-python/src/discovery.rs +++ b/crates/uv-python/src/discovery.rs @@ -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. @@ -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)), } } @@ -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) } diff --git a/crates/uv/src/settings.rs b/crates/uv/src/settings.rs index d8ae29071..d0ec6e30f 100644 --- a/crates/uv/src/settings.rs +++ b/crates/uv/src/settings.rs @@ -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)) diff --git a/crates/uv/tests/common/mod.rs b/crates/uv/tests/common/mod.rs index ac93c5a06..41e94b982 100644 --- a/crates/uv/tests/common/mod.rs +++ b/crates/uv/tests/common/mod.rs @@ -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] diff --git a/crates/uv/tests/lock.rs b/crates/uv/tests/lock.rs index 501466de1..9f4ecb2a7 100644 --- a/crates/uv/tests/lock.rs +++ b/crates/uv/tests/lock.rs @@ -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 @@ -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(()) diff --git a/crates/uv/tests/python_find.rs b/crates/uv/tests/python_find.rs index da8c27ccf..bd44fc1bd 100644 --- a/crates/uv/tests/python_find.rs +++ b/crates/uv/tests/python_find.rs @@ -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###" @@ -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 "###); } @@ -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###" @@ -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 "###); } @@ -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 @@ -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 diff --git a/crates/uv/tests/python_pin.rs b/crates/uv/tests/python_pin.rs index b58e1f7cd..4a0986e4d 100644 --- a/crates/uv/tests/python_pin.rs +++ b/crates/uv/tests/python_pin.rs @@ -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); @@ -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); @@ -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 "###); } @@ -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###" @@ -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 "###); } @@ -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###" @@ -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 "###); } } @@ -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); @@ -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); diff --git a/crates/uv/tests/show_settings.rs b/crates/uv/tests/show_settings.rs index dcad6fac7..816fe923c 100644 --- a/crates/uv/tests/show_settings.rs +++ b/crates/uv/tests/show_settings.rs @@ -60,7 +60,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -202,7 +202,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -345,7 +345,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -520,7 +520,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -664,7 +664,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -794,7 +794,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -961,7 +961,7 @@ fn resolve_index_url() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -1128,7 +1128,7 @@ fn resolve_index_url() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -1340,7 +1340,7 @@ fn resolve_find_links() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -1506,7 +1506,7 @@ fn resolve_top_level() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -1642,7 +1642,7 @@ fn resolve_top_level() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -1806,7 +1806,7 @@ fn resolve_top_level() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -1994,7 +1994,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -2120,7 +2120,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -2246,7 +2246,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -2374,7 +2374,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -2521,7 +2521,7 @@ fn resolve_tool() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -2678,7 +2678,7 @@ fn resolve_poetry_toml() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -2832,7 +2832,7 @@ fn resolve_both() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -3001,7 +3001,7 @@ fn resolve_config_file() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -3245,7 +3245,7 @@ fn resolve_skip_empty() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -3374,7 +3374,7 @@ fn resolve_skip_empty() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, } @@ -3511,7 +3511,7 @@ fn allow_insecure_host() -> anyhow::Result<()> { connectivity: Online, show_settings: true, preview: Disabled, - python_preference: OnlySystem, + python_preference: Managed, python_downloads: Automatic, no_progress: false, }