Skip to content

fix: remove potential partial cache-population in case of error - #2892

Merged
henryiii merged 1 commit into
pypa:mainfrom
mayeut:cleanup-on-error
Jun 5, 2026
Merged

henryiii merged 1 commit into
pypa:mainfrom
mayeut:cleanup-on-error

Conversation

@mayeut

@mayeut mayeut commented Jun 3, 2026

Copy link
Copy Markdown
Member

This address the "Resource Management & Concurrency" section of #2854

🤖 AI text below 🤖

This PR introduces a shared “cleanup on error” mechanism intended to prevent partially-populated cache entries (and related artifacts) from being left behind when downloads/extractions/install steps fail, and applies it across several cache-population code paths.

Changes:

  • Added a remove_on_error context manager in cibuildwheel.util.file to delete a target path if an exception occurs.
  • Wrapped multiple cache-population operations (downloads, nuget installs, pyodide xbuildenv installs, etc.) with remove_on_error to clean up partial cache state on failure.
  • Added unit tests covering keep-vs-remove behavior for files and directories.

Co-Authored-By: Copilot <198982749+Copilot@users.noreply.github.com>
@@ -140,8 +146,9 @@ def install_target_cpython(tmp: Path, config: PythonConfiguration, free_threadin
if not installation_path.exists():
downloaded_tar_gz = tmp / ios_python_tar_gz
download(config.url, downloaded_tar_gz, sha256=config.sha256)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the download call have a remove_on_error wrapper as well? (macOS has the same pattern)

More generally - is there any reason that download() shouldn't incorporate remove_on_error handling? Is there any use case for downloading and preserving a failed download?

@mayeut mayeut Jun 3, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All non-cache persisted download cases should be downloads to a temp directory -as is the case here - which is already taken care of when cibuildwheel exits.
I prefer the consistency of FileLock+remove_on_error always appearing together when it comes to preventing cache pollution, even if the download helper was updated with remove_on_error.
I consider that updating download might be worthwhile but orthogonal to the issue being fixed here and if it were updated, I'd rather keep the FileLock+remove_on_error consistency and be in a "belt and braces" situation in case like:

diff --git a/cibuildwheel/platforms/windows.py b/cibuildwheel/platforms/windows.py
index 7dbd3a56..f55fc54d 100644
@@ -112,7 +113,8 @@ def _ensure_nuget() -> Path:
     nuget = CIBW_CACHE_PATH / "nuget.exe"
     with FileLock(str(nuget) + ".lock"):
         if not nuget.exists():
-            download("https://dist.nuget.org/win-x86-commandline/latest/nuget.exe", nuget)
+            with remove_on_error(nuget):
+                download("https://dist.nuget.org/win-x86-commandline/latest/nuget.exe", nuget)
     return nuget
 
 

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah - I missed the intersection of this with tmp usage. In which case - ignore my comment.

@mayeut mayeut changed the title fix: remove potential partial extraction in case of error fix: remove potential cache-population in case of error Jun 3, 2026
@mayeut mayeut changed the title fix: remove potential cache-population in case of error fix: remove potential partial cache-population in case of error Jun 3, 2026

@agriyakhetarpal agriyakhetarpal left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Comment thread cibuildwheel/platforms/pyodide.py

@mhsmith mhsmith left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Android changes look fine to me.

@henryiii
henryiii merged commit 6cd2d19 into pypa:main Jun 5, 2026
45 checks passed
@mayeut
mayeut deleted the cleanup-on-error branch August 8, 2026 07:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants