Enable mirror for python-build-standalone downloads (#5719)

## Summary

This came up again recently, so decided to do it real quick.

Closes https://github.com/astral-sh/uv/issues/5224.
This commit is contained in:
Charlie Marsh 2024-08-07 21:34:19 -04:00 committed by GitHub
parent 9081509715
commit f7110e0a07
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 67 additions and 8 deletions

View file

@ -36,10 +36,10 @@ pub enum Error {
InvalidPythonVersion(String),
#[error("Invalid request key (too many parts): {0}")]
TooManyParts(String),
#[error("Download failed")]
#[error(transparent)]
NetworkError(#[from] WrappedReqwestError),
#[error("Download failed")]
NetworkMiddlewareError(#[source] anyhow::Error),
#[error(transparent)]
NetworkMiddlewareError(#[from] anyhow::Error),
#[error("Failed to extract archive: {0}")]
ExtractError(String, #[source] uv_extract::Error),
#[error("Failed to hash installation")]
@ -70,6 +70,10 @@ pub enum Error {
InvalidRequestPlatform(#[from] platform::Error),
#[error("No download found for request: {}", _0.green())]
NoDownloadFound(PythonDownloadRequest),
#[error(
"A mirror was provided via `{0}`, but the URL does not match the expected format: {0}"
)]
Mirror(&'static str, &'static str),
}
#[derive(Debug, PartialEq)]
@ -410,7 +414,7 @@ impl ManagedPythonDownload {
cache: &Cache,
reporter: Option<&dyn Reporter>,
) -> Result<DownloadResult, Error> {
let url = Url::parse(self.url)?;
let url = self.download_url()?;
let path = parent_path.join(self.key().to_string());
// If it already exists, return it
@ -433,8 +437,8 @@ impl ManagedPythonDownload {
let temp_dir = tempfile::tempdir_in(cache.root()).map_err(Error::DownloadDirError)?;
debug!(
"Downloading {url} to temporary location {}",
temp_dir.path().display()
"Downloading {url} to temporary location: {}",
temp_dir.path().simplified().display()
);
let stream = response
@ -525,6 +529,41 @@ impl ManagedPythonDownload {
pub fn python_version(&self) -> PythonVersion {
self.key.version()
}
/// Return the [`Url`] to use when downloading the distribution. If a mirror is set via the
/// appropriate environment variable, use it instead.
fn download_url(&self) -> Result<Url, Error> {
match self.key.implementation {
LenientImplementationName::Known(ImplementationName::CPython) => {
if let Ok(mirror) = std::env::var("UV_PYTHON_INSTALL_MIRROR") {
let Some(suffix) = self.url.strip_prefix(
"https://github.com/indygreg/python-build-standalone/releases/download/",
) else {
return Err(Error::Mirror("UV_PYTHON_INSTALL_MIRROR", self.url));
};
return Ok(Url::parse(
format!("{}/{}", mirror.trim_end_matches('/'), suffix).as_str(),
)?);
}
}
LenientImplementationName::Known(ImplementationName::PyPy) => {
if let Ok(mirror) = std::env::var("UV_PYPY_INSTALL_MIRROR") {
let Some(suffix) = self.url.strip_prefix("https://downloads.python.org/pypy/")
else {
return Err(Error::Mirror("UV_PYPY_INSTALL_MIRROR", self.url));
};
return Ok(Url::parse(
format!("{}/{}", mirror.trim_end_matches('/'), suffix).as_str(),
)?);
}
}
_ => {}
}
Ok(Url::parse(self.url)?)
}
}
impl From<reqwest::Error> for Error {