🐛 fix(win): restore best-effort lock file cleanup on release#511
Merged
gaborbernat merged 2 commits intotox-dev:mainfrom Mar 9, 2026
Merged
🐛 fix(win): restore best-effort lock file cleanup on release#511gaborbernat merged 2 commits intotox-dev:mainfrom
gaborbernat merged 2 commits intotox-dev:mainfrom
Conversation
In version 3.25.0, PR tox-dev#484 removed lock file cleanup on Windows to fix threading race conditions where unlink() would fail when other threads held open handles. This created a regression where single-threaded usage (the common case) left orphaned lock files, breaking user expectations and diverging from Unix behavior where lock files are cleaned up. Restore opportunistic cleanup with suppressed OSError. This provides the expected behavior for single-threaded scenarios where the file deletes successfully after close(), while gracefully handling multi-threaded failures by silently suppressing deletion errors when other threads hold handles. The suppressed exception preserves thread-safety from PR tox-dev#484 while fixing the orphaned lock file issue for typical usage.
Added documentation clarifying that Windows lock file cleanup is best-effort and not guaranteed in multi-threaded scenarios, while Unix and macOS provide reliable cleanup. This helps users understand the expected behavior and avoid confusion when lock files persist on Windows. Documentation updated in: - Platform-specific details section in concepts.rst - WindowsFileLock and UnixFileLock class docstrings
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Version 3.25.0 introduced a regression on Windows where lock files were no longer cleaned up after release, leaving orphaned
.lockfiles on disk. 🗑️ Users upgrading from 3.18.0 reported that their single-threaded applications now leave persistent lock files, breaking the expected behavior and diverging from how Unix platforms work (where lock files are cleaned up).The regression came from PR #484, which removed the
unlink()call to fix threading race conditions. While that fix correctly addressed multi-threaded scenarios where Windows cannot delete files with open handles, it sacrificed cleanup for the common single-threaded use case where deletion would succeed.This fix restores opportunistic cleanup by attempting to unlink the lock file after closing it, with errors suppressed via
suppress(OSError). ✨ In single-threaded scenarios, the file deletes successfully and users get the expected behavior. In multi-threaded scenarios where other threads hold handles, the deletion fails silently and the lock file persists, preserving the thread-safety guarantees from PR #484.The test suite is updated to remove the Windows skip condition from
test_lock_file_removed_after_release, as Windows now supports cleanup in typical usage patterns.Closes #509