mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-19 03:28:42 +00:00
Add UV_UPLOAD_HTTP_TIMEOUT and respect UV_HTTP_TIMEOUT in uploads (#16040)
## Summary - Move parsing `UV_HTTP_TIMEOUT`, `UV_REQUEST_TIMEOUT` and `HTTP_TIMEOUT` to `EnvironmentOptions` - Add new env varialbe `UV_UPLOAD_HTTP_TIMEOUT` Relates https://github.com/astral-sh/uv/issues/14720 ## Test Plan Tests with existing tests
This commit is contained in:
parent
84d6a913ac
commit
a58d031157
16 changed files with 243 additions and 62 deletions
|
|
@ -79,7 +79,7 @@ pub struct BaseClientBuilder<'a> {
|
||||||
platform: Option<&'a Platform>,
|
platform: Option<&'a Platform>,
|
||||||
auth_integration: AuthIntegration,
|
auth_integration: AuthIntegration,
|
||||||
indexes: Indexes,
|
indexes: Indexes,
|
||||||
default_timeout: Duration,
|
timeout: Duration,
|
||||||
extra_middleware: Option<ExtraMiddleware>,
|
extra_middleware: Option<ExtraMiddleware>,
|
||||||
proxies: Vec<Proxy>,
|
proxies: Vec<Proxy>,
|
||||||
redirect_policy: RedirectPolicy,
|
redirect_policy: RedirectPolicy,
|
||||||
|
|
@ -137,7 +137,7 @@ impl Default for BaseClientBuilder<'_> {
|
||||||
platform: None,
|
platform: None,
|
||||||
auth_integration: AuthIntegration::default(),
|
auth_integration: AuthIntegration::default(),
|
||||||
indexes: Indexes::new(),
|
indexes: Indexes::new(),
|
||||||
default_timeout: Duration::from_secs(30),
|
timeout: Duration::from_secs(30),
|
||||||
extra_middleware: None,
|
extra_middleware: None,
|
||||||
proxies: vec![],
|
proxies: vec![],
|
||||||
redirect_policy: RedirectPolicy::default(),
|
redirect_policy: RedirectPolicy::default(),
|
||||||
|
|
@ -153,12 +153,14 @@ impl BaseClientBuilder<'_> {
|
||||||
native_tls: bool,
|
native_tls: bool,
|
||||||
allow_insecure_host: Vec<TrustedHost>,
|
allow_insecure_host: Vec<TrustedHost>,
|
||||||
preview: Preview,
|
preview: Preview,
|
||||||
|
timeout: Duration,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
preview,
|
preview,
|
||||||
allow_insecure_host,
|
allow_insecure_host,
|
||||||
native_tls,
|
native_tls,
|
||||||
connectivity,
|
connectivity,
|
||||||
|
timeout,
|
||||||
..Self::default()
|
..Self::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -246,8 +248,8 @@ impl<'a> BaseClientBuilder<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn default_timeout(mut self, default_timeout: Duration) -> Self {
|
pub fn timeout(mut self, timeout: Duration) -> Self {
|
||||||
self.default_timeout = default_timeout;
|
self.timeout = timeout;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -299,21 +301,7 @@ impl<'a> BaseClientBuilder<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(&self) -> BaseClient {
|
pub fn build(&self) -> BaseClient {
|
||||||
// Timeout options, matching https://doc.rust-lang.org/nightly/cargo/reference/config.html#httptimeout
|
let timeout = self.timeout;
|
||||||
// `UV_REQUEST_TIMEOUT` is provided for backwards compatibility with v0.1.6
|
|
||||||
let timeout = env::var(EnvVars::UV_HTTP_TIMEOUT)
|
|
||||||
.or_else(|_| env::var(EnvVars::UV_REQUEST_TIMEOUT))
|
|
||||||
.or_else(|_| env::var(EnvVars::HTTP_TIMEOUT))
|
|
||||||
.and_then(|value| {
|
|
||||||
value.parse::<u64>()
|
|
||||||
.map(Duration::from_secs)
|
|
||||||
.or_else(|_| {
|
|
||||||
// On parse error, warn and use the default timeout
|
|
||||||
warn_user_once!("Ignoring invalid value from environment for `UV_HTTP_TIMEOUT`. Expected an integer number of seconds, got \"{value}\".");
|
|
||||||
Ok(self.default_timeout)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.unwrap_or(self.default_timeout);
|
|
||||||
debug!("Using request timeout of {}s", timeout.as_secs());
|
debug!("Using request timeout of {}s", timeout.as_secs());
|
||||||
|
|
||||||
// Use the custom client if provided, otherwise create a new one
|
// Use the custom client if provided, otherwise create a new one
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ use anyhow::Result;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
|
use uv_settings::EnvironmentOptions;
|
||||||
|
|
||||||
use crate::clear_compile::ClearCompileArgs;
|
use crate::clear_compile::ClearCompileArgs;
|
||||||
use crate::compile::CompileArgs;
|
use crate::compile::CompileArgs;
|
||||||
use crate::generate_all::Args as GenerateAllArgs;
|
use crate::generate_all::Args as GenerateAllArgs;
|
||||||
|
|
@ -61,9 +63,10 @@ enum Cli {
|
||||||
#[instrument] // Anchor span to check for overhead
|
#[instrument] // Anchor span to check for overhead
|
||||||
pub async fn run() -> Result<()> {
|
pub async fn run() -> Result<()> {
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
let environment = EnvironmentOptions::new()?;
|
||||||
match cli {
|
match cli {
|
||||||
Cli::WheelMetadata(args) => wheel_metadata::wheel_metadata(args).await?,
|
Cli::WheelMetadata(args) => wheel_metadata::wheel_metadata(args, environment).await?,
|
||||||
Cli::ValidateZip(args) => validate_zip::validate_zip(args).await?,
|
Cli::ValidateZip(args) => validate_zip::validate_zip(args, environment).await?,
|
||||||
Cli::Compile(args) => compile::compile(args).await?,
|
Cli::Compile(args) => compile::compile(args).await?,
|
||||||
Cli::ClearCompile(args) => clear_compile::clear_compile(&args)?,
|
Cli::ClearCompile(args) => clear_compile::clear_compile(&args)?,
|
||||||
Cli::GenerateAll(args) => generate_all::main(&args).await?,
|
Cli::GenerateAll(args) => generate_all::main(&args).await?,
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ use uv_cache::{Cache, CacheArgs};
|
||||||
use uv_client::{BaseClientBuilder, RegistryClientBuilder};
|
use uv_client::{BaseClientBuilder, RegistryClientBuilder};
|
||||||
use uv_pep508::VerbatimUrl;
|
use uv_pep508::VerbatimUrl;
|
||||||
use uv_pypi_types::ParsedUrl;
|
use uv_pypi_types::ParsedUrl;
|
||||||
|
use uv_settings::EnvironmentOptions;
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
pub(crate) struct ValidateZipArgs {
|
pub(crate) struct ValidateZipArgs {
|
||||||
|
|
@ -17,9 +18,16 @@ pub(crate) struct ValidateZipArgs {
|
||||||
cache_args: CacheArgs,
|
cache_args: CacheArgs,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn validate_zip(args: ValidateZipArgs) -> Result<()> {
|
pub(crate) async fn validate_zip(
|
||||||
|
args: ValidateZipArgs,
|
||||||
|
environment: EnvironmentOptions,
|
||||||
|
) -> Result<()> {
|
||||||
let cache = Cache::try_from(args.cache_args)?.init()?;
|
let cache = Cache::try_from(args.cache_args)?.init()?;
|
||||||
let client = RegistryClientBuilder::new(BaseClientBuilder::default(), cache).build();
|
let client = RegistryClientBuilder::new(
|
||||||
|
BaseClientBuilder::default().timeout(environment.http_timeout),
|
||||||
|
cache,
|
||||||
|
)
|
||||||
|
.build();
|
||||||
|
|
||||||
let ParsedUrl::Archive(archive) = ParsedUrl::try_from(args.url.to_url())? else {
|
let ParsedUrl::Archive(archive) = ParsedUrl::try_from(args.url.to_url())? else {
|
||||||
bail!("Only archive URLs are supported");
|
bail!("Only archive URLs are supported");
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ use uv_distribution_filename::WheelFilename;
|
||||||
use uv_distribution_types::{BuiltDist, DirectUrlBuiltDist, IndexCapabilities, RemoteSource};
|
use uv_distribution_types::{BuiltDist, DirectUrlBuiltDist, IndexCapabilities, RemoteSource};
|
||||||
use uv_pep508::VerbatimUrl;
|
use uv_pep508::VerbatimUrl;
|
||||||
use uv_pypi_types::ParsedUrl;
|
use uv_pypi_types::ParsedUrl;
|
||||||
|
use uv_settings::EnvironmentOptions;
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
pub(crate) struct WheelMetadataArgs {
|
pub(crate) struct WheelMetadataArgs {
|
||||||
|
|
@ -18,9 +19,16 @@ pub(crate) struct WheelMetadataArgs {
|
||||||
cache_args: CacheArgs,
|
cache_args: CacheArgs,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn wheel_metadata(args: WheelMetadataArgs) -> Result<()> {
|
pub(crate) async fn wheel_metadata(
|
||||||
|
args: WheelMetadataArgs,
|
||||||
|
environment: EnvironmentOptions,
|
||||||
|
) -> Result<()> {
|
||||||
let cache = Cache::try_from(args.cache_args)?.init()?;
|
let cache = Cache::try_from(args.cache_args)?.init()?;
|
||||||
let client = RegistryClientBuilder::new(BaseClientBuilder::default(), cache).build();
|
let client = RegistryClientBuilder::new(
|
||||||
|
BaseClientBuilder::default().timeout(environment.http_timeout),
|
||||||
|
cache,
|
||||||
|
)
|
||||||
|
.build();
|
||||||
let capabilities = IndexCapabilities::default();
|
let capabilities = IndexCapabilities::default();
|
||||||
|
|
||||||
let filename = WheelFilename::from_str(&args.url.filename()?)?;
|
let filename = WheelFilename::from_str(&args.url.filename()?)?;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use uv_dirs::{system_config_file, user_config_dir};
|
use uv_dirs::{system_config_file, user_config_dir};
|
||||||
use uv_flags::EnvironmentFlags;
|
use uv_flags::EnvironmentFlags;
|
||||||
|
|
@ -552,7 +553,8 @@ pub enum Error {
|
||||||
#[error("Failed to parse: `{}`", _0.user_display())]
|
#[error("Failed to parse: `{}`", _0.user_display())]
|
||||||
UvToml(PathBuf, #[source] Box<toml::de::Error>),
|
UvToml(PathBuf, #[source] Box<toml::de::Error>),
|
||||||
|
|
||||||
#[error("Failed to parse: `{}`. The `{}` field is not allowed in a `uv.toml` file. `{}` is only applicable in the context of a project, and should be placed in a `pyproject.toml` file instead.", _0.user_display(), _1, _1)]
|
#[error("Failed to parse: `{}`. The `{}` field is not allowed in a `uv.toml` file. `{}` is only applicable in the context of a project, and should be placed in a `pyproject.toml` file instead.", _0.user_display(), _1, _1
|
||||||
|
)]
|
||||||
PyprojectOnlyField(PathBuf, &'static str),
|
PyprojectOnlyField(PathBuf, &'static str),
|
||||||
|
|
||||||
#[error("Failed to parse environment variable `{name}` with invalid value `{value}`: {err}")]
|
#[error("Failed to parse environment variable `{name}` with invalid value `{value}`: {err}")]
|
||||||
|
|
@ -574,6 +576,8 @@ pub struct EnvironmentOptions {
|
||||||
pub python_install_registry: Option<bool>,
|
pub python_install_registry: Option<bool>,
|
||||||
pub install_mirrors: PythonInstallMirrors,
|
pub install_mirrors: PythonInstallMirrors,
|
||||||
pub log_context: Option<bool>,
|
pub log_context: Option<bool>,
|
||||||
|
pub http_timeout: Duration,
|
||||||
|
pub upload_http_timeout: Duration,
|
||||||
#[cfg(feature = "tracing-durations-export")]
|
#[cfg(feature = "tracing-durations-export")]
|
||||||
pub tracing_durations_file: Option<PathBuf>,
|
pub tracing_durations_file: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
@ -581,6 +585,15 @@ pub struct EnvironmentOptions {
|
||||||
impl EnvironmentOptions {
|
impl EnvironmentOptions {
|
||||||
/// Create a new [`EnvironmentOptions`] from environment variables.
|
/// Create a new [`EnvironmentOptions`] from environment variables.
|
||||||
pub fn new() -> Result<Self, Error> {
|
pub fn new() -> Result<Self, Error> {
|
||||||
|
// Timeout options, matching https://doc.rust-lang.org/nightly/cargo/reference/config.html#httptimeout
|
||||||
|
// `UV_REQUEST_TIMEOUT` is provided for backwards compatibility with v0.1.6
|
||||||
|
let http_timeout = parse_integer_environment_variable(EnvVars::UV_HTTP_TIMEOUT)?
|
||||||
|
.or(parse_integer_environment_variable(
|
||||||
|
EnvVars::UV_REQUEST_TIMEOUT,
|
||||||
|
)?)
|
||||||
|
.or(parse_integer_environment_variable(EnvVars::HTTP_TIMEOUT)?)
|
||||||
|
.map(Duration::from_secs);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
skip_wheel_filename_check: parse_boolish_environment_variable(
|
skip_wheel_filename_check: parse_boolish_environment_variable(
|
||||||
EnvVars::UV_SKIP_WHEEL_FILENAME_CHECK,
|
EnvVars::UV_SKIP_WHEEL_FILENAME_CHECK,
|
||||||
|
|
@ -601,6 +614,13 @@ impl EnvironmentOptions {
|
||||||
)?,
|
)?,
|
||||||
},
|
},
|
||||||
log_context: parse_boolish_environment_variable(EnvVars::UV_LOG_CONTEXT)?,
|
log_context: parse_boolish_environment_variable(EnvVars::UV_LOG_CONTEXT)?,
|
||||||
|
upload_http_timeout: parse_integer_environment_variable(
|
||||||
|
EnvVars::UV_UPLOAD_HTTP_TIMEOUT,
|
||||||
|
)?
|
||||||
|
.map(Duration::from_secs)
|
||||||
|
.or(http_timeout)
|
||||||
|
.unwrap_or(Duration::from_secs(15 * 60)),
|
||||||
|
http_timeout: http_timeout.unwrap_or(Duration::from_secs(30)),
|
||||||
#[cfg(feature = "tracing-durations-export")]
|
#[cfg(feature = "tracing-durations-export")]
|
||||||
tracing_durations_file: parse_path_environment_variable(
|
tracing_durations_file: parse_path_environment_variable(
|
||||||
EnvVars::TRACING_DURATIONS_FILE,
|
EnvVars::TRACING_DURATIONS_FILE,
|
||||||
|
|
@ -682,6 +702,34 @@ fn parse_string_environment_variable(name: &'static str) -> Result<Option<String
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parse a integer environment variable.
|
||||||
|
fn parse_integer_environment_variable(name: &'static str) -> Result<Option<u64>, Error> {
|
||||||
|
let value = match std::env::var(name) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(e) => {
|
||||||
|
return match e {
|
||||||
|
std::env::VarError::NotPresent => Ok(None),
|
||||||
|
std::env::VarError::NotUnicode(err) => Err(Error::InvalidEnvironmentVariable {
|
||||||
|
name: name.to_string(),
|
||||||
|
value: err.to_string_lossy().to_string(),
|
||||||
|
err: "expected an integer".to_string(),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if value.is_empty() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
match value.parse::<u64>() {
|
||||||
|
Ok(v) => Ok(Some(v)),
|
||||||
|
Err(_) => Err(Error::InvalidEnvironmentVariable {
|
||||||
|
name: name.to_string(),
|
||||||
|
value,
|
||||||
|
err: "expected an integer".to_string(),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "tracing-durations-export")]
|
#[cfg(feature = "tracing-durations-export")]
|
||||||
/// Parse a path environment variable.
|
/// Parse a path environment variable.
|
||||||
fn parse_path_environment_variable(name: &'static str) -> Option<PathBuf> {
|
fn parse_path_environment_variable(name: &'static str) -> Option<PathBuf> {
|
||||||
|
|
|
||||||
|
|
@ -590,6 +590,9 @@ impl EnvVars {
|
||||||
#[attr_added_in("0.1.38")]
|
#[attr_added_in("0.1.38")]
|
||||||
pub const NO_PROXY: &'static str = "NO_PROXY";
|
pub const NO_PROXY: &'static str = "NO_PROXY";
|
||||||
|
|
||||||
|
/// Timeout (in seconds) for only upload HTTP requests. (default: 900 s)
|
||||||
|
pub const UV_UPLOAD_HTTP_TIMEOUT: &'static str = "UV_UPLOAD_HTTP_TIMEOUT";
|
||||||
|
|
||||||
/// Timeout (in seconds) for HTTP requests. (default: 30 s)
|
/// Timeout (in seconds) for HTTP requests. (default: 30 s)
|
||||||
#[attr_added_in("0.1.7")]
|
#[attr_added_in("0.1.7")]
|
||||||
pub const UV_HTTP_TIMEOUT: &'static str = "UV_HTTP_TIMEOUT";
|
pub const UV_HTTP_TIMEOUT: &'static str = "UV_HTTP_TIMEOUT";
|
||||||
|
|
|
||||||
|
|
@ -38,10 +38,13 @@ pub(crate) async fn login(
|
||||||
bail!("Cannot specify a password when logging in to pyx");
|
bail!("Cannot specify a password when logging in to pyx");
|
||||||
}
|
}
|
||||||
|
|
||||||
let client = BaseClientBuilder::default()
|
let client = BaseClientBuilder::new(
|
||||||
.connectivity(network_settings.connectivity)
|
network_settings.connectivity,
|
||||||
.native_tls(network_settings.native_tls)
|
network_settings.native_tls,
|
||||||
.allow_insecure_host(network_settings.allow_insecure_host.clone())
|
network_settings.allow_insecure_host.clone(),
|
||||||
|
preview,
|
||||||
|
network_settings.timeout,
|
||||||
|
)
|
||||||
.auth_integration(AuthIntegration::NoAuthMiddleware)
|
.auth_integration(AuthIntegration::NoAuthMiddleware)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ pub(crate) async fn logout(
|
||||||
) -> Result<ExitStatus> {
|
) -> Result<ExitStatus> {
|
||||||
let pyx_store = PyxTokenStore::from_settings()?;
|
let pyx_store = PyxTokenStore::from_settings()?;
|
||||||
if pyx_store.is_known_domain(service.url()) {
|
if pyx_store.is_known_domain(service.url()) {
|
||||||
return pyx_logout(&pyx_store, network_settings, printer).await;
|
return pyx_logout(&pyx_store, network_settings, printer, preview).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
let backend = AuthBackend::from_settings(preview)?;
|
let backend = AuthBackend::from_settings(preview)?;
|
||||||
|
|
@ -95,12 +95,16 @@ async fn pyx_logout(
|
||||||
store: &PyxTokenStore,
|
store: &PyxTokenStore,
|
||||||
network_settings: &NetworkSettings,
|
network_settings: &NetworkSettings,
|
||||||
printer: Printer,
|
printer: Printer,
|
||||||
|
preview: Preview,
|
||||||
) -> Result<ExitStatus> {
|
) -> Result<ExitStatus> {
|
||||||
// Initialize the client.
|
// Initialize the client.
|
||||||
let client = BaseClientBuilder::default()
|
let client = BaseClientBuilder::new(
|
||||||
.connectivity(network_settings.connectivity)
|
network_settings.connectivity,
|
||||||
.native_tls(network_settings.native_tls)
|
network_settings.native_tls,
|
||||||
.allow_insecure_host(network_settings.allow_insecure_host.clone())
|
network_settings.allow_insecure_host.clone(),
|
||||||
|
preview,
|
||||||
|
network_settings.timeout,
|
||||||
|
)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// Retrieve the token store.
|
// Retrieve the token store.
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,13 @@ pub(crate) async fn token(
|
||||||
if username.is_some() {
|
if username.is_some() {
|
||||||
bail!("Cannot specify a username when logging in to pyx");
|
bail!("Cannot specify a username when logging in to pyx");
|
||||||
}
|
}
|
||||||
|
let client = BaseClientBuilder::new(
|
||||||
let client = BaseClientBuilder::default()
|
network_settings.connectivity,
|
||||||
.connectivity(network_settings.connectivity)
|
network_settings.native_tls,
|
||||||
.native_tls(network_settings.native_tls)
|
network_settings.allow_insecure_host.clone(),
|
||||||
.allow_insecure_host(network_settings.allow_insecure_host.clone())
|
preview,
|
||||||
|
network_settings.timeout,
|
||||||
|
)
|
||||||
.auth_integration(AuthIntegration::NoAuthMiddleware)
|
.auth_integration(AuthIntegration::NoAuthMiddleware)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use anyhow::{Context, Result, bail};
|
use anyhow::{Context, Result, bail};
|
||||||
use console::Term;
|
use console::Term;
|
||||||
|
|
@ -18,6 +17,7 @@ use uv_publish::{
|
||||||
files_for_publishing, upload,
|
files_for_publishing, upload,
|
||||||
};
|
};
|
||||||
use uv_redacted::DisplaySafeUrl;
|
use uv_redacted::DisplaySafeUrl;
|
||||||
|
use uv_settings::EnvironmentOptions;
|
||||||
use uv_warnings::{warn_user_once, write_error_chain};
|
use uv_warnings::{warn_user_once, write_error_chain};
|
||||||
|
|
||||||
use crate::commands::reporters::PublishReporter;
|
use crate::commands::reporters::PublishReporter;
|
||||||
|
|
@ -29,6 +29,7 @@ pub(crate) async fn publish(
|
||||||
publish_url: DisplaySafeUrl,
|
publish_url: DisplaySafeUrl,
|
||||||
trusted_publishing: TrustedPublishing,
|
trusted_publishing: TrustedPublishing,
|
||||||
keyring_provider: KeyringProviderType,
|
keyring_provider: KeyringProviderType,
|
||||||
|
environment: &EnvironmentOptions,
|
||||||
client_builder: &BaseClientBuilder<'_>,
|
client_builder: &BaseClientBuilder<'_>,
|
||||||
username: Option<String>,
|
username: Option<String>,
|
||||||
password: Option<String>,
|
password: Option<String>,
|
||||||
|
|
@ -123,9 +124,7 @@ pub(crate) async fn publish(
|
||||||
.keyring(keyring_provider)
|
.keyring(keyring_provider)
|
||||||
// Don't try cloning the request to make an unauthenticated request first.
|
// Don't try cloning the request to make an unauthenticated request first.
|
||||||
.auth_integration(AuthIntegration::OnlyAuthenticated)
|
.auth_integration(AuthIntegration::OnlyAuthenticated)
|
||||||
// Set a very high timeout for uploads, connections are often 10x slower on upload than
|
.timeout(environment.upload_http_timeout)
|
||||||
// download. 15 min is taken from the time a trusted publishing token is valid.
|
|
||||||
.default_timeout(Duration::from_secs(15 * 60))
|
|
||||||
.build();
|
.build();
|
||||||
let oidc_client = client_builder
|
let oidc_client = client_builder
|
||||||
.clone()
|
.clone()
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,9 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
||||||
.map(Cow::Owned)
|
.map(Cow::Owned)
|
||||||
.unwrap_or_else(|| Cow::Borrowed(&*CWD));
|
.unwrap_or_else(|| Cow::Borrowed(&*CWD));
|
||||||
|
|
||||||
|
// Load environment variables not handled by Clap
|
||||||
|
let environment = EnvironmentOptions::new()?;
|
||||||
|
|
||||||
// The `--isolated` argument is deprecated on preview APIs, and warns on non-preview APIs.
|
// The `--isolated` argument is deprecated on preview APIs, and warns on non-preview APIs.
|
||||||
let deprecated_isolated = if cli.top_level.global_args.isolated {
|
let deprecated_isolated = if cli.top_level.global_args.isolated {
|
||||||
match &*cli.command {
|
match &*cli.command {
|
||||||
|
|
@ -170,12 +173,17 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
||||||
..
|
..
|
||||||
}) = &mut **command
|
}) = &mut **command
|
||||||
{
|
{
|
||||||
let settings = GlobalSettings::resolve(&cli.top_level.global_args, filesystem.as_ref());
|
let settings = GlobalSettings::resolve(
|
||||||
|
&cli.top_level.global_args,
|
||||||
|
filesystem.as_ref(),
|
||||||
|
&environment,
|
||||||
|
);
|
||||||
let client_builder = BaseClientBuilder::new(
|
let client_builder = BaseClientBuilder::new(
|
||||||
settings.network_settings.connectivity,
|
settings.network_settings.connectivity,
|
||||||
settings.network_settings.native_tls,
|
settings.network_settings.native_tls,
|
||||||
settings.network_settings.allow_insecure_host,
|
settings.network_settings.allow_insecure_host,
|
||||||
settings.preview,
|
settings.preview,
|
||||||
|
environment.http_timeout,
|
||||||
)
|
)
|
||||||
.retries_from_env()?;
|
.retries_from_env()?;
|
||||||
Some(
|
Some(
|
||||||
|
|
@ -306,11 +314,12 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
||||||
.map(FilesystemOptions::from)
|
.map(FilesystemOptions::from)
|
||||||
.combine(filesystem);
|
.combine(filesystem);
|
||||||
|
|
||||||
// Load environment variables not handled by Clap
|
|
||||||
let environment = EnvironmentOptions::new()?;
|
|
||||||
|
|
||||||
// Resolve the global settings.
|
// Resolve the global settings.
|
||||||
let globals = GlobalSettings::resolve(&cli.top_level.global_args, filesystem.as_ref());
|
let globals = GlobalSettings::resolve(
|
||||||
|
&cli.top_level.global_args,
|
||||||
|
filesystem.as_ref(),
|
||||||
|
&environment,
|
||||||
|
);
|
||||||
|
|
||||||
// Resolve the cache settings.
|
// Resolve the cache settings.
|
||||||
let cache_settings = CacheSettings::resolve(*cli.top_level.cache_args, filesystem.as_ref());
|
let cache_settings = CacheSettings::resolve(*cli.top_level.cache_args, filesystem.as_ref());
|
||||||
|
|
@ -447,6 +456,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
||||||
globals.network_settings.native_tls,
|
globals.network_settings.native_tls,
|
||||||
globals.network_settings.allow_insecure_host.clone(),
|
globals.network_settings.allow_insecure_host.clone(),
|
||||||
globals.preview,
|
globals.preview,
|
||||||
|
environment.http_timeout,
|
||||||
)
|
)
|
||||||
.retries_from_env()?;
|
.retries_from_env()?;
|
||||||
|
|
||||||
|
|
@ -459,6 +469,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
||||||
args,
|
args,
|
||||||
&cli.top_level.global_args,
|
&cli.top_level.global_args,
|
||||||
filesystem.as_ref(),
|
filesystem.as_ref(),
|
||||||
|
&environment,
|
||||||
);
|
);
|
||||||
show_settings!(args);
|
show_settings!(args);
|
||||||
|
|
||||||
|
|
@ -481,6 +492,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
||||||
args,
|
args,
|
||||||
&cli.top_level.global_args,
|
&cli.top_level.global_args,
|
||||||
filesystem.as_ref(),
|
filesystem.as_ref(),
|
||||||
|
&environment,
|
||||||
);
|
);
|
||||||
show_settings!(args);
|
show_settings!(args);
|
||||||
|
|
||||||
|
|
@ -501,6 +513,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
||||||
args,
|
args,
|
||||||
&cli.top_level.global_args,
|
&cli.top_level.global_args,
|
||||||
filesystem.as_ref(),
|
filesystem.as_ref(),
|
||||||
|
&environment,
|
||||||
);
|
);
|
||||||
show_settings!(args);
|
show_settings!(args);
|
||||||
|
|
||||||
|
|
@ -1417,7 +1430,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
||||||
command: ToolCommand::Upgrade(args),
|
command: ToolCommand::Upgrade(args),
|
||||||
}) => {
|
}) => {
|
||||||
// Resolve the settings from the command-line arguments and workspace configuration.
|
// Resolve the settings from the command-line arguments and workspace configuration.
|
||||||
let args = settings::ToolUpgradeSettings::resolve(args, filesystem, environment);
|
let args = settings::ToolUpgradeSettings::resolve(args, filesystem, &environment);
|
||||||
show_settings!(args);
|
show_settings!(args);
|
||||||
|
|
||||||
// Initialize the cache.
|
// Initialize the cache.
|
||||||
|
|
@ -1680,6 +1693,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
||||||
publish_url,
|
publish_url,
|
||||||
trusted_publishing,
|
trusted_publishing,
|
||||||
keyring_provider,
|
keyring_provider,
|
||||||
|
&environment,
|
||||||
&client_builder,
|
&client_builder,
|
||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use std::num::NonZeroUsize;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process;
|
use std::process;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use uv_auth::Service;
|
use uv_auth::Service;
|
||||||
use uv_cache::{CacheArgs, Refresh};
|
use uv_cache::{CacheArgs, Refresh};
|
||||||
|
|
@ -78,8 +79,12 @@ pub(crate) struct GlobalSettings {
|
||||||
|
|
||||||
impl GlobalSettings {
|
impl GlobalSettings {
|
||||||
/// Resolve the [`GlobalSettings`] from the CLI and filesystem configuration.
|
/// Resolve the [`GlobalSettings`] from the CLI and filesystem configuration.
|
||||||
pub(crate) fn resolve(args: &GlobalArgs, workspace: Option<&FilesystemOptions>) -> Self {
|
pub(crate) fn resolve(
|
||||||
let network_settings = NetworkSettings::resolve(args, workspace);
|
args: &GlobalArgs,
|
||||||
|
workspace: Option<&FilesystemOptions>,
|
||||||
|
environment: &EnvironmentOptions,
|
||||||
|
) -> Self {
|
||||||
|
let network_settings = NetworkSettings::resolve(args, workspace, environment);
|
||||||
let python_preference = resolve_python_preference(args, workspace);
|
let python_preference = resolve_python_preference(args, workspace);
|
||||||
Self {
|
Self {
|
||||||
required_version: workspace
|
required_version: workspace
|
||||||
|
|
@ -172,10 +177,15 @@ pub(crate) struct NetworkSettings {
|
||||||
pub(crate) connectivity: Connectivity,
|
pub(crate) connectivity: Connectivity,
|
||||||
pub(crate) native_tls: bool,
|
pub(crate) native_tls: bool,
|
||||||
pub(crate) allow_insecure_host: Vec<TrustedHost>,
|
pub(crate) allow_insecure_host: Vec<TrustedHost>,
|
||||||
|
pub(crate) timeout: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NetworkSettings {
|
impl NetworkSettings {
|
||||||
pub(crate) fn resolve(args: &GlobalArgs, workspace: Option<&FilesystemOptions>) -> Self {
|
pub(crate) fn resolve(
|
||||||
|
args: &GlobalArgs,
|
||||||
|
workspace: Option<&FilesystemOptions>,
|
||||||
|
environment: &EnvironmentOptions,
|
||||||
|
) -> Self {
|
||||||
let connectivity = if flag(args.offline, args.no_offline, "offline")
|
let connectivity = if flag(args.offline, args.no_offline, "offline")
|
||||||
.combine(workspace.and_then(|workspace| workspace.globals.offline))
|
.combine(workspace.and_then(|workspace| workspace.globals.offline))
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
|
|
@ -184,6 +194,7 @@ impl NetworkSettings {
|
||||||
} else {
|
} else {
|
||||||
Connectivity::Online
|
Connectivity::Online
|
||||||
};
|
};
|
||||||
|
let timeout = environment.http_timeout;
|
||||||
let native_tls = flag(args.native_tls, args.no_native_tls, "native-tls")
|
let native_tls = flag(args.native_tls, args.no_native_tls, "native-tls")
|
||||||
.combine(workspace.and_then(|workspace| workspace.globals.native_tls))
|
.combine(workspace.and_then(|workspace| workspace.globals.native_tls))
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
|
|
@ -208,6 +219,7 @@ impl NetworkSettings {
|
||||||
connectivity,
|
connectivity,
|
||||||
native_tls,
|
native_tls,
|
||||||
allow_insecure_host,
|
allow_insecure_host,
|
||||||
|
timeout,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -746,7 +758,7 @@ impl ToolUpgradeSettings {
|
||||||
pub(crate) fn resolve(
|
pub(crate) fn resolve(
|
||||||
args: ToolUpgradeArgs,
|
args: ToolUpgradeArgs,
|
||||||
filesystem: Option<FilesystemOptions>,
|
filesystem: Option<FilesystemOptions>,
|
||||||
environment: EnvironmentOptions,
|
environment: &EnvironmentOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let ToolUpgradeArgs {
|
let ToolUpgradeArgs {
|
||||||
name,
|
name,
|
||||||
|
|
@ -834,6 +846,7 @@ impl ToolUpgradeSettings {
|
||||||
filesystem: top_level,
|
filesystem: top_level,
|
||||||
install_mirrors: environment
|
install_mirrors: environment
|
||||||
.install_mirrors
|
.install_mirrors
|
||||||
|
.clone()
|
||||||
.combine(filesystem_install_mirrors),
|
.combine(filesystem_install_mirrors),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3662,11 +3675,12 @@ impl AuthLogoutSettings {
|
||||||
args: AuthLogoutArgs,
|
args: AuthLogoutArgs,
|
||||||
global_args: &GlobalArgs,
|
global_args: &GlobalArgs,
|
||||||
filesystem: Option<&FilesystemOptions>,
|
filesystem: Option<&FilesystemOptions>,
|
||||||
|
environment: &EnvironmentOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
service: args.service,
|
service: args.service,
|
||||||
username: args.username,
|
username: args.username,
|
||||||
network_settings: NetworkSettings::resolve(global_args, filesystem),
|
network_settings: NetworkSettings::resolve(global_args, filesystem, environment),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3687,11 +3701,12 @@ impl AuthTokenSettings {
|
||||||
args: AuthTokenArgs,
|
args: AuthTokenArgs,
|
||||||
global_args: &GlobalArgs,
|
global_args: &GlobalArgs,
|
||||||
filesystem: Option<&FilesystemOptions>,
|
filesystem: Option<&FilesystemOptions>,
|
||||||
|
environment: &EnvironmentOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
service: args.service,
|
service: args.service,
|
||||||
username: args.username,
|
username: args.username,
|
||||||
network_settings: NetworkSettings::resolve(global_args, filesystem),
|
network_settings: NetworkSettings::resolve(global_args, filesystem, environment),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3714,13 +3729,14 @@ impl AuthLoginSettings {
|
||||||
args: AuthLoginArgs,
|
args: AuthLoginArgs,
|
||||||
global_args: &GlobalArgs,
|
global_args: &GlobalArgs,
|
||||||
filesystem: Option<&FilesystemOptions>,
|
filesystem: Option<&FilesystemOptions>,
|
||||||
|
environment: &EnvironmentOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
service: args.service,
|
service: args.service,
|
||||||
username: args.username,
|
username: args.username,
|
||||||
password: args.password,
|
password: args.password,
|
||||||
token: args.token,
|
token: args.token,
|
||||||
network_settings: NetworkSettings::resolve(global_args, filesystem),
|
network_settings: NetworkSettings::resolve(global_args, filesystem, environment),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,13 @@ impl TestContext {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the "http timeout" for all commands in this context.
|
||||||
|
pub fn with_http_timeout(mut self, http_timeout: &str) -> Self {
|
||||||
|
self.extra_env
|
||||||
|
.push((EnvVars::UV_HTTP_TIMEOUT.into(), http_timeout.into()));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Add extra standard filtering for messages like "Resolved 10 packages" which
|
/// Add extra standard filtering for messages like "Resolved 10 packages" which
|
||||||
/// can differ between platforms.
|
/// can differ between platforms.
|
||||||
///
|
///
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -265,6 +266,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -465,6 +467,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -697,6 +700,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -898,6 +902,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -1075,6 +1080,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -1301,6 +1307,7 @@ fn resolve_index_url() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -1535,6 +1542,7 @@ fn resolve_index_url() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -1827,6 +1835,7 @@ fn resolve_find_links() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -2050,6 +2059,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -2232,6 +2242,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -2464,6 +2475,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -2719,6 +2731,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -2891,6 +2904,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -3063,6 +3077,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -3237,6 +3252,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -3430,6 +3446,7 @@ fn resolve_tool() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -3615,6 +3632,7 @@ fn resolve_poetry_toml() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -3821,6 +3839,7 @@ fn resolve_both() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -4066,6 +4085,7 @@ fn resolve_both_special_fields() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -4390,6 +4410,7 @@ fn resolve_config_file() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -4689,6 +4710,7 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -4864,6 +4886,7 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -5058,6 +5081,7 @@ fn allow_insecure_host() -> anyhow::Result<()> {
|
||||||
port: None,
|
port: None,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -5244,6 +5268,7 @@ fn index_priority() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -5478,6 +5503,7 @@ fn index_priority() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -5718,6 +5744,7 @@ fn index_priority() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -5953,6 +5980,7 @@ fn index_priority() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -6195,6 +6223,7 @@ fn index_priority() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -6430,6 +6459,7 @@ fn index_priority() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -6678,6 +6708,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -6843,6 +6874,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -7006,6 +7038,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -7171,6 +7204,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -7334,6 +7368,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -7498,6 +7533,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -7677,6 +7713,7 @@ fn preview_features() {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -7789,6 +7826,7 @@ fn preview_features() {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -7901,6 +7939,7 @@ fn preview_features() {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -8013,6 +8052,7 @@ fn preview_features() {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -8125,6 +8165,7 @@ fn preview_features() {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -8239,6 +8280,7 @@ fn preview_features() {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -8372,6 +8414,7 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -8545,6 +8588,7 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -8741,6 +8785,7 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -8912,6 +8957,7 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -9077,6 +9123,7 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -9243,6 +9290,7 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -9474,6 +9522,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -9591,6 +9640,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -9731,6 +9781,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -9846,6 +9897,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -9951,6 +10003,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -10057,6 +10110,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -10227,6 +10281,7 @@ fn build_isolation_override() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -10395,6 +10450,7 @@ fn build_isolation_override() -> anyhow::Result<()> {
|
||||||
connectivity: Online,
|
connectivity: Online,
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
|
timeout: [TIME],
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
|
||||||
|
|
@ -882,6 +882,24 @@ fn seed_older_python_version() {
|
||||||
context.venv.assert(predicates::path::is_dir());
|
context.venv.assert(predicates::path::is_dir());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn create_venv_with_invalid_http_timeout() {
|
||||||
|
let context = TestContext::new_with_versions(&["3.12"]).with_http_timeout("not_a_number");
|
||||||
|
|
||||||
|
// Create a virtual environment at `.venv`.
|
||||||
|
uv_snapshot!(context.filters(), context.venv()
|
||||||
|
.arg(context.venv.as_os_str())
|
||||||
|
.arg("--python")
|
||||||
|
.arg("3.12"), @r###"
|
||||||
|
success: false
|
||||||
|
exit_code: 2
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
error: Failed to parse environment variable `UV_HTTP_TIMEOUT` with invalid value `not_a_number`: expected an integer
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn create_venv_unknown_python_minor() {
|
fn create_venv_unknown_python_minor() {
|
||||||
let context = TestContext::new_with_versions(&["3.12"]).with_filtered_python_sources();
|
let context = TestContext::new_with_versions(&["3.12"]).with_filtered_python_sources();
|
||||||
|
|
|
||||||
|
|
@ -651,6 +651,10 @@ Equivalent to the `--torch-backend` command-line argument (e.g., `cpu`, `cu126`,
|
||||||
Used ephemeral environments like CI to install uv to a specific path while preventing
|
Used ephemeral environments like CI to install uv to a specific path while preventing
|
||||||
the installer from modifying shell profiles or environment variables.
|
the installer from modifying shell profiles or environment variables.
|
||||||
|
|
||||||
|
### `UV_UPLOAD_HTTP_TIMEOUT`
|
||||||
|
|
||||||
|
Timeout (in seconds) for only upload HTTP requests. (default: 900 s)
|
||||||
|
|
||||||
### `UV_VENV_CLEAR`
|
### `UV_VENV_CLEAR`
|
||||||
<small class="added-in">added in `0.8.0`</small>
|
<small class="added-in">added in `0.8.0`</small>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue