Skip to content

Clean up temporary files when closing a rewrite fails - #721

Open
FanWu-ai wants to merge 1 commit into
theskumar:mainfrom
FanWu-ai:fix/cleanup-temp-close-error
Open

FanWu-ai wants to merge 1 commit into
theskumar:mainfrom
FanWu-ai:fix/cleanup-temp-close-error

Conversation

@FanWu-ai

@FanWu-ai FanWu-ai commented Oct 5, 2026

Copy link
Copy Markdown

Summary

Clean up the temporary file when rewrite() fails while closing its buffered output. The cleanup scope now includes the temporary-file context manager's exit, while preserving the original target and propagating the error.

A write can be buffered successfully and fail only during close (for example, when the filesystem reports a size limit). Previously, that exception escaped before _discard_temp_file(), leaving a partial .tmp_* file behind after set_key() or unset_key().

Changes

  • Include close, mode restoration, and replacement in the existing best-effort cleanup scope.
  • Keep temporary-file cleanup after the handle is closed.
  • Add three close-failure regression cases for creating, updating, and deleting keys, plus two guards for ordinary exceptions and KeyboardInterrupt.
  • Add a changelog entry.

Reproduction and related work

An isolated Linux subprocess with RLIMIT_FSIZE=3 and SIGXFSZ ignored reproduces a real close-time EFBIG without mocking file I/O. Creating a new file, updating an existing file, and removing a key each leave one partial temporary file on the base; this patch leaves none. The original target remains unchanged in all cases.

This extends the cleanup introduced in #686. It also covers a failure boundary still present with the flush/fsync change proposed in #717: a repeated buffered-write failure during context exit can escape its inner cleanup scope.

Validation

Against main at 0b2880591780a426b0551436f47a17e7a76d954f:

  • Full unmodified baseline suite on Linux/Python 3.10, 3.12, 3.13, and 3.14: 288 passed per interpreter, zero skipped.
  • Full patched suite on the same four interpreters: 293 passed per interpreter, zero skipped.
  • Five added cases: three close-failure regressions fail on the base and pass with this patch; the two body-error guards pass on both.
  • Ruff lint and format, mypy targets 3.10 through 3.14, pinned pre-commit hooks, check-manifest, strict MkDocs build, and isolated sdist/wheel build all pass.

Windows, PyPy, Python 3.11, and free-threaded runtime coverage are left to upstream CI; the local runtime results above are Linux only.

AI assistance: this patch, tests, and description were prepared and checked with OpenAI Codex. Submitted as a draft for human review.

@FanWu-ai
FanWu-ai marked this pull request as ready for review October 5, 2026 04:56

This branch has not been deployed

No deployments
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.

1 participant