mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 13:25:00 +00:00
Allow configuring the toolchain fetch strategy (#4601)
Adds a `toolchain-fetch` option alongside `toolchain-preference` with `automatic` (default) and `manual` values allowing automatic toolchain fetches to be disabled (replaces https://github.com/astral-sh/uv/pull/4425). When `manual`, toolchains must be installed with `uv toolchain install`. Note this was previously implemented with `if-necessary`, `always`, `never` variants but the interaction between this and `toolchain-preference` was too confusing. By reducing to a binary option, things should be clearer. The `if-necessary` behavior moved to `toolchain-preference=installed`. See https://github.com/astral-sh/uv/pull/4601#discussion_r1657839633 and https://github.com/astral-sh/uv/pull/4601#discussion_r1658658755
This commit is contained in:
parent
ec2723a9f5
commit
6799cc883a
25 changed files with 219 additions and 89 deletions
|
@ -13,7 +13,7 @@ use uv_configuration::{
|
|||
};
|
||||
use uv_normalize::{ExtraName, PackageName};
|
||||
use uv_resolver::{AnnotationStyle, ExcludeNewer, PreReleaseMode, ResolutionMode};
|
||||
use uv_toolchain::{PythonVersion, ToolchainPreference};
|
||||
use uv_toolchain::{PythonVersion, ToolchainFetch, ToolchainPreference};
|
||||
|
||||
pub mod compat;
|
||||
pub mod options;
|
||||
|
@ -118,10 +118,14 @@ pub struct GlobalArgs {
|
|||
#[arg(global = true, long, overrides_with("offline"), hide = true)]
|
||||
pub no_offline: bool,
|
||||
|
||||
/// Whether to use system or uv-managed Python toolchains.
|
||||
/// Whether to prefer Python toolchains from uv or on the system.
|
||||
#[arg(global = true, long)]
|
||||
pub toolchain_preference: Option<ToolchainPreference>,
|
||||
|
||||
/// Whether to automatically download Python toolchains when required.
|
||||
#[arg(global = true, long)]
|
||||
pub toolchain_fetch: Option<ToolchainFetch>,
|
||||
|
||||
/// Whether to enable experimental, preview features.
|
||||
#[arg(global = true, long, hide = true, env = "UV_PREVIEW", value_parser = clap::builder::BoolishValueParser::new(), overrides_with("no_preview"))]
|
||||
pub preview: bool,
|
||||
|
|
|
@ -5,7 +5,7 @@ use distribution_types::IndexUrl;
|
|||
use install_wheel_rs::linker::LinkMode;
|
||||
use uv_configuration::{ConfigSettings, IndexStrategy, KeyringProviderType, TargetTriple};
|
||||
use uv_resolver::{AnnotationStyle, ExcludeNewer, PreReleaseMode, ResolutionMode};
|
||||
use uv_toolchain::{PythonVersion, ToolchainPreference};
|
||||
use uv_toolchain::{PythonVersion, ToolchainFetch, ToolchainPreference};
|
||||
|
||||
use crate::{FilesystemOptions, PipOptions};
|
||||
|
||||
|
@ -70,6 +70,7 @@ impl_combine_or!(ResolutionMode);
|
|||
impl_combine_or!(String);
|
||||
impl_combine_or!(TargetTriple);
|
||||
impl_combine_or!(ToolchainPreference);
|
||||
impl_combine_or!(ToolchainFetch);
|
||||
impl_combine_or!(bool);
|
||||
|
||||
impl<T> Combine for Option<Vec<T>> {
|
||||
|
|
|
@ -11,7 +11,7 @@ use uv_configuration::{
|
|||
use uv_macros::CombineOptions;
|
||||
use uv_normalize::{ExtraName, PackageName};
|
||||
use uv_resolver::{AnnotationStyle, ExcludeNewer, PreReleaseMode, ResolutionMode};
|
||||
use uv_toolchain::{PythonVersion, ToolchainPreference};
|
||||
use uv_toolchain::{PythonVersion, ToolchainFetch, ToolchainPreference};
|
||||
|
||||
/// A `pyproject.toml` with an (optional) `[tool.uv]` section.
|
||||
#[allow(dead_code)]
|
||||
|
@ -60,6 +60,7 @@ pub struct GlobalOptions {
|
|||
pub cache_dir: Option<PathBuf>,
|
||||
pub preview: Option<bool>,
|
||||
pub toolchain_preference: Option<ToolchainPreference>,
|
||||
pub toolchain_fetch: Option<ToolchainFetch>,
|
||||
}
|
||||
|
||||
/// Settings relevant to all installer operations.
|
||||
|
|
|
@ -57,20 +57,31 @@ pub enum ToolchainRequest {
|
|||
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub enum ToolchainPreference {
|
||||
/// Only use managed interpreters, never use system interpreters.
|
||||
/// Only use managed toolchains, never use system toolchains.
|
||||
OnlyManaged,
|
||||
/// Prefer installed managed interpreters, but use system interpreters if not found.
|
||||
/// If neither can be found, download a managed interpreter.
|
||||
/// Prefer installed toolchains, only download managed toolchains if no system toolchain is found.
|
||||
#[default]
|
||||
PreferInstalledManaged,
|
||||
/// Prefer managed interpreters, even if one needs to be downloaded, but use system interpreters if found.
|
||||
Installed,
|
||||
/// Prefer managed toolchains over system toolchains, even if one needs to be downloaded.
|
||||
PreferManaged,
|
||||
/// Prefer system interpreters, only use managed interpreters if no system interpreter is found.
|
||||
/// Prefer system toolchains, only use managed toolchains if no system toolchain is found.
|
||||
PreferSystem,
|
||||
/// Only use system interpreters, never use managed interpreters.
|
||||
/// Only use system toolchains, never use managed toolchains.
|
||||
OnlySystem,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, serde::Deserialize)]
|
||||
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
|
||||
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub enum ToolchainFetch {
|
||||
/// Automatically fetch managed toolchains when needed.
|
||||
#[default]
|
||||
Automatic,
|
||||
/// Do not automatically fetch managed toolchains; require explicit installation.
|
||||
Manual,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
||||
pub enum EnvironmentPreference {
|
||||
/// Only use virtual environments, never allow a system environment.
|
||||
|
@ -302,12 +313,7 @@ fn python_executables_from_installed<'a>(
|
|||
|
||||
match preference {
|
||||
ToolchainPreference::OnlyManaged => Box::new(from_managed_toolchains),
|
||||
ToolchainPreference::PreferInstalledManaged => Box::new(
|
||||
from_managed_toolchains
|
||||
.chain(from_search_path)
|
||||
.chain(from_py_launcher),
|
||||
),
|
||||
ToolchainPreference::PreferManaged => Box::new(
|
||||
ToolchainPreference::PreferManaged | ToolchainPreference::Installed => Box::new(
|
||||
from_managed_toolchains
|
||||
.chain(from_search_path)
|
||||
.chain(from_py_launcher),
|
||||
|
@ -1147,9 +1153,7 @@ impl ToolchainPreference {
|
|||
|
||||
match self {
|
||||
ToolchainPreference::OnlyManaged => matches!(source, ToolchainSource::Managed),
|
||||
ToolchainPreference::PreferInstalledManaged
|
||||
| Self::PreferManaged
|
||||
| Self::PreferSystem => matches!(
|
||||
Self::PreferManaged | Self::PreferSystem | Self::Installed => matches!(
|
||||
source,
|
||||
ToolchainSource::Managed
|
||||
| ToolchainSource::SearchPath
|
||||
|
@ -1179,11 +1183,17 @@ impl ToolchainPreference {
|
|||
pub(crate) fn allows_managed(self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
Self::PreferManaged | Self::PreferInstalledManaged | Self::OnlyManaged
|
||||
Self::PreferManaged | Self::OnlyManaged | Self::Installed
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToolchainFetch {
|
||||
pub fn is_automatic(self) -> bool {
|
||||
matches!(self, Self::Automatic)
|
||||
}
|
||||
}
|
||||
|
||||
impl EnvironmentPreference {
|
||||
pub fn from_system_flag(system: bool, mutable: bool) -> Self {
|
||||
match (system, mutable) {
|
||||
|
@ -1481,7 +1491,7 @@ impl fmt::Display for ToolchainPreference {
|
|||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
let s = match self {
|
||||
Self::OnlyManaged => "managed toolchains",
|
||||
Self::PreferManaged | Self::PreferInstalledManaged | Self::PreferSystem => {
|
||||
Self::PreferManaged | Self::Installed | Self::PreferSystem => {
|
||||
if cfg!(windows) {
|
||||
"managed toolchains, system path, or `py` launcher"
|
||||
} else {
|
||||
|
|
|
@ -125,32 +125,38 @@ impl PythonDownloadRequest {
|
|||
self
|
||||
}
|
||||
|
||||
/// Construct a new [`PythonDownloadRequest`] from a [`ToolchainRequest`] if possible.
|
||||
///
|
||||
/// Returns [`None`] if the request kind is not compatible with a download, e.g., it is
|
||||
/// a request for a specific directory or executable name.
|
||||
pub fn try_from_request(request: &ToolchainRequest) -> Option<Self> {
|
||||
Self::from_request(request).ok()
|
||||
}
|
||||
|
||||
/// Construct a new [`PythonDownloadRequest`] from a [`ToolchainRequest`].
|
||||
pub fn from_request(request: ToolchainRequest) -> Result<Self, Error> {
|
||||
let result = match request {
|
||||
ToolchainRequest::Version(version) => Self::default().with_version(version),
|
||||
pub fn from_request(request: &ToolchainRequest) -> Result<Self, Error> {
|
||||
match request {
|
||||
ToolchainRequest::Version(version) => Ok(Self::default().with_version(version.clone())),
|
||||
ToolchainRequest::Implementation(implementation) => {
|
||||
Self::default().with_implementation(implementation)
|
||||
Ok(Self::default().with_implementation(*implementation))
|
||||
}
|
||||
ToolchainRequest::ImplementationVersion(implementation, version) => Self::default()
|
||||
.with_implementation(implementation)
|
||||
.with_version(version),
|
||||
ToolchainRequest::Key(request) => request,
|
||||
ToolchainRequest::Any => Self::default(),
|
||||
ToolchainRequest::ImplementationVersion(implementation, version) => Ok(Self::default()
|
||||
.with_implementation(*implementation)
|
||||
.with_version(version.clone())),
|
||||
ToolchainRequest::Key(request) => Ok(request.clone()),
|
||||
ToolchainRequest::Any => Ok(Self::default()),
|
||||
// We can't download a toolchain for these request kinds
|
||||
ToolchainRequest::Directory(_)
|
||||
| ToolchainRequest::ExecutableName(_)
|
||||
| ToolchainRequest::File(_) => {
|
||||
return Err(Error::InvalidRequestKind(request));
|
||||
}
|
||||
};
|
||||
Ok(result)
|
||||
| ToolchainRequest::File(_) => Err(Error::InvalidRequestKind(request.clone())),
|
||||
}
|
||||
}
|
||||
|
||||
/// Fill empty entries with default values.
|
||||
///
|
||||
/// Platform information is pulled from the environment.
|
||||
pub fn fill(mut self) -> Result<Self, Error> {
|
||||
#[must_use]
|
||||
pub fn fill(mut self) -> Self {
|
||||
if self.implementation.is_none() {
|
||||
self.implementation = Some(ImplementationName::CPython);
|
||||
}
|
||||
|
@ -163,7 +169,7 @@ impl PythonDownloadRequest {
|
|||
if self.libc.is_none() {
|
||||
self.libc = Some(Libc::from_env());
|
||||
}
|
||||
Ok(self)
|
||||
self
|
||||
}
|
||||
|
||||
/// Construct a new [`PythonDownloadRequest`] with platform information from the environment.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
use thiserror::Error;
|
||||
|
||||
pub use crate::discovery::{
|
||||
find_toolchains, EnvironmentPreference, Error as DiscoveryError, SystemPython,
|
||||
find_toolchains, EnvironmentPreference, Error as DiscoveryError, SystemPython, ToolchainFetch,
|
||||
ToolchainNotFound, ToolchainPreference, ToolchainRequest, ToolchainSource, VersionRequest,
|
||||
};
|
||||
pub use crate::environment::PythonEnvironment;
|
||||
|
|
|
@ -14,7 +14,9 @@ use crate::downloads::{DownloadResult, PythonDownload, PythonDownloadRequest};
|
|||
use crate::implementation::LenientImplementationName;
|
||||
use crate::managed::{InstalledToolchain, InstalledToolchains};
|
||||
use crate::platform::{Arch, Libc, Os};
|
||||
use crate::{Error, Interpreter, PythonVersion, ToolchainPreference, ToolchainSource};
|
||||
use crate::{
|
||||
Error, Interpreter, PythonVersion, ToolchainFetch, ToolchainPreference, ToolchainSource,
|
||||
};
|
||||
|
||||
/// A Python interpreter and accompanying tools.
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -79,18 +81,36 @@ impl Toolchain {
|
|||
request: Option<ToolchainRequest>,
|
||||
environments: EnvironmentPreference,
|
||||
preference: ToolchainPreference,
|
||||
client_builder: BaseClientBuilder<'a>,
|
||||
toolchain_fetch: ToolchainFetch,
|
||||
client_builder: &BaseClientBuilder<'a>,
|
||||
cache: &Cache,
|
||||
) -> Result<Self, Error> {
|
||||
let request = request.unwrap_or_default();
|
||||
// Perform a find first
|
||||
|
||||
// Perform a fetch aggressively if managed toolchains are preferred
|
||||
if matches!(preference, ToolchainPreference::PreferManaged)
|
||||
&& toolchain_fetch.is_automatic()
|
||||
{
|
||||
if let Some(request) = PythonDownloadRequest::try_from_request(&request) {
|
||||
return Self::fetch(request, client_builder, cache).await;
|
||||
}
|
||||
}
|
||||
|
||||
// Search for the toolchain
|
||||
match Self::find(&request, environments, preference, cache) {
|
||||
Ok(venv) => Ok(venv),
|
||||
Err(Error::MissingToolchain(_))
|
||||
if preference.allows_managed() && client_builder.connectivity.is_online() =>
|
||||
// If missing and allowed, perform a fetch
|
||||
err @ Err(Error::MissingToolchain(_))
|
||||
if preference.allows_managed()
|
||||
&& toolchain_fetch.is_automatic()
|
||||
&& client_builder.connectivity.is_online() =>
|
||||
{
|
||||
debug!("Requested Python not found, checking for available download...");
|
||||
Self::fetch(request, client_builder, cache).await
|
||||
if let Some(request) = PythonDownloadRequest::try_from_request(&request) {
|
||||
debug!("Requested Python not found, checking for available download...");
|
||||
Self::fetch(request, client_builder, cache).await
|
||||
} else {
|
||||
err
|
||||
}
|
||||
}
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
|
@ -98,14 +118,13 @@ impl Toolchain {
|
|||
|
||||
/// Download and install the requested toolchain.
|
||||
pub async fn fetch<'a>(
|
||||
request: ToolchainRequest,
|
||||
client_builder: BaseClientBuilder<'a>,
|
||||
request: PythonDownloadRequest,
|
||||
client_builder: &BaseClientBuilder<'a>,
|
||||
cache: &Cache,
|
||||
) -> Result<Self, Error> {
|
||||
let toolchains = InstalledToolchains::from_settings()?.init()?;
|
||||
let toolchain_dir = toolchains.root();
|
||||
|
||||
let request = PythonDownloadRequest::from_request(request)?.fill()?;
|
||||
let download = PythonDownload::from_request(&request)?;
|
||||
let client = client_builder.build();
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ use uv_git::GitResolver;
|
|||
use uv_normalize::PackageName;
|
||||
use uv_requirements::{NamedRequirementsResolver, RequirementsSource, RequirementsSpecification};
|
||||
use uv_resolver::{FlatIndex, InMemoryIndex};
|
||||
use uv_toolchain::{ToolchainPreference, ToolchainRequest};
|
||||
use uv_toolchain::{ToolchainFetch, ToolchainPreference, ToolchainRequest};
|
||||
use uv_types::{BuildIsolation, HashStrategy, InFlight};
|
||||
use uv_warnings::warn_user_once;
|
||||
|
||||
|
@ -39,6 +39,7 @@ pub(crate) async fn add(
|
|||
python: Option<String>,
|
||||
settings: ResolverInstallerSettings,
|
||||
toolchain_preference: ToolchainPreference,
|
||||
toolchain_fetch: ToolchainFetch,
|
||||
preview: PreviewMode,
|
||||
connectivity: Connectivity,
|
||||
concurrency: Concurrency,
|
||||
|
@ -65,6 +66,7 @@ pub(crate) async fn add(
|
|||
project.workspace(),
|
||||
python.as_deref().map(ToolchainRequest::parse),
|
||||
toolchain_preference,
|
||||
toolchain_fetch,
|
||||
connectivity,
|
||||
native_tls,
|
||||
cache,
|
||||
|
|
|
@ -11,7 +11,7 @@ use uv_distribution::{Workspace, DEV_DEPENDENCIES};
|
|||
use uv_git::ResolvedRepositoryReference;
|
||||
use uv_requirements::upgrade::{read_lockfile, LockedRequirements};
|
||||
use uv_resolver::{FlatIndex, Lock, OptionsBuilder, PythonRequirement, RequiresPython};
|
||||
use uv_toolchain::{Interpreter, ToolchainPreference, ToolchainRequest};
|
||||
use uv_toolchain::{Interpreter, ToolchainFetch, ToolchainPreference, ToolchainRequest};
|
||||
use uv_types::{BuildIsolation, EmptyInstalledPackages, HashStrategy, InFlight};
|
||||
use uv_warnings::{warn_user, warn_user_once};
|
||||
|
||||
|
@ -26,6 +26,7 @@ pub(crate) async fn lock(
|
|||
settings: ResolverSettings,
|
||||
preview: PreviewMode,
|
||||
toolchain_preference: ToolchainPreference,
|
||||
toolchain_fetch: ToolchainFetch,
|
||||
connectivity: Connectivity,
|
||||
concurrency: Concurrency,
|
||||
native_tls: bool,
|
||||
|
@ -44,6 +45,7 @@ pub(crate) async fn lock(
|
|||
&workspace,
|
||||
python.as_deref().map(ToolchainRequest::parse),
|
||||
toolchain_preference,
|
||||
toolchain_fetch,
|
||||
connectivity,
|
||||
native_tls,
|
||||
cache,
|
||||
|
|
|
@ -19,7 +19,7 @@ use uv_requirements::{NamedRequirementsResolver, RequirementsSpecification};
|
|||
use uv_resolver::{FlatIndex, InMemoryIndex, OptionsBuilder, PythonRequirement, RequiresPython};
|
||||
use uv_toolchain::{
|
||||
request_from_version_file, EnvironmentPreference, Interpreter, PythonEnvironment, Toolchain,
|
||||
ToolchainPreference, ToolchainRequest, VersionRequest,
|
||||
ToolchainFetch, ToolchainPreference, ToolchainRequest, VersionRequest,
|
||||
};
|
||||
use uv_types::{BuildIsolation, HashStrategy, InFlight};
|
||||
|
||||
|
@ -127,6 +127,7 @@ impl FoundInterpreter {
|
|||
workspace: &Workspace,
|
||||
python_request: Option<ToolchainRequest>,
|
||||
toolchain_preference: ToolchainPreference,
|
||||
toolchain_fetch: ToolchainFetch,
|
||||
connectivity: Connectivity,
|
||||
native_tls: bool,
|
||||
cache: &Cache,
|
||||
|
@ -183,7 +184,8 @@ impl FoundInterpreter {
|
|||
python_request,
|
||||
EnvironmentPreference::OnlySystem,
|
||||
toolchain_preference,
|
||||
client_builder,
|
||||
toolchain_fetch,
|
||||
&client_builder,
|
||||
cache,
|
||||
)
|
||||
.await?
|
||||
|
@ -222,6 +224,7 @@ pub(crate) async fn get_or_init_environment(
|
|||
workspace: &Workspace,
|
||||
python: Option<ToolchainRequest>,
|
||||
toolchain_preference: ToolchainPreference,
|
||||
toolchain_fetch: ToolchainFetch,
|
||||
connectivity: Connectivity,
|
||||
native_tls: bool,
|
||||
cache: &Cache,
|
||||
|
@ -231,6 +234,7 @@ pub(crate) async fn get_or_init_environment(
|
|||
workspace,
|
||||
python,
|
||||
toolchain_preference,
|
||||
toolchain_fetch,
|
||||
connectivity,
|
||||
native_tls,
|
||||
cache,
|
||||
|
|
|
@ -7,7 +7,7 @@ use uv_configuration::{Concurrency, ExtrasSpecification, PreviewMode};
|
|||
use uv_distribution::pyproject::DependencyType;
|
||||
use uv_distribution::pyproject_mut::PyProjectTomlMut;
|
||||
use uv_distribution::{ProjectWorkspace, VirtualProject, Workspace};
|
||||
use uv_toolchain::{ToolchainPreference, ToolchainRequest};
|
||||
use uv_toolchain::{ToolchainFetch, ToolchainPreference, ToolchainRequest};
|
||||
use uv_warnings::{warn_user, warn_user_once};
|
||||
|
||||
use crate::commands::pip::operations::Modifications;
|
||||
|
@ -23,6 +23,7 @@ pub(crate) async fn remove(
|
|||
package: Option<PackageName>,
|
||||
python: Option<String>,
|
||||
toolchain_preference: ToolchainPreference,
|
||||
toolchain_fetch: ToolchainFetch,
|
||||
preview: PreviewMode,
|
||||
connectivity: Connectivity,
|
||||
concurrency: Concurrency,
|
||||
|
@ -86,6 +87,7 @@ pub(crate) async fn remove(
|
|||
project.workspace(),
|
||||
python.as_deref().map(ToolchainRequest::parse),
|
||||
toolchain_preference,
|
||||
toolchain_fetch,
|
||||
connectivity,
|
||||
native_tls,
|
||||
cache,
|
||||
|
|
|
@ -16,7 +16,7 @@ use uv_normalize::PackageName;
|
|||
use uv_requirements::{RequirementsSource, RequirementsSpecification};
|
||||
use uv_toolchain::{
|
||||
request_from_version_file, EnvironmentPreference, Interpreter, PythonEnvironment, Toolchain,
|
||||
ToolchainPreference, ToolchainRequest, VersionRequest,
|
||||
ToolchainFetch, ToolchainPreference, ToolchainRequest, VersionRequest,
|
||||
};
|
||||
use uv_warnings::warn_user_once;
|
||||
|
||||
|
@ -38,6 +38,7 @@ pub(crate) async fn run(
|
|||
isolated: bool,
|
||||
preview: PreviewMode,
|
||||
toolchain_preference: ToolchainPreference,
|
||||
toolchain_fetch: ToolchainFetch,
|
||||
connectivity: Connectivity,
|
||||
concurrency: Concurrency,
|
||||
native_tls: bool,
|
||||
|
@ -89,7 +90,8 @@ pub(crate) async fn run(
|
|||
python_request,
|
||||
EnvironmentPreference::Any,
|
||||
toolchain_preference,
|
||||
client_builder,
|
||||
toolchain_fetch,
|
||||
&client_builder,
|
||||
cache,
|
||||
)
|
||||
.await?
|
||||
|
@ -170,6 +172,7 @@ pub(crate) async fn run(
|
|||
project.workspace(),
|
||||
python.as_deref().map(ToolchainRequest::parse),
|
||||
toolchain_preference,
|
||||
toolchain_fetch,
|
||||
connectivity,
|
||||
native_tls,
|
||||
cache,
|
||||
|
@ -222,7 +225,8 @@ pub(crate) async fn run(
|
|||
// No opt-in is required for system environments, since we are not mutating it.
|
||||
EnvironmentPreference::Any,
|
||||
toolchain_preference,
|
||||
client_builder,
|
||||
toolchain_fetch,
|
||||
&client_builder,
|
||||
cache,
|
||||
)
|
||||
.await?;
|
||||
|
@ -261,7 +265,8 @@ pub(crate) async fn run(
|
|||
python.as_deref().map(ToolchainRequest::parse),
|
||||
EnvironmentPreference::Any,
|
||||
toolchain_preference,
|
||||
client_builder,
|
||||
toolchain_fetch,
|
||||
&client_builder,
|
||||
cache,
|
||||
)
|
||||
.await?
|
||||
|
|
|
@ -7,7 +7,7 @@ use uv_dispatch::BuildDispatch;
|
|||
use uv_distribution::{VirtualProject, DEV_DEPENDENCIES};
|
||||
use uv_installer::SitePackages;
|
||||
use uv_resolver::{FlatIndex, Lock};
|
||||
use uv_toolchain::{PythonEnvironment, ToolchainPreference, ToolchainRequest};
|
||||
use uv_toolchain::{PythonEnvironment, ToolchainFetch, ToolchainPreference, ToolchainRequest};
|
||||
use uv_types::{BuildIsolation, HashStrategy, InFlight};
|
||||
use uv_warnings::warn_user_once;
|
||||
|
||||
|
@ -24,6 +24,7 @@ pub(crate) async fn sync(
|
|||
modifications: Modifications,
|
||||
python: Option<String>,
|
||||
toolchain_preference: ToolchainPreference,
|
||||
toolchain_fetch: ToolchainFetch,
|
||||
settings: InstallerSettings,
|
||||
preview: PreviewMode,
|
||||
connectivity: Connectivity,
|
||||
|
@ -44,6 +45,7 @@ pub(crate) async fn sync(
|
|||
project.workspace(),
|
||||
python.as_deref().map(ToolchainRequest::parse),
|
||||
toolchain_preference,
|
||||
toolchain_fetch,
|
||||
connectivity,
|
||||
native_tls,
|
||||
cache,
|
||||
|
|
|
@ -20,7 +20,8 @@ use uv_normalize::PackageName;
|
|||
use uv_requirements::RequirementsSpecification;
|
||||
use uv_tool::{entrypoint_paths, find_executable_directory, InstalledTools, Tool, ToolEntrypoint};
|
||||
use uv_toolchain::{
|
||||
EnvironmentPreference, Interpreter, Toolchain, ToolchainPreference, ToolchainRequest,
|
||||
EnvironmentPreference, Interpreter, Toolchain, ToolchainFetch, ToolchainPreference,
|
||||
ToolchainRequest,
|
||||
};
|
||||
use uv_warnings::warn_user_once;
|
||||
|
||||
|
@ -39,6 +40,7 @@ pub(crate) async fn install(
|
|||
settings: ResolverInstallerSettings,
|
||||
preview: PreviewMode,
|
||||
toolchain_preference: ToolchainPreference,
|
||||
_toolchain_fetch: ToolchainFetch,
|
||||
connectivity: Connectivity,
|
||||
concurrency: Concurrency,
|
||||
native_tls: bool,
|
||||
|
@ -49,6 +51,7 @@ pub(crate) async fn install(
|
|||
warn_user_once!("`uv tool install` is experimental and may change without warning.");
|
||||
}
|
||||
|
||||
// TODO(zanieb): Use `find_or_fetch` here
|
||||
let interpreter = Toolchain::find(
|
||||
&python
|
||||
.as_deref()
|
||||
|
|
|
@ -16,7 +16,8 @@ use uv_configuration::{Concurrency, PreviewMode};
|
|||
use uv_normalize::PackageName;
|
||||
use uv_requirements::{RequirementsSource, RequirementsSpecification};
|
||||
use uv_toolchain::{
|
||||
EnvironmentPreference, PythonEnvironment, Toolchain, ToolchainPreference, ToolchainRequest,
|
||||
EnvironmentPreference, PythonEnvironment, Toolchain, ToolchainFetch, ToolchainPreference,
|
||||
ToolchainRequest,
|
||||
};
|
||||
use uv_warnings::warn_user_once;
|
||||
|
||||
|
@ -35,6 +36,7 @@ pub(crate) async fn run(
|
|||
_isolated: bool,
|
||||
preview: PreviewMode,
|
||||
toolchain_preference: ToolchainPreference,
|
||||
_toolchain_fetch: ToolchainFetch,
|
||||
connectivity: Connectivity,
|
||||
concurrency: Concurrency,
|
||||
native_tls: bool,
|
||||
|
@ -76,6 +78,7 @@ pub(crate) async fn run(
|
|||
|
||||
// Discover an interpreter.
|
||||
// Note we force preview on during `uv tool run` for now since the entire interface is in preview
|
||||
// TODO(zanieb): We should use `find_or_fetch` here
|
||||
let interpreter = Toolchain::find(
|
||||
&python
|
||||
.as_deref()
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use anyhow::Result;
|
||||
use futures::StreamExt;
|
||||
use itertools::Itertools;
|
||||
use std::fmt::Write;
|
||||
use uv_cache::Cache;
|
||||
use uv_client::Connectivity;
|
||||
|
@ -48,7 +47,7 @@ pub(crate) async fn install(
|
|||
|
||||
let download_requests = requests
|
||||
.iter()
|
||||
.map(|request| PythonDownloadRequest::from_request(request.clone()))
|
||||
.map(PythonDownloadRequest::from_request)
|
||||
.collect::<Result<Vec<_>, downloads::Error>>()?;
|
||||
|
||||
let installed_toolchains: Vec<_> = toolchains.find_all()?.collect();
|
||||
|
@ -105,8 +104,7 @@ pub(crate) async fn install(
|
|||
.into_iter()
|
||||
// Populate the download requests with defaults
|
||||
.map(PythonDownloadRequest::fill)
|
||||
.map(|request| request.map(|inner| PythonDownload::from_request(&inner)))
|
||||
.flatten_ok()
|
||||
.map(|request| PythonDownload::from_request(&request))
|
||||
.collect::<Result<Vec<_>, uv_toolchain::downloads::Error>>()?;
|
||||
|
||||
// Construct a client
|
||||
|
|
|
@ -8,8 +8,8 @@ use uv_configuration::PreviewMode;
|
|||
use uv_fs::Simplified;
|
||||
use uv_toolchain::downloads::PythonDownloadRequest;
|
||||
use uv_toolchain::{
|
||||
find_toolchains, DiscoveryError, EnvironmentPreference, Toolchain, ToolchainNotFound,
|
||||
ToolchainPreference, ToolchainRequest, ToolchainSource,
|
||||
find_toolchains, DiscoveryError, EnvironmentPreference, Toolchain, ToolchainFetch,
|
||||
ToolchainNotFound, ToolchainPreference, ToolchainRequest, ToolchainSource,
|
||||
};
|
||||
use uv_warnings::warn_user_once;
|
||||
|
||||
|
@ -25,11 +25,13 @@ enum Kind {
|
|||
}
|
||||
|
||||
/// List available toolchains.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) async fn list(
|
||||
kinds: ToolchainListKinds,
|
||||
all_versions: bool,
|
||||
all_platforms: bool,
|
||||
toolchain_preference: ToolchainPreference,
|
||||
toolchain_fetch: ToolchainFetch,
|
||||
preview: PreviewMode,
|
||||
cache: &Cache,
|
||||
printer: Printer,
|
||||
|
@ -40,11 +42,18 @@ pub(crate) async fn list(
|
|||
|
||||
let download_request = match kinds {
|
||||
ToolchainListKinds::Installed => None,
|
||||
ToolchainListKinds::Default => Some(if all_platforms {
|
||||
PythonDownloadRequest::default()
|
||||
} else {
|
||||
PythonDownloadRequest::from_env()?
|
||||
}),
|
||||
ToolchainListKinds::Default => {
|
||||
if toolchain_fetch.is_automatic() {
|
||||
Some(if all_platforms {
|
||||
PythonDownloadRequest::default()
|
||||
} else {
|
||||
PythonDownloadRequest::from_env()?
|
||||
})
|
||||
} else {
|
||||
// If fetching is not automatic, then don't show downloads as available by default
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let downloads = download_request
|
||||
|
|
|
@ -24,8 +24,8 @@ use uv_fs::Simplified;
|
|||
use uv_git::GitResolver;
|
||||
use uv_resolver::{ExcludeNewer, FlatIndex, InMemoryIndex};
|
||||
use uv_toolchain::{
|
||||
request_from_version_file, EnvironmentPreference, Toolchain, ToolchainPreference,
|
||||
ToolchainRequest,
|
||||
request_from_version_file, EnvironmentPreference, Toolchain, ToolchainFetch,
|
||||
ToolchainPreference, ToolchainRequest,
|
||||
};
|
||||
use uv_types::{BuildContext, BuildIsolation, HashStrategy, InFlight};
|
||||
|
||||
|
@ -43,6 +43,7 @@ pub(crate) async fn venv(
|
|||
path: &Path,
|
||||
python_request: Option<&str>,
|
||||
toolchain_preference: ToolchainPreference,
|
||||
toolchain_fetch: ToolchainFetch,
|
||||
link_mode: LinkMode,
|
||||
index_locations: &IndexLocations,
|
||||
index_strategy: IndexStrategy,
|
||||
|
@ -71,6 +72,7 @@ pub(crate) async fn venv(
|
|||
seed,
|
||||
preview,
|
||||
toolchain_preference,
|
||||
toolchain_fetch,
|
||||
allow_existing,
|
||||
exclude_newer,
|
||||
native_tls,
|
||||
|
@ -121,6 +123,7 @@ async fn venv_impl(
|
|||
seed: bool,
|
||||
preview: PreviewMode,
|
||||
toolchain_preference: ToolchainPreference,
|
||||
toolchain_fetch: ToolchainFetch,
|
||||
allow_existing: bool,
|
||||
exclude_newer: Option<ExcludeNewer>,
|
||||
native_tls: bool,
|
||||
|
@ -141,7 +144,8 @@ async fn venv_impl(
|
|||
interpreter_request,
|
||||
EnvironmentPreference::OnlySystem,
|
||||
toolchain_preference,
|
||||
client_builder,
|
||||
toolchain_fetch,
|
||||
&client_builder,
|
||||
cache,
|
||||
)
|
||||
.await
|
||||
|
|
|
@ -617,6 +617,7 @@ async fn run() -> Result<ExitStatus> {
|
|||
&args.name,
|
||||
args.settings.python.as_deref(),
|
||||
globals.toolchain_preference,
|
||||
globals.toolchain_fetch,
|
||||
args.settings.link_mode,
|
||||
&args.settings.index_locations,
|
||||
args.settings.index_strategy,
|
||||
|
@ -659,6 +660,7 @@ async fn run() -> Result<ExitStatus> {
|
|||
globals.isolated,
|
||||
globals.preview,
|
||||
globals.toolchain_preference,
|
||||
globals.toolchain_fetch,
|
||||
globals.connectivity,
|
||||
Concurrency::default(),
|
||||
globals.native_tls,
|
||||
|
@ -681,6 +683,7 @@ async fn run() -> Result<ExitStatus> {
|
|||
args.modifications,
|
||||
args.python,
|
||||
globals.toolchain_preference,
|
||||
globals.toolchain_fetch,
|
||||
args.settings,
|
||||
globals.preview,
|
||||
globals.connectivity,
|
||||
|
@ -704,6 +707,7 @@ async fn run() -> Result<ExitStatus> {
|
|||
args.settings,
|
||||
globals.preview,
|
||||
globals.toolchain_preference,
|
||||
globals.toolchain_fetch,
|
||||
globals.connectivity,
|
||||
Concurrency::default(),
|
||||
globals.native_tls,
|
||||
|
@ -733,6 +737,7 @@ async fn run() -> Result<ExitStatus> {
|
|||
args.python,
|
||||
args.settings,
|
||||
globals.toolchain_preference,
|
||||
globals.toolchain_fetch,
|
||||
globals.preview,
|
||||
globals.connectivity,
|
||||
Concurrency::default(),
|
||||
|
@ -756,6 +761,7 @@ async fn run() -> Result<ExitStatus> {
|
|||
args.package,
|
||||
args.python,
|
||||
globals.toolchain_preference,
|
||||
globals.toolchain_fetch,
|
||||
globals.preview,
|
||||
globals.connectivity,
|
||||
Concurrency::default(),
|
||||
|
@ -796,6 +802,7 @@ async fn run() -> Result<ExitStatus> {
|
|||
globals.isolated,
|
||||
globals.preview,
|
||||
globals.toolchain_preference,
|
||||
globals.toolchain_fetch,
|
||||
globals.connectivity,
|
||||
Concurrency::default(),
|
||||
globals.native_tls,
|
||||
|
@ -823,6 +830,7 @@ async fn run() -> Result<ExitStatus> {
|
|||
args.settings,
|
||||
globals.preview,
|
||||
globals.toolchain_preference,
|
||||
globals.toolchain_fetch,
|
||||
globals.connectivity,
|
||||
Concurrency::default(),
|
||||
globals.native_tls,
|
||||
|
@ -870,6 +878,7 @@ async fn run() -> Result<ExitStatus> {
|
|||
args.all_versions,
|
||||
args.all_platforms,
|
||||
globals.toolchain_preference,
|
||||
globals.toolchain_fetch,
|
||||
globals.preview,
|
||||
&cache,
|
||||
printer,
|
||||
|
|
|
@ -31,7 +31,7 @@ use uv_settings::{
|
|||
Combine, FilesystemOptions, InstallerOptions, Options, PipOptions, ResolverInstallerOptions,
|
||||
ResolverOptions,
|
||||
};
|
||||
use uv_toolchain::{Prefix, PythonVersion, Target, ToolchainPreference};
|
||||
use uv_toolchain::{Prefix, PythonVersion, Target, ToolchainFetch, ToolchainPreference};
|
||||
|
||||
use crate::commands::pip::operations::Modifications;
|
||||
|
||||
|
@ -48,6 +48,7 @@ pub(crate) struct GlobalSettings {
|
|||
pub(crate) show_settings: bool,
|
||||
pub(crate) preview: PreviewMode,
|
||||
pub(crate) toolchain_preference: ToolchainPreference,
|
||||
pub(crate) toolchain_fetch: ToolchainFetch,
|
||||
}
|
||||
|
||||
impl GlobalSettings {
|
||||
|
@ -114,6 +115,10 @@ impl GlobalSettings {
|
|||
.toolchain_preference
|
||||
.combine(workspace.and_then(|workspace| workspace.globals.toolchain_preference))
|
||||
.unwrap_or(default_toolchain_preference),
|
||||
toolchain_fetch: args
|
||||
.toolchain_fetch
|
||||
.combine(workspace.and_then(|workspace| workspace.globals.toolchain_fetch))
|
||||
.unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -711,7 +711,7 @@ pub fn python_toolchains_for_versions(
|
|||
if let Ok(toolchain) = Toolchain::find(
|
||||
&ToolchainRequest::parse(python_version),
|
||||
EnvironmentPreference::OnlySystem,
|
||||
ToolchainPreference::PreferInstalledManaged,
|
||||
ToolchainPreference::PreferManaged,
|
||||
&cache,
|
||||
) {
|
||||
toolchain.into_interpreter().sys_executable().to_owned()
|
||||
|
|
|
@ -2039,8 +2039,8 @@ fn lock_requires_python() -> Result<()> {
|
|||
.collect();
|
||||
|
||||
// Install from the lockfile.
|
||||
// Note we need `--offline` otherwise we'll just fetch a 3.12 interpreter!
|
||||
uv_snapshot!(filters, context38.sync().arg("--offline"), @r###"
|
||||
// Note we need to disable toolchain fetches or we'll just download 3.12
|
||||
uv_snapshot!(filters, context38.sync().arg("--toolchain-fetch").arg("manual"), @r###"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
|
|
@ -448,7 +448,6 @@ fn prune() {
|
|||
└── threadpoolctl v3.4.0
|
||||
|
||||
----- stderr -----
|
||||
|
||||
"###
|
||||
);
|
||||
|
||||
|
@ -472,7 +471,6 @@ fn prune() {
|
|||
└── threadpoolctl v3.4.0
|
||||
|
||||
----- stderr -----
|
||||
|
||||
"###
|
||||
);
|
||||
|
||||
|
@ -495,7 +493,6 @@ fn prune() {
|
|||
└── threadpoolctl v3.4.0
|
||||
|
||||
----- stderr -----
|
||||
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
@ -1350,7 +1347,6 @@ fn with_editable() {
|
|||
└── iniconfig v2.0.1.dev6+g9cae431
|
||||
|
||||
----- stderr -----
|
||||
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
|||
show_settings: true,
|
||||
preview: Disabled,
|
||||
toolchain_preference: OnlySystem,
|
||||
toolchain_fetch: Automatic,
|
||||
}
|
||||
CacheSettings {
|
||||
no_cache: false,
|
||||
|
@ -188,6 +189,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
|||
show_settings: true,
|
||||
preview: Disabled,
|
||||
toolchain_preference: OnlySystem,
|
||||
toolchain_fetch: Automatic,
|
||||
}
|
||||
CacheSettings {
|
||||
no_cache: false,
|
||||
|
@ -319,6 +321,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
|||
show_settings: true,
|
||||
preview: Disabled,
|
||||
toolchain_preference: OnlySystem,
|
||||
toolchain_fetch: Automatic,
|
||||
}
|
||||
CacheSettings {
|
||||
no_cache: false,
|
||||
|
@ -482,6 +485,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
|||
show_settings: true,
|
||||
preview: Disabled,
|
||||
toolchain_preference: OnlySystem,
|
||||
toolchain_fetch: Automatic,
|
||||
}
|
||||
CacheSettings {
|
||||
no_cache: false,
|
||||
|
@ -614,6 +618,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
|||
show_settings: true,
|
||||
preview: Disabled,
|
||||
toolchain_preference: OnlySystem,
|
||||
toolchain_fetch: Automatic,
|
||||
}
|
||||
CacheSettings {
|
||||
no_cache: false,
|
||||
|
@ -732,6 +737,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
|||
show_settings: true,
|
||||
preview: Disabled,
|
||||
toolchain_preference: OnlySystem,
|
||||
toolchain_fetch: Automatic,
|
||||
}
|
||||
CacheSettings {
|
||||
no_cache: false,
|
||||
|
@ -887,6 +893,7 @@ fn resolve_index_url() -> anyhow::Result<()> {
|
|||
show_settings: true,
|
||||
preview: Disabled,
|
||||
toolchain_preference: OnlySystem,
|
||||
toolchain_fetch: Automatic,
|
||||
}
|
||||
CacheSettings {
|
||||
no_cache: false,
|
||||
|
@ -1042,6 +1049,7 @@ fn resolve_index_url() -> anyhow::Result<()> {
|
|||
show_settings: true,
|
||||
preview: Disabled,
|
||||
toolchain_preference: OnlySystem,
|
||||
toolchain_fetch: Automatic,
|
||||
}
|
||||
CacheSettings {
|
||||
no_cache: false,
|
||||
|
@ -1242,6 +1250,7 @@ fn resolve_find_links() -> anyhow::Result<()> {
|
|||
show_settings: true,
|
||||
preview: Disabled,
|
||||
toolchain_preference: OnlySystem,
|
||||
toolchain_fetch: Automatic,
|
||||
}
|
||||
CacheSettings {
|
||||
no_cache: false,
|
||||
|
@ -1391,6 +1400,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
|||
show_settings: true,
|
||||
preview: Disabled,
|
||||
toolchain_preference: OnlySystem,
|
||||
toolchain_fetch: Automatic,
|
||||
}
|
||||
CacheSettings {
|
||||
no_cache: false,
|
||||
|
@ -1515,6 +1525,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
|||
show_settings: true,
|
||||
preview: Disabled,
|
||||
toolchain_preference: OnlySystem,
|
||||
toolchain_fetch: Automatic,
|
||||
}
|
||||
CacheSettings {
|
||||
no_cache: false,
|
||||
|
@ -1667,6 +1678,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
|||
show_settings: true,
|
||||
preview: Disabled,
|
||||
toolchain_preference: OnlySystem,
|
||||
toolchain_fetch: Automatic,
|
||||
}
|
||||
CacheSettings {
|
||||
no_cache: false,
|
||||
|
@ -1843,6 +1855,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
show_settings: true,
|
||||
preview: Disabled,
|
||||
toolchain_preference: OnlySystem,
|
||||
toolchain_fetch: Automatic,
|
||||
}
|
||||
CacheSettings {
|
||||
no_cache: false,
|
||||
|
@ -1957,6 +1970,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
show_settings: true,
|
||||
preview: Disabled,
|
||||
toolchain_preference: OnlySystem,
|
||||
toolchain_fetch: Automatic,
|
||||
}
|
||||
CacheSettings {
|
||||
no_cache: false,
|
||||
|
@ -2071,6 +2085,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
show_settings: true,
|
||||
preview: Disabled,
|
||||
toolchain_preference: OnlySystem,
|
||||
toolchain_fetch: Automatic,
|
||||
}
|
||||
CacheSettings {
|
||||
no_cache: false,
|
||||
|
@ -2187,6 +2202,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
show_settings: true,
|
||||
preview: Disabled,
|
||||
toolchain_preference: OnlySystem,
|
||||
toolchain_fetch: Automatic,
|
||||
}
|
||||
CacheSettings {
|
||||
no_cache: false,
|
||||
|
@ -2328,6 +2344,7 @@ fn resolve_poetry_toml() -> anyhow::Result<()> {
|
|||
show_settings: true,
|
||||
preview: Disabled,
|
||||
toolchain_preference: OnlySystem,
|
||||
toolchain_fetch: Automatic,
|
||||
}
|
||||
CacheSettings {
|
||||
no_cache: false,
|
||||
|
|
40
uv.schema.json
generated
40
uv.schema.json
generated
|
@ -235,6 +235,16 @@
|
|||
"$ref": "#/definitions/Source"
|
||||
}
|
||||
},
|
||||
"toolchain-fetch": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ToolchainFetch"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"toolchain-preference": {
|
||||
"anyOf": [
|
||||
{
|
||||
|
@ -1187,38 +1197,56 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"ToolchainFetch": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Automatically fetch managed toolchains when needed.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"automatic"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Do not automatically fetch managed toolchains; require explicit installation.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"manual"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"ToolchainPreference": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Only use managed interpreters, never use system interpreters.",
|
||||
"description": "Only use managed toolchains, never use system toolchains.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"only-managed"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Prefer installed managed interpreters, but use system interpreters if not found. If neither can be found, download a managed interpreter.",
|
||||
"description": "Prefer installed toolchains, only download managed toolchains if no system toolchain is found.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"prefer-installed-managed"
|
||||
"installed"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Prefer managed interpreters, even if one needs to be downloaded, but use system interpreters if found.",
|
||||
"description": "Prefer managed toolchains over system toolchains, even if one needs to be downloaded.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"prefer-managed"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Prefer system interpreters, only use managed interpreters if no system interpreter is found.",
|
||||
"description": "Prefer system toolchains, only use managed toolchains if no system toolchain is found.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"prefer-system"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Only use system interpreters, never use managed interpreters.",
|
||||
"description": "Only use system toolchains, never use managed toolchains.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"only-system"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue