mirror of https://github.com/astral-sh/uv
Move parsing http retries to EnvironmentOptions (#16284)
## Summary - Move parsing `UV_HTTP_RETRIES` to `EnvironmentOptions` Relates https://github.com/astral-sh/uv/issues/14720 ## Test Plan - Tests with existing tests
This commit is contained in:
parent
29cec24d5c
commit
51e8da2d1c
|
|
@ -5291,7 +5291,6 @@ dependencies = [
|
||||||
"predicates",
|
"predicates",
|
||||||
"regex",
|
"regex",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"reqwest-retry",
|
|
||||||
"rkyv",
|
"rkyv",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"self-replace",
|
"self-replace",
|
||||||
|
|
@ -6605,6 +6604,7 @@ dependencies = [
|
||||||
"tracing",
|
"tracing",
|
||||||
"url",
|
"url",
|
||||||
"uv-cache-info",
|
"uv-cache-info",
|
||||||
|
"uv-client",
|
||||||
"uv-configuration",
|
"uv-configuration",
|
||||||
"uv-dirs",
|
"uv-dirs",
|
||||||
"uv-distribution-types",
|
"uv-distribution-types",
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@ use crate::middleware::OfflineMiddleware;
|
||||||
use crate::tls::read_identity;
|
use crate::tls::read_identity;
|
||||||
use crate::{Connectivity, WrappedReqwestError};
|
use crate::{Connectivity, WrappedReqwestError};
|
||||||
|
|
||||||
/// Do not use this value directly outside tests, use [`retries_from_env`] instead.
|
|
||||||
pub const DEFAULT_RETRIES: u32 = 3;
|
pub const DEFAULT_RETRIES: u32 = 3;
|
||||||
|
|
||||||
/// Maximum number of redirects to follow before giving up.
|
/// Maximum number of redirects to follow before giving up.
|
||||||
|
|
@ -154,11 +153,13 @@ impl BaseClientBuilder<'_> {
|
||||||
allow_insecure_host: Vec<TrustedHost>,
|
allow_insecure_host: Vec<TrustedHost>,
|
||||||
preview: Preview,
|
preview: Preview,
|
||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
|
retries: u32,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
preview,
|
preview,
|
||||||
allow_insecure_host,
|
allow_insecure_host,
|
||||||
native_tls,
|
native_tls,
|
||||||
|
retries,
|
||||||
connectivity,
|
connectivity,
|
||||||
timeout,
|
timeout,
|
||||||
..Self::default()
|
..Self::default()
|
||||||
|
|
@ -202,15 +203,6 @@ impl<'a> BaseClientBuilder<'a> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read the retry count from [`EnvVars::UV_HTTP_RETRIES`] if set, otherwise use the default
|
|
||||||
/// retries.
|
|
||||||
///
|
|
||||||
/// Errors when [`EnvVars::UV_HTTP_RETRIES`] is not a valid u32.
|
|
||||||
pub fn retries_from_env(mut self) -> Result<Self, RetryParsingError> {
|
|
||||||
self.retries = retries_from_env()?;
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn native_tls(mut self, native_tls: bool) -> Self {
|
pub fn native_tls(mut self, native_tls: bool) -> Self {
|
||||||
self.native_tls = native_tls;
|
self.native_tls = native_tls;
|
||||||
|
|
@ -292,7 +284,7 @@ impl<'a> BaseClientBuilder<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a [`RetryPolicy`] for the client.
|
/// Create a [`RetryPolicy`] for the client.
|
||||||
fn retry_policy(&self) -> ExponentialBackoff {
|
pub fn retry_policy(&self) -> ExponentialBackoff {
|
||||||
let mut builder = ExponentialBackoff::builder();
|
let mut builder = ExponentialBackoff::builder();
|
||||||
if env::var_os(EnvVars::UV_TEST_NO_HTTP_RETRY_DELAY).is_some() {
|
if env::var_os(EnvVars::UV_TEST_NO_HTTP_RETRY_DELAY).is_some() {
|
||||||
builder = builder.retry_bounds(Duration::from_millis(0), Duration::from_millis(0));
|
builder = builder.retry_bounds(Duration::from_millis(0), Duration::from_millis(0));
|
||||||
|
|
@ -1093,19 +1085,6 @@ pub enum RetryParsingError {
|
||||||
ParseInt(#[from] ParseIntError),
|
ParseInt(#[from] ParseIntError),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read the retry count from [`EnvVars::UV_HTTP_RETRIES`] if set, otherwise, make no change.
|
|
||||||
///
|
|
||||||
/// Errors when [`EnvVars::UV_HTTP_RETRIES`] is not a valid u32.
|
|
||||||
pub fn retries_from_env() -> Result<u32, RetryParsingError> {
|
|
||||||
// TODO(zanieb): We should probably parse this in another layer, but there's not a natural
|
|
||||||
// fit for it right now
|
|
||||||
if let Some(value) = env::var_os(EnvVars::UV_HTTP_RETRIES) {
|
|
||||||
Ok(value.to_string_lossy().as_ref().parse::<u32>()?)
|
|
||||||
} else {
|
|
||||||
Ok(DEFAULT_RETRIES)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
pub use base_client::{
|
pub use base_client::{
|
||||||
AuthIntegration, BaseClient, BaseClientBuilder, DEFAULT_RETRIES, ExtraMiddleware,
|
AuthIntegration, BaseClient, BaseClientBuilder, DEFAULT_RETRIES, ExtraMiddleware,
|
||||||
RedirectClientWithMiddleware, RequestBuilder, RetryParsingError, UvRetryableStrategy,
|
RedirectClientWithMiddleware, RequestBuilder, RetryParsingError, UvRetryableStrategy,
|
||||||
is_transient_network_error, retries_from_env,
|
is_transient_network_error,
|
||||||
};
|
};
|
||||||
pub use cached_client::{CacheControl, CachedClient, CachedClientError, DataWithCachePolicy};
|
pub use cached_client::{CacheControl, CachedClient, CachedClientError, DataWithCachePolicy};
|
||||||
pub use error::{Error, ErrorKind, WrappedReqwestError};
|
pub use error::{Error, ErrorKind, WrappedReqwestError};
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ use uv_auth::{Credentials, PyxTokenStore};
|
||||||
use uv_cache::{Cache, Refresh};
|
use uv_cache::{Cache, Refresh};
|
||||||
use uv_client::{
|
use uv_client::{
|
||||||
BaseClient, MetadataFormat, OwnedArchive, RegistryClientBuilder, RequestBuilder,
|
BaseClient, MetadataFormat, OwnedArchive, RegistryClientBuilder, RequestBuilder,
|
||||||
RetryParsingError, UvRetryableStrategy, retries_from_env,
|
RetryParsingError, UvRetryableStrategy,
|
||||||
};
|
};
|
||||||
use uv_configuration::{KeyringProviderType, TrustedPublishing};
|
use uv_configuration::{KeyringProviderType, TrustedPublishing};
|
||||||
use uv_distribution_filename::{DistFilename, SourceDistExtension, SourceDistFilename};
|
use uv_distribution_filename::{DistFilename, SourceDistExtension, SourceDistFilename};
|
||||||
|
|
@ -382,6 +382,7 @@ pub async fn upload(
|
||||||
filename: &DistFilename,
|
filename: &DistFilename,
|
||||||
registry: &DisplaySafeUrl,
|
registry: &DisplaySafeUrl,
|
||||||
client: &BaseClient,
|
client: &BaseClient,
|
||||||
|
retry_policy: ExponentialBackoff,
|
||||||
credentials: &Credentials,
|
credentials: &Credentials,
|
||||||
check_url_client: Option<&CheckUrlClient<'_>>,
|
check_url_client: Option<&CheckUrlClient<'_>>,
|
||||||
download_concurrency: &Semaphore,
|
download_concurrency: &Semaphore,
|
||||||
|
|
@ -389,8 +390,6 @@ pub async fn upload(
|
||||||
) -> Result<bool, PublishError> {
|
) -> Result<bool, PublishError> {
|
||||||
let mut n_past_retries = 0;
|
let mut n_past_retries = 0;
|
||||||
let start_time = SystemTime::now();
|
let start_time = SystemTime::now();
|
||||||
// N.B. We cannot use the client policy here because it is set to zero retries.
|
|
||||||
let retry_policy = ExponentialBackoff::builder().build_with_max_retries(retries_from_env()?);
|
|
||||||
loop {
|
loop {
|
||||||
let (request, idx) = build_upload_request(
|
let (request, idx) = build_upload_request(
|
||||||
file,
|
file,
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,10 @@ use std::str::FromStr;
|
||||||
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use ref_cast::RefCast;
|
use ref_cast::RefCast;
|
||||||
use reqwest_retry::policies::ExponentialBackoff;
|
|
||||||
use tracing::{debug, info};
|
use tracing::{debug, info};
|
||||||
|
|
||||||
use uv_cache::Cache;
|
use uv_cache::Cache;
|
||||||
use uv_client::{BaseClientBuilder, retries_from_env};
|
use uv_client::BaseClientBuilder;
|
||||||
use uv_pep440::{Prerelease, Version};
|
use uv_pep440::{Prerelease, Version};
|
||||||
use uv_platform::{Arch, Libc, Os, Platform};
|
use uv_platform::{Arch, Libc, Os, Platform};
|
||||||
use uv_preview::Preview;
|
use uv_preview::Preview;
|
||||||
|
|
@ -231,8 +230,7 @@ impl PythonInstallation {
|
||||||
|
|
||||||
// Python downloads are performing their own retries to catch stream errors, disable the
|
// Python downloads are performing their own retries to catch stream errors, disable the
|
||||||
// default retries to avoid the middleware from performing uncontrolled retries.
|
// default retries to avoid the middleware from performing uncontrolled retries.
|
||||||
let retry_policy =
|
let retry_policy = client_builder.retry_policy();
|
||||||
ExponentialBackoff::builder().build_with_max_retries(retries_from_env()?);
|
|
||||||
let client = client_builder.clone().retries(0).build();
|
let client = client_builder.clone().retries(0).build();
|
||||||
|
|
||||||
info!("Fetching requested Python...");
|
info!("Fetching requested Python...");
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
uv-cache-info = { workspace = true, features = ["schemars"] }
|
uv-cache-info = { workspace = true, features = ["schemars"] }
|
||||||
|
uv-client = { workspace = true }
|
||||||
uv-configuration = { workspace = true, features = ["schemars", "clap"] }
|
uv-configuration = { workspace = true, features = ["schemars", "clap"] }
|
||||||
uv-dirs = { workspace = true }
|
uv-dirs = { workspace = true }
|
||||||
uv-distribution-types = { workspace = true, features = ["schemars"] }
|
uv-distribution-types = { workspace = true, features = ["schemars"] }
|
||||||
|
|
|
||||||
|
|
@ -585,6 +585,7 @@ pub struct EnvironmentOptions {
|
||||||
pub install_mirrors: PythonInstallMirrors,
|
pub install_mirrors: PythonInstallMirrors,
|
||||||
pub log_context: Option<bool>,
|
pub log_context: Option<bool>,
|
||||||
pub http_timeout: Duration,
|
pub http_timeout: Duration,
|
||||||
|
pub http_retries: u32,
|
||||||
pub upload_http_timeout: Duration,
|
pub upload_http_timeout: Duration,
|
||||||
pub concurrency: Concurrency,
|
pub concurrency: Concurrency,
|
||||||
#[cfg(feature = "tracing-durations-export")]
|
#[cfg(feature = "tracing-durations-export")]
|
||||||
|
|
@ -596,9 +597,11 @@ impl EnvironmentOptions {
|
||||||
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
|
// 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
|
// `UV_REQUEST_TIMEOUT` is provided for backwards compatibility with v0.1.6
|
||||||
let http_timeout = parse_u64_environment_variable(EnvVars::UV_HTTP_TIMEOUT)?
|
let http_timeout = parse_integer_environment_variable(EnvVars::UV_HTTP_TIMEOUT)?
|
||||||
.or(parse_u64_environment_variable(EnvVars::UV_REQUEST_TIMEOUT)?)
|
.or(parse_integer_environment_variable(
|
||||||
.or(parse_u64_environment_variable(EnvVars::HTTP_TIMEOUT)?)
|
EnvVars::UV_REQUEST_TIMEOUT,
|
||||||
|
)?)
|
||||||
|
.or(parse_integer_environment_variable(EnvVars::HTTP_TIMEOUT)?)
|
||||||
.map(Duration::from_secs);
|
.map(Duration::from_secs);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
|
@ -610,13 +613,9 @@ impl EnvironmentOptions {
|
||||||
EnvVars::UV_PYTHON_INSTALL_REGISTRY,
|
EnvVars::UV_PYTHON_INSTALL_REGISTRY,
|
||||||
)?,
|
)?,
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: parse_non_zero_usize_environment_variable(
|
downloads: parse_integer_environment_variable(EnvVars::UV_CONCURRENT_DOWNLOADS)?,
|
||||||
EnvVars::UV_CONCURRENT_DOWNLOADS,
|
builds: parse_integer_environment_variable(EnvVars::UV_CONCURRENT_BUILDS)?,
|
||||||
)?,
|
installs: parse_integer_environment_variable(EnvVars::UV_CONCURRENT_INSTALLS)?,
|
||||||
builds: parse_non_zero_usize_environment_variable(EnvVars::UV_CONCURRENT_BUILDS)?,
|
|
||||||
installs: parse_non_zero_usize_environment_variable(
|
|
||||||
EnvVars::UV_CONCURRENT_INSTALLS,
|
|
||||||
)?,
|
|
||||||
},
|
},
|
||||||
install_mirrors: PythonInstallMirrors {
|
install_mirrors: PythonInstallMirrors {
|
||||||
python_install_mirror: parse_string_environment_variable(
|
python_install_mirror: parse_string_environment_variable(
|
||||||
|
|
@ -630,11 +629,15 @@ 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_u64_environment_variable(EnvVars::UV_UPLOAD_HTTP_TIMEOUT)?
|
upload_http_timeout: parse_integer_environment_variable(
|
||||||
.map(Duration::from_secs)
|
EnvVars::UV_UPLOAD_HTTP_TIMEOUT,
|
||||||
.or(http_timeout)
|
)?
|
||||||
.unwrap_or(Duration::from_secs(15 * 60)),
|
.map(Duration::from_secs)
|
||||||
|
.or(http_timeout)
|
||||||
|
.unwrap_or(Duration::from_secs(15 * 60)),
|
||||||
http_timeout: http_timeout.unwrap_or(Duration::from_secs(30)),
|
http_timeout: http_timeout.unwrap_or(Duration::from_secs(30)),
|
||||||
|
http_retries: parse_integer_environment_variable(EnvVars::UV_HTTP_RETRIES)?
|
||||||
|
.unwrap_or(uv_client::DEFAULT_RETRIES),
|
||||||
#[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,
|
||||||
|
|
@ -716,10 +719,7 @@ fn parse_string_environment_variable(name: &'static str) -> Result<Option<String
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_integer_environment_variable<T>(
|
fn parse_integer_environment_variable<T>(name: &'static str) -> Result<Option<T>, Error>
|
||||||
name: &'static str,
|
|
||||||
err_msg: &'static str,
|
|
||||||
) -> Result<Option<T>, Error>
|
|
||||||
where
|
where
|
||||||
T: std::str::FromStr + Copy,
|
T: std::str::FromStr + Copy,
|
||||||
<T as std::str::FromStr>::Err: std::fmt::Display,
|
<T as std::str::FromStr>::Err: std::fmt::Display,
|
||||||
|
|
@ -732,7 +732,7 @@ where
|
||||||
std::env::VarError::NotUnicode(err) => Err(Error::InvalidEnvironmentVariable {
|
std::env::VarError::NotUnicode(err) => Err(Error::InvalidEnvironmentVariable {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
value: err.to_string_lossy().to_string(),
|
value: err.to_string_lossy().to_string(),
|
||||||
err: err_msg.to_string(),
|
err: "expected a valid UTF-8 string".to_string(),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -743,26 +743,14 @@ where
|
||||||
|
|
||||||
match value.parse::<T>() {
|
match value.parse::<T>() {
|
||||||
Ok(v) => Ok(Some(v)),
|
Ok(v) => Ok(Some(v)),
|
||||||
Err(_) => Err(Error::InvalidEnvironmentVariable {
|
Err(err) => Err(Error::InvalidEnvironmentVariable {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
value,
|
value,
|
||||||
err: err_msg.to_string(),
|
err: err.to_string(),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a integer environment variable.
|
|
||||||
fn parse_u64_environment_variable(name: &'static str) -> Result<Option<u64>, Error> {
|
|
||||||
parse_integer_environment_variable(name, "expected an integer")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parse a non-zero usize environment variable.
|
|
||||||
fn parse_non_zero_usize_environment_variable(
|
|
||||||
name: &'static str,
|
|
||||||
) -> Result<Option<NonZeroUsize>, Error> {
|
|
||||||
parse_integer_environment_variable(name, "expected a non-zero positive integer")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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> {
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,6 @@ owo-colors = { workspace = true }
|
||||||
petgraph = { workspace = true }
|
petgraph = { workspace = true }
|
||||||
regex = { workspace = true }
|
regex = { workspace = true }
|
||||||
reqwest = { workspace = true }
|
reqwest = { workspace = true }
|
||||||
reqwest-retry = { workspace = true }
|
|
||||||
rkyv = { workspace = true }
|
rkyv = { workspace = true }
|
||||||
rustc-hash = { workspace = true }
|
rustc-hash = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ pub(crate) async fn login(
|
||||||
network_settings.allow_insecure_host.clone(),
|
network_settings.allow_insecure_host.clone(),
|
||||||
preview,
|
preview,
|
||||||
network_settings.timeout,
|
network_settings.timeout,
|
||||||
|
network_settings.retries,
|
||||||
)
|
)
|
||||||
.auth_integration(AuthIntegration::NoAuthMiddleware)
|
.auth_integration(AuthIntegration::NoAuthMiddleware)
|
||||||
.build();
|
.build();
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,7 @@ async fn pyx_logout(
|
||||||
network_settings.allow_insecure_host.clone(),
|
network_settings.allow_insecure_host.clone(),
|
||||||
preview,
|
preview,
|
||||||
network_settings.timeout,
|
network_settings.timeout,
|
||||||
|
network_settings.retries,
|
||||||
)
|
)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ pub(crate) async fn token(
|
||||||
network_settings.allow_insecure_host.clone(),
|
network_settings.allow_insecure_host.clone(),
|
||||||
preview,
|
preview,
|
||||||
network_settings.timeout,
|
network_settings.timeout,
|
||||||
|
network_settings.retries,
|
||||||
)
|
)
|
||||||
.auth_integration(AuthIntegration::NoAuthMiddleware)
|
.auth_integration(AuthIntegration::NoAuthMiddleware)
|
||||||
.build();
|
.build();
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,11 @@ use std::path::Path;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use reqwest_retry::policies::ExponentialBackoff;
|
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
|
||||||
use uv_bin_install::{Binary, bin_install};
|
use uv_bin_install::{Binary, bin_install};
|
||||||
use uv_cache::Cache;
|
use uv_cache::Cache;
|
||||||
use uv_client::{BaseClientBuilder, retries_from_env};
|
use uv_client::BaseClientBuilder;
|
||||||
use uv_pep440::Version;
|
use uv_pep440::Version;
|
||||||
use uv_preview::{Preview, PreviewFeatures};
|
use uv_preview::{Preview, PreviewFeatures};
|
||||||
use uv_warnings::warn_user;
|
use uv_warnings::warn_user;
|
||||||
|
|
@ -64,9 +63,9 @@ pub(crate) async fn format(
|
||||||
// Parse version if provided
|
// Parse version if provided
|
||||||
let version = version.as_deref().map(Version::from_str).transpose()?;
|
let version = version.as_deref().map(Version::from_str).transpose()?;
|
||||||
|
|
||||||
|
let retry_policy = client_builder.retry_policy();
|
||||||
// Python downloads are performing their own retries to catch stream errors, disable the
|
// Python downloads are performing their own retries to catch stream errors, disable the
|
||||||
// default retries to avoid the middleware from performing uncontrolled retries.
|
// default retries to avoid the middleware from performing uncontrolled retries.
|
||||||
let retry_policy = ExponentialBackoff::builder().build_with_max_retries(retries_from_env()?);
|
|
||||||
let client = client_builder.retries(0).build();
|
let client = client_builder.retries(0).build();
|
||||||
|
|
||||||
// Get the path to Ruff, downloading it if necessary
|
// Get the path to Ruff, downloading it if necessary
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,7 @@ pub(crate) async fn publish(
|
||||||
.auth_integration(AuthIntegration::NoAuthMiddleware)
|
.auth_integration(AuthIntegration::NoAuthMiddleware)
|
||||||
.wrap_existing(&upload_client);
|
.wrap_existing(&upload_client);
|
||||||
|
|
||||||
|
let retry_policy = client_builder.retry_policy();
|
||||||
// We're only checking a single URL and one at a time, so 1 permit is sufficient
|
// We're only checking a single URL and one at a time, so 1 permit is sufficient
|
||||||
let download_concurrency = Arc::new(Semaphore::new(1));
|
let download_concurrency = Arc::new(Semaphore::new(1));
|
||||||
|
|
||||||
|
|
@ -222,6 +223,7 @@ pub(crate) async fn publish(
|
||||||
&filename,
|
&filename,
|
||||||
&publish_url,
|
&publish_url,
|
||||||
&upload_client,
|
&upload_client,
|
||||||
|
retry_policy,
|
||||||
&credentials,
|
&credentials,
|
||||||
check_url_client.as_ref(),
|
check_url_client.as_ref(),
|
||||||
&download_concurrency,
|
&download_concurrency,
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,10 @@ use futures::stream::FuturesUnordered;
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
use itertools::{Either, Itertools};
|
use itertools::{Either, Itertools};
|
||||||
use owo_colors::{AnsiColors, OwoColorize};
|
use owo_colors::{AnsiColors, OwoColorize};
|
||||||
use reqwest_retry::policies::ExponentialBackoff;
|
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use tracing::{debug, trace};
|
use tracing::{debug, trace};
|
||||||
|
|
||||||
use uv_client::{BaseClientBuilder, retries_from_env};
|
use uv_client::BaseClientBuilder;
|
||||||
use uv_fs::Simplified;
|
use uv_fs::Simplified;
|
||||||
use uv_platform::{Arch, Libc};
|
use uv_platform::{Arch, Libc};
|
||||||
use uv_preview::{Preview, PreviewFeatures};
|
use uv_preview::{Preview, PreviewFeatures};
|
||||||
|
|
@ -398,9 +397,9 @@ pub(crate) async fn install(
|
||||||
.unique_by(|download| download.key())
|
.unique_by(|download| download.key())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let retry_policy = client_builder.retry_policy();
|
||||||
// Python downloads are performing their own retries to catch stream errors, disable the
|
// Python downloads are performing their own retries to catch stream errors, disable the
|
||||||
// default retries to avoid the middleware from performing uncontrolled retries.
|
// default retries to avoid the middleware from performing uncontrolled retries.
|
||||||
let retry_policy = ExponentialBackoff::builder().build_with_max_retries(retries_from_env()?);
|
|
||||||
let client = client_builder.retries(0).build();
|
let client = client_builder.retries(0).build();
|
||||||
|
|
||||||
let reporter = PythonDownloadReporter::new(printer, downloads.len() as u64);
|
let reporter = PythonDownloadReporter::new(printer, downloads.len() as u64);
|
||||||
|
|
|
||||||
|
|
@ -183,9 +183,9 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
||||||
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,
|
settings.network_settings.timeout,
|
||||||
)
|
settings.network_settings.retries,
|
||||||
.retries_from_env()?;
|
);
|
||||||
Some(
|
Some(
|
||||||
RunCommand::from_args(command, client_builder, *module, *script, *gui_script)
|
RunCommand::from_args(command, client_builder, *module, *script, *gui_script)
|
||||||
.await?,
|
.await?,
|
||||||
|
|
@ -456,9 +456,9 @@ 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,
|
globals.network_settings.timeout,
|
||||||
)
|
globals.network_settings.retries,
|
||||||
.retries_from_env()?;
|
);
|
||||||
|
|
||||||
match *cli.command {
|
match *cli.command {
|
||||||
Commands::Auth(AuthNamespace {
|
Commands::Auth(AuthNamespace {
|
||||||
|
|
|
||||||
|
|
@ -184,6 +184,7 @@ pub(crate) struct NetworkSettings {
|
||||||
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,
|
pub(crate) timeout: Duration,
|
||||||
|
pub(crate) retries: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NetworkSettings {
|
impl NetworkSettings {
|
||||||
|
|
@ -200,7 +201,6 @@ 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);
|
||||||
|
|
@ -225,7 +225,8 @@ impl NetworkSettings {
|
||||||
connectivity,
|
connectivity,
|
||||||
native_tls,
|
native_tls,
|
||||||
allow_insecure_host,
|
allow_insecure_host,
|
||||||
timeout,
|
timeout: environment.http_timeout,
|
||||||
|
retries: environment.http_retries,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -323,8 +323,21 @@ async fn install_http_retries() {
|
||||||
----- stdout -----
|
----- stdout -----
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
error: Failed to parse `UV_HTTP_RETRIES`
|
error: Failed to parse environment variable `UV_HTTP_RETRIES` with invalid value `foo`: invalid digit found in string
|
||||||
Caused by: invalid digit found in string
|
"
|
||||||
|
);
|
||||||
|
|
||||||
|
uv_snapshot!(context.filters(), context.pip_install()
|
||||||
|
.arg("anyio")
|
||||||
|
.arg("--index")
|
||||||
|
.arg(server.uri())
|
||||||
|
.env(EnvVars::UV_HTTP_RETRIES, "-1"), @r"
|
||||||
|
success: false
|
||||||
|
exit_code: 2
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
error: Failed to parse environment variable `UV_HTTP_RETRIES` with invalid value `-1`: invalid digit found in string
|
||||||
"
|
"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -338,8 +351,7 @@ async fn install_http_retries() {
|
||||||
----- stdout -----
|
----- stdout -----
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
error: Failed to parse `UV_HTTP_RETRIES`
|
error: Failed to parse environment variable `UV_HTTP_RETRIES` with invalid value `999999999999`: number too large to fit in target type
|
||||||
Caused by: number too large to fit in target type
|
|
||||||
"
|
"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -267,6 +268,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -468,6 +470,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -701,6 +704,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -903,6 +907,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -1081,6 +1086,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -1308,6 +1314,7 @@ fn resolve_index_url() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -1543,6 +1550,7 @@ fn resolve_index_url() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -1836,6 +1844,7 @@ fn resolve_find_links() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -2060,6 +2069,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -2243,6 +2253,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -2476,6 +2487,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -2732,6 +2744,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -2905,6 +2918,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -3078,6 +3092,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -3253,6 +3268,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -3447,6 +3463,7 @@ fn resolve_tool() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -3633,6 +3650,7 @@ fn resolve_poetry_toml() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -3840,6 +3858,7 @@ fn resolve_both() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -4086,6 +4105,7 @@ fn resolve_both_special_fields() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -4411,6 +4431,7 @@ fn resolve_config_file() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -4711,6 +4732,7 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -4887,6 +4909,7 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -5082,6 +5105,7 @@ fn allow_insecure_host() -> anyhow::Result<()> {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -5269,6 +5293,7 @@ fn index_priority() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -5504,6 +5529,7 @@ fn index_priority() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -5745,6 +5771,7 @@ fn index_priority() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -5981,6 +6008,7 @@ fn index_priority() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -6224,6 +6252,7 @@ fn index_priority() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -6460,6 +6489,7 @@ fn index_priority() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -6709,6 +6739,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -6875,6 +6906,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -7039,6 +7071,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -7205,6 +7238,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -7369,6 +7403,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -7534,6 +7569,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -7714,6 +7750,7 @@ fn preview_features() {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -7827,6 +7864,7 @@ fn preview_features() {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -7940,6 +7978,7 @@ fn preview_features() {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -8053,6 +8092,7 @@ fn preview_features() {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -8166,6 +8206,7 @@ fn preview_features() {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -8281,6 +8322,7 @@ fn preview_features() {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -8415,6 +8457,7 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -8589,6 +8632,7 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -8786,6 +8830,7 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -8958,6 +9003,7 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -9124,6 +9170,7 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -9291,6 +9338,7 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -9523,6 +9571,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -9641,6 +9690,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -9782,6 +9832,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -9898,6 +9949,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -10004,6 +10056,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -10111,6 +10164,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -10282,6 +10336,7 @@ fn build_isolation_override() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
@ -10451,6 +10506,7 @@ fn build_isolation_override() -> anyhow::Result<()> {
|
||||||
native_tls: false,
|
native_tls: false,
|
||||||
allow_insecure_host: [],
|
allow_insecure_host: [],
|
||||||
timeout: [TIME],
|
timeout: [TIME],
|
||||||
|
retries: 3,
|
||||||
},
|
},
|
||||||
concurrency: Concurrency {
|
concurrency: Concurrency {
|
||||||
downloads: 50,
|
downloads: 50,
|
||||||
|
|
|
||||||
|
|
@ -885,8 +885,6 @@ fn seed_older_python_version() {
|
||||||
#[test]
|
#[test]
|
||||||
fn create_venv_with_invalid_http_timeout() {
|
fn create_venv_with_invalid_http_timeout() {
|
||||||
let context = TestContext::new_with_versions(&["3.12"]).with_http_timeout("not_a_number");
|
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()
|
uv_snapshot!(context.filters(), context.venv()
|
||||||
.arg(context.venv.as_os_str())
|
.arg(context.venv.as_os_str())
|
||||||
.arg("--python")
|
.arg("--python")
|
||||||
|
|
@ -896,15 +894,13 @@ fn create_venv_with_invalid_http_timeout() {
|
||||||
----- stdout -----
|
----- stdout -----
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
error: Failed to parse environment variable `UV_HTTP_TIMEOUT` with invalid value `not_a_number`: expected an integer
|
error: Failed to parse environment variable `UV_HTTP_TIMEOUT` with invalid value `not_a_number`: invalid digit found in string
|
||||||
"###);
|
"###);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn create_venv_with_invalid_concurrent_installs() {
|
fn create_venv_with_invalid_concurrent_installs() {
|
||||||
let context = TestContext::new_with_versions(&["3.12"]).with_concurrent_installs("0");
|
let context = TestContext::new_with_versions(&["3.12"]).with_concurrent_installs("0");
|
||||||
|
|
||||||
// Create a virtual environment at `.venv`.
|
|
||||||
uv_snapshot!(context.filters(), context.venv()
|
uv_snapshot!(context.filters(), context.venv()
|
||||||
.arg(context.venv.as_os_str())
|
.arg(context.venv.as_os_str())
|
||||||
.arg("--python")
|
.arg("--python")
|
||||||
|
|
@ -914,7 +910,7 @@ fn create_venv_with_invalid_concurrent_installs() {
|
||||||
----- stdout -----
|
----- stdout -----
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
error: Failed to parse environment variable `UV_CONCURRENT_INSTALLS` with invalid value `0`: expected a non-zero positive integer
|
error: Failed to parse environment variable `UV_CONCURRENT_INSTALLS` with invalid value `0`: number would be zero for non-zero type
|
||||||
"###);
|
"###);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue