From d6e484497688b69560f0cbdb06bcbc18f02250b8 Mon Sep 17 00:00:00 2001 From: Emma Smith Date: Wed, 28 May 2025 14:18:34 -0700 Subject: [PATCH 1/2] gh-134262: Add retries to downloads in PCbuild\get_external.py (GH-134820) (cherry picked from commit e9d845b41dca9ad84b76ef777d05e647a4b4d8cd) Co-authored-by: Emma Smith --- PCbuild/get_external.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/PCbuild/get_external.py b/PCbuild/get_external.py index 4ecc8925349c93..99aff63882f5ba 100755 --- a/PCbuild/get_external.py +++ b/PCbuild/get_external.py @@ -9,6 +9,25 @@ from urllib.request import urlretrieve +def retrieve_with_retries(download_location, output_path, reporthook, + max_retries=7): + """Download a file with exponential backoff retry and save to disk.""" + for attempt in range(max_retries): + try: + resp = urlretrieve( + download_location, + output_path, + reporthook=reporthook, + ) + except ConnectionError as ex: + if attempt == max_retries: + msg = f"Download from {download_location} failed." + raise OSError(msg) from ex + time.sleep(2.25**attempt) + else: + return resp + + def fetch_zip(commit_hash, zip_dir, *, org='python', binary=False, verbose): repo = f'cpython-{"bin" if binary else "source"}-deps' url = f'https://github.com/{org}/{repo}/archive/{commit_hash}.zip' @@ -16,10 +35,10 @@ def fetch_zip(commit_hash, zip_dir, *, org='python', binary=False, verbose): if verbose: reporthook = print zip_dir.mkdir(parents=True, exist_ok=True) - filename, headers = urlretrieve( + filename, _headers = retrieve_with_retries( url, zip_dir / f'{commit_hash}.zip', - reporthook=reporthook, + reporthook ) return filename From 84a943d85d81fff22e1c6b52d842ef7c4244e090 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Wed, 28 May 2025 18:21:42 -0500 Subject: [PATCH 2/2] Fix off-by-one (cherry-picked from e64395e8eb8d3a9e35e3e534e87d427ff27ab0a5) --- PCbuild/get_external.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PCbuild/get_external.py b/PCbuild/get_external.py index 99aff63882f5ba..8c1155c74a642c 100755 --- a/PCbuild/get_external.py +++ b/PCbuild/get_external.py @@ -12,7 +12,7 @@ def retrieve_with_retries(download_location, output_path, reporthook, max_retries=7): """Download a file with exponential backoff retry and save to disk.""" - for attempt in range(max_retries): + for attempt in range(max_retries + 1): try: resp = urlretrieve( download_location,