From b03b033924e5733ecd7fdeaca5e6928c51138d8d Mon Sep 17 00:00:00 2001 From: Zanie Blue Date: Thu, 19 Mar 2026 12:28:50 -0500 Subject: [PATCH] Move `is_explicit` check to `PythonSource` (#18569) --- crates/uv-python/src/discovery.rs | 46 ++++++++++++++++--------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/crates/uv-python/src/discovery.rs b/crates/uv-python/src/discovery.rs index e2f4bf9f0..ed1d5bc54 100644 --- a/crates/uv-python/src/discovery.rs +++ b/crates/uv-python/src/discovery.rs @@ -2282,6 +2282,24 @@ impl PythonSource { } } + /// Whether this source is "explicit", e.g., it was directly provided by the user or is + /// an active virtual environment. + pub(crate) fn is_explicit(self) -> bool { + match self { + Self::ProvidedPath + | Self::ParentInterpreter + | Self::ActiveEnvironment + | Self::CondaPrefix => true, + Self::Managed + | Self::DiscoveredEnvironment + | Self::SearchPath + | Self::SearchPathFirst + | Self::Registry + | Self::MicrosoftStore + | Self::BaseCondaPrefix => false, + } + } + /// Whether this source **could** be a system interpreter. pub(crate) fn is_maybe_system(self) -> bool { match self { @@ -2343,35 +2361,19 @@ impl PythonPreference { /// Returns `true` if the given installation is allowed by this preference. /// /// Explicit sources (e.g., provided paths, active environments) are always allowed, even if - /// they conflict with the preference. + /// they conflict with the preference. We may want to invalidate the environment in some + /// cases, like in projects, but we can't distinguish between explicit requests for a + /// different Python preference or a persistent preference in a configuration file which + /// would result in overly aggressive invalidation. pub fn allows_installation(self, installation: &PythonInstallation) -> bool { let source = installation.source; let interpreter = &installation.interpreter; - // If the source is "explicit", we will not apply the Python preference, e.g., if the - // user has activated a virtual environment, we should always allow it. We may want to - // invalidate the environment in some cases, like in projects, but we can't distinguish - // between explicit requests for a different Python preference or a persistent preference - // in a configuration file which would result in overly aggressive invalidation. - let is_explicit = match source { - PythonSource::ProvidedPath - | PythonSource::ParentInterpreter - | PythonSource::ActiveEnvironment - | PythonSource::CondaPrefix => true, - PythonSource::Managed - | PythonSource::DiscoveredEnvironment - | PythonSource::SearchPath - | PythonSource::SearchPathFirst - | PythonSource::Registry - | PythonSource::MicrosoftStore - | PythonSource::BaseCondaPrefix => false, - }; - match self { Self::OnlyManaged => { if self.allows_interpreter(interpreter) { true - } else if is_explicit { + } else if source.is_explicit() { debug!( "Allowing unmanaged Python interpreter at `{}` (in conflict with the `python-preference`) since it is from source: {source}", interpreter.sys_executable().display() @@ -2390,7 +2392,7 @@ impl PythonPreference { Self::OnlySystem => { if self.allows_interpreter(interpreter) { true - } else if is_explicit { + } else if source.is_explicit() { debug!( "Allowing managed Python interpreter at `{}` (in conflict with the `python-preference`) since it is from source: {source}", interpreter.sys_executable().display()