]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] gh-134262: Add retries to generate_sbom.py (GH-134460)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Wed, 28 May 2025 23:52:31 +0000 (01:52 +0200)
committerGitHub <noreply@github.com>
Wed, 28 May 2025 23:52:31 +0000 (23:52 +0000)
(cherry picked from commit 0c5a8b0b55238a45b9073d06a10c3a59568cdf3c)

Includes fix for off-by-one error from GH-134867
(cherry-picked from commit e64395e8eb8d3a9e35e3e534e87d427ff27ab0a5)

Co-authored-by: Emma Smith <emma@emmatyping.dev>
Co-authored-by: Semyon Moroz <donbarbos@proton.me>
Tools/build/generate_sbom.py

index db01426e9722c3d5a1baa677ee1aa76c9c8761ef..89f8f83999c47e1440ba5ea8d5d5ddd679989aaf 100644 (file)
@@ -7,7 +7,9 @@ import os
 import re
 import subprocess
 import sys
+import time
 import typing
+import urllib.error
 import urllib.request
 from pathlib import Path, PurePosixPath, PureWindowsPath
 
@@ -161,6 +163,21 @@ def get_externals() -> list[str]:
     return externals
 
 
+def download_with_retries(download_location: str,
+                          max_retries: int = 5,
+                          base_delay: float = 2.0) -> typing.Any:
+    """Download a file with exponential backoff retry."""
+    for attempt in range(max_retries + 1):
+        try:
+            resp = urllib.request.urlopen(download_location)
+        except urllib.error.URLError as ex:
+            if attempt == max_retries:
+                raise ex
+            time.sleep(base_delay**attempt)
+        else:
+            return resp
+
+
 def check_sbom_packages(sbom_data: dict[str, typing.Any]) -> None:
     """Make a bunch of assertions about the SBOM package data to ensure it's consistent."""
 
@@ -175,7 +192,7 @@ def check_sbom_packages(sbom_data: dict[str, typing.Any]) -> None:
         # and that the download URL is valid.
         if "checksums" not in package or "CI" in os.environ:
             download_location = package["downloadLocation"]
-            resp = urllib.request.urlopen(download_location)
+            resp = download_with_retries(download_location)
             error_if(resp.status != 200, f"Couldn't access URL: {download_location}'")
 
             package["checksums"] = [{