mirror of https://github.com/astral-sh/uv
Prefer system Python installations over managed ones when `--system` is used (#15061)
This fixes a regression from 0.8.0 from https://github.com/astral-sh/uv/pull/7934 and follows https://github.com/astral-sh/uv/pull/15059 The regression is from [this change](https://github.com/astral-sh/uv/pull/7934/files#diff-c7a660ac39628d5e12f388b0cacc7360affa3d7bb21191184d7ee78489675e83), which was made because we'd otherwise (with the other changes in that pull request) _filter out_ managed Python interpreters found in virtual environments. When `--system` is used we'll convert the default Python preference of `managed` to `system` which avoids things like `uv pip install --system` targeting a managed Python installation. The basic test is ``` uv python install uv pip install --system anyio ``` Prior to this change, we'd read a managed interpreter from our managed installation directory and target that. After this change, without #15059, we'd read a managed interpreter from the PATH and target that. Both of those experiences are bad, because the managed interpreters are marked as externally managed. After this change, with #15059, we properly target the system interpreter. Since we use `system` instead of `only-system`, if there is not a system interpreter we'll still retain our existing behavior and use a managed interpreter. This should limit breakage from the change. Given the source of the regression, we could probably use `only-system` here. I don't feel strongly. I think the main benefit of doing so would be that we'd omit the check for managed installations in error messages when an interpreter cannot be found? We can't really add test coverage here because the test suite always has externally managed interpreters :)
This commit is contained in:
parent
c77cb2023f
commit
8db61abb50
|
|
@ -5,7 +5,7 @@ use tracing::info;
|
|||
|
||||
use uv_cache::{Cache, CacheArgs};
|
||||
use uv_configuration::{Concurrency, Preview};
|
||||
use uv_python::{EnvironmentPreference, PythonEnvironment, PythonRequest};
|
||||
use uv_python::{EnvironmentPreference, PythonEnvironment, PythonPreference, PythonRequest};
|
||||
|
||||
#[derive(Parser)]
|
||||
pub(crate) struct CompileArgs {
|
||||
|
|
@ -25,6 +25,7 @@ pub(crate) async fn compile(args: CompileArgs) -> anyhow::Result<()> {
|
|||
let interpreter = PythonEnvironment::find(
|
||||
&PythonRequest::default(),
|
||||
EnvironmentPreference::OnlyVirtual,
|
||||
PythonPreference::default(),
|
||||
&cache,
|
||||
Preview::default(),
|
||||
)?
|
||||
|
|
|
|||
|
|
@ -2093,6 +2093,30 @@ impl PythonPreference {
|
|||
Self::Managed | Self::System | Self::OnlyManaged => true,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a new preference when the `--system` flag is used.
|
||||
///
|
||||
/// This will convert [`PythonPreference::Managed`] to [`PythonPreference::System`] when system
|
||||
/// is set.
|
||||
#[must_use]
|
||||
pub fn with_system_flag(self, system: bool) -> Self {
|
||||
match self {
|
||||
// TODO(zanieb): It's not clear if we want to allow `--system` to override
|
||||
// `--managed-python`. We should probably make this `from_system_flag` and refactor
|
||||
// handling of the `PythonPreference` to use an `Option` so we can tell if the user
|
||||
// provided it?
|
||||
Self::OnlyManaged => self,
|
||||
Self::Managed => {
|
||||
if system {
|
||||
Self::System
|
||||
} else {
|
||||
self
|
||||
}
|
||||
}
|
||||
Self::System => self,
|
||||
Self::OnlySystem => self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PythonDownloads {
|
||||
|
|
|
|||
|
|
@ -152,19 +152,16 @@ impl PythonEnvironment {
|
|||
pub fn find(
|
||||
request: &PythonRequest,
|
||||
preference: EnvironmentPreference,
|
||||
python_preference: PythonPreference,
|
||||
cache: &Cache,
|
||||
preview: Preview,
|
||||
) -> Result<Self, Error> {
|
||||
let installation = match find_python_installation(
|
||||
request,
|
||||
preference,
|
||||
PythonPreference::default(),
|
||||
cache,
|
||||
preview,
|
||||
)? {
|
||||
Ok(installation) => installation,
|
||||
Err(err) => return Err(EnvironmentNotFound::from(err).into()),
|
||||
};
|
||||
let installation =
|
||||
match find_python_installation(request, preference, python_preference, cache, preview)?
|
||||
{
|
||||
Ok(installation) => installation,
|
||||
Err(err) => return Err(EnvironmentNotFound::from(err).into()),
|
||||
};
|
||||
Ok(Self::from_installation(installation))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use uv_cache::Cache;
|
|||
use uv_configuration::Preview;
|
||||
use uv_distribution_types::{Diagnostic, InstalledDist};
|
||||
use uv_installer::{SitePackages, SitePackagesDiagnostic};
|
||||
use uv_python::PythonPreference;
|
||||
use uv_python::{EnvironmentPreference, PythonEnvironment, PythonRequest};
|
||||
|
||||
use crate::commands::pip::operations::report_target_environment;
|
||||
|
|
@ -28,6 +29,7 @@ pub(crate) fn pip_check(
|
|||
let environment = PythonEnvironment::find(
|
||||
&python.map(PythonRequest::parse).unwrap_or_default(),
|
||||
EnvironmentPreference::from_system_flag(system, false),
|
||||
PythonPreference::default().with_system_flag(system),
|
||||
cache,
|
||||
preview,
|
||||
)?;
|
||||
|
|
|
|||
|
|
@ -284,6 +284,7 @@ pub(crate) async fn pip_compile(
|
|||
|
||||
// Find an interpreter to use for building distributions
|
||||
let environment_preference = EnvironmentPreference::from_system_flag(system, false);
|
||||
let python_preference = python_preference.with_system_flag(system);
|
||||
let interpreter = if let Some(python) = python.as_ref() {
|
||||
let request = PythonRequest::parse(python);
|
||||
PythonInstallation::find(
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use uv_cache::Cache;
|
|||
use uv_configuration::Preview;
|
||||
use uv_distribution_types::{Diagnostic, InstalledDist, Name};
|
||||
use uv_installer::SitePackages;
|
||||
use uv_python::PythonPreference;
|
||||
use uv_python::{EnvironmentPreference, PythonEnvironment, PythonRequest};
|
||||
|
||||
use crate::commands::ExitStatus;
|
||||
|
|
@ -30,6 +31,7 @@ pub(crate) fn pip_freeze(
|
|||
let environment = PythonEnvironment::find(
|
||||
&python.map(PythonRequest::parse).unwrap_or_default(),
|
||||
EnvironmentPreference::from_system_flag(system, false),
|
||||
PythonPreference::default().with_system_flag(system),
|
||||
cache,
|
||||
preview,
|
||||
)?;
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ pub(crate) async fn pip_install(
|
|||
.map(PythonRequest::parse)
|
||||
.unwrap_or_default(),
|
||||
EnvironmentPreference::from_system_flag(system, false),
|
||||
python_preference,
|
||||
python_preference.with_system_flag(system),
|
||||
&cache,
|
||||
preview,
|
||||
)?;
|
||||
|
|
@ -207,6 +207,7 @@ pub(crate) async fn pip_install(
|
|||
.map(PythonRequest::parse)
|
||||
.unwrap_or_default(),
|
||||
EnvironmentPreference::from_system_flag(system, true),
|
||||
PythonPreference::default().with_system_flag(system),
|
||||
&cache,
|
||||
preview,
|
||||
)?;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ use uv_installer::SitePackages;
|
|||
use uv_normalize::PackageName;
|
||||
use uv_pep440::Version;
|
||||
use uv_python::PythonRequest;
|
||||
use uv_python::{EnvironmentPreference, PythonEnvironment};
|
||||
use uv_python::{EnvironmentPreference, PythonEnvironment, PythonPreference};
|
||||
use uv_resolver::{ExcludeNewer, PrereleaseMode};
|
||||
|
||||
use crate::commands::ExitStatus;
|
||||
|
|
@ -65,6 +65,7 @@ pub(crate) async fn pip_list(
|
|||
let environment = PythonEnvironment::find(
|
||||
&python.map(PythonRequest::parse).unwrap_or_default(),
|
||||
EnvironmentPreference::from_system_flag(system, false),
|
||||
PythonPreference::default().with_system_flag(system),
|
||||
cache,
|
||||
preview,
|
||||
)?;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use uv_fs::Simplified;
|
|||
use uv_install_wheel::read_record_file;
|
||||
use uv_installer::SitePackages;
|
||||
use uv_normalize::PackageName;
|
||||
use uv_python::{EnvironmentPreference, PythonEnvironment, PythonRequest};
|
||||
use uv_python::{EnvironmentPreference, PythonEnvironment, PythonPreference, PythonRequest};
|
||||
|
||||
use crate::commands::ExitStatus;
|
||||
use crate::commands::pip::operations::report_target_environment;
|
||||
|
|
@ -47,6 +47,7 @@ pub(crate) fn pip_show(
|
|||
let environment = PythonEnvironment::find(
|
||||
&python.map(PythonRequest::parse).unwrap_or_default(),
|
||||
EnvironmentPreference::from_system_flag(system, false),
|
||||
PythonPreference::default().with_system_flag(system),
|
||||
cache,
|
||||
preview,
|
||||
)?;
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ pub(crate) async fn pip_sync(
|
|||
.map(PythonRequest::parse)
|
||||
.unwrap_or_default(),
|
||||
EnvironmentPreference::from_system_flag(system, false),
|
||||
python_preference,
|
||||
python_preference.with_system_flag(system),
|
||||
&cache,
|
||||
preview,
|
||||
)?;
|
||||
|
|
@ -184,6 +184,7 @@ pub(crate) async fn pip_sync(
|
|||
.map(PythonRequest::parse)
|
||||
.unwrap_or_default(),
|
||||
EnvironmentPreference::from_system_flag(system, true),
|
||||
PythonPreference::default().with_system_flag(system),
|
||||
&cache,
|
||||
preview,
|
||||
)?;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ use uv_normalize::PackageName;
|
|||
use uv_pep440::Version;
|
||||
use uv_pep508::{Requirement, VersionOrUrl};
|
||||
use uv_pypi_types::{ResolutionMetadata, ResolverMarkerEnvironment, VerbatimParsedUrl};
|
||||
use uv_python::{EnvironmentPreference, PythonEnvironment, PythonRequest};
|
||||
use uv_python::{EnvironmentPreference, PythonEnvironment, PythonPreference, PythonRequest};
|
||||
use uv_resolver::{ExcludeNewer, PrereleaseMode};
|
||||
|
||||
use crate::commands::ExitStatus;
|
||||
|
|
@ -58,6 +58,7 @@ pub(crate) async fn pip_tree(
|
|||
let environment = PythonEnvironment::find(
|
||||
&python.map(PythonRequest::parse).unwrap_or_default(),
|
||||
EnvironmentPreference::from_system_flag(system, false),
|
||||
PythonPreference::default().with_system_flag(system),
|
||||
cache,
|
||||
preview,
|
||||
)?;
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ use uv_distribution_types::{InstalledMetadata, Name, UnresolvedRequirement};
|
|||
use uv_fs::Simplified;
|
||||
use uv_pep508::UnnamedRequirement;
|
||||
use uv_pypi_types::VerbatimParsedUrl;
|
||||
use uv_python::EnvironmentPreference;
|
||||
use uv_python::PythonRequest;
|
||||
use uv_python::{EnvironmentPreference, PythonPreference};
|
||||
use uv_python::{Prefix, PythonEnvironment, Target};
|
||||
use uv_requirements::{RequirementsSource, RequirementsSpecification};
|
||||
|
||||
|
|
@ -58,6 +58,7 @@ pub(crate) async fn pip_uninstall(
|
|||
.map(PythonRequest::parse)
|
||||
.unwrap_or_default(),
|
||||
EnvironmentPreference::from_system_flag(system, true),
|
||||
PythonPreference::default().with_system_flag(system),
|
||||
&cache,
|
||||
preview,
|
||||
)?;
|
||||
|
|
|
|||
Loading…
Reference in New Issue