From b08df2a283371e0ed20fb1cf74f60b12b2d6f809 Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Mon, 19 Aug 2024 15:39:06 -0500 Subject: [PATCH] Apply system Python filtering to executable name requests --- crates/uv-python/src/discovery.rs | 14 +++++++---- crates/uv-python/src/lib.rs | 42 +++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/crates/uv-python/src/discovery.rs b/crates/uv-python/src/discovery.rs index 1a382b9813453..8a9552f27fbef 100644 --- a/crates/uv-python/src/discovery.rs +++ b/crates/uv-python/src/discovery.rs @@ -717,11 +717,15 @@ pub fn find_python_installations<'a>( if preference.allows(PythonSource::SearchPath) { debug!("Checking for Python interpreter at {request}"); Box::new( - python_interpreters_with_executable_name(name, cache).map(|result| { - result - .map(PythonInstallation::from_tuple) - .map(FindPythonResult::Ok) - }), + python_interpreters_with_executable_name(name, cache) + .filter(move |result| { + result_satisfies_environment_preference(result, environments) + }) + .map(|result| { + result + .map(PythonInstallation::from_tuple) + .map(FindPythonResult::Ok) + }), ) } else { Box::new(std::iter::once(Err(Error::SourceNotAllowed( diff --git a/crates/uv-python/src/lib.rs b/crates/uv-python/src/lib.rs index 3f687552c0d7e..1e5627e0811c1 100644 --- a/crates/uv-python/src/lib.rs +++ b/crates/uv-python/src/lib.rs @@ -1609,6 +1609,48 @@ mod tests { "We should find the `bar` executable" ); + // With [`EnvironmentPreference::OnlyVirtual`], we should not allow the interpreter + let result = context.run(|| { + find_python_installation( + &PythonRequest::parse("bar"), + EnvironmentPreference::ExplicitSystem, + PythonPreference::OnlySystem, + &context.cache, + ) + })?; + assert!( + matches!(result, Err(PythonNotFound { .. })), + "We should not allow a system interpreter; got {result:?}" + ); + + // Unless it's a virtual environment interpreter + let mut context = TestContext::new()?; + let python = context.tempdir.child("foo").join("bar"); + TestContext::create_mock_interpreter( + &python, + &PythonVersion::from_str("3.10.0").unwrap(), + ImplementationName::default(), + false, // Not a system interpreter + )?; + context.add_to_search_path(context.tempdir.child("foo").to_path_buf()); + + let python = context + .run(|| { + find_python_installation( + &PythonRequest::parse("bar"), + EnvironmentPreference::ExplicitSystem, + PythonPreference::OnlySystem, + &context.cache, + ) + }) + .unwrap() + .unwrap(); + assert_eq!( + python.interpreter().python_full_version().to_string(), + "3.10.0", + "We should find the `bar` executable" + ); + Ok(()) }