-
-
Notifications
You must be signed in to change notification settings - Fork 127
Comparing changes
Open a pull request
base repository: tox-dev/filelock
base: 3.23.0
head repository: tox-dev/filelock
compare: 3.24.0
- 8 commits
- 15 files changed
- 2 contributors
Commits on Feb 14, 2026
-
🐛 fix(unix): auto-fallback to SoftFileLock on ENOSYS (#480)
On platforms like Android/Termux and network filesystems (NFS, CIFS), fcntl imports fine but flock() fails at runtime with ENOSYS. Previously this raised NotImplementedError, leaving users no recourse except monkey-patching filelock.FileLock before any other imports. Now UnixFileLock catches ENOSYS, cleans up the leftover lock file, and swaps __class__ to SoftFileLock (or AsyncSoftFileLock for async instances). Both classes share the same BaseFileLock layout with no extra instance state, so the swap is safe and preserves all context. Subsequent acquire/release calls go straight through the soft path. Fixes #289, fixes #349
Configuration menu - View commit details
-
Copy full SHA for 7dfdb02 - Browse repository at this point
Copy the full SHA 7dfdb02View commit details -
✨ feat(lock): add poll_interval to constructor (#482)
Previously poll_interval was hardcoded to 0.05s in acquire() and could not be configured when using locks as context managers since __enter__ calls acquire() without arguments. This follows the existing pattern for timeout and blocking: store the default on FileLockContext, accept it in __init__, expose a property, and fall back to it in acquire() when None is passed. Both sync and async lock variants are updated. Closes #400
Configuration menu - View commit details
-
Copy full SHA for 79ca84f - Browse repository at this point
Copy the full SHA 79ca84fView commit details -
🐛 fix(win): eliminate lock file race in threaded usage (#484)
On Windows, _release() called unlink() after close(), but between those calls another thread would already hold an open handle via os.open(), preventing deletion (Windows can't delete files with open handles). The suppressed unlink added a syscall that widened the race window for no benefit. Additionally, O_TRUNC in _acquire() mapped to CREATE_ALWAYS which caused EACCES when truncating a file with open handles from other threads, pushing them into the retry loop at the os.open level. Remove unlink() from _release() — the lock file persists on disk but _acquire() already handles existing files via O_CREAT. Remove O_TRUNC from _acquire() — lock file content is irrelevant, only the msvcrt byte-range lock matters. This lets the threaded tests run at full Unix-equivalent intensity on Windows.
Configuration menu - View commit details
-
Copy full SHA for 23b797c - Browse repository at this point
Copy the full SHA 23b797cView commit details -
✨ feat(mode): respect POSIX default ACLs (#378) (#483)
Directories with default ACLs (setfacl -d) expect newly created files to inherit those permissions. The hardcoded mode=0o644 and fchmod call were preventing this by overriding the OS permission machinery. Introduce a sentinel default so that when no explicit mode is passed, lock files are created with 0o666 (letting umask and default ACLs control final permissions) and fchmod is skipped. When mode is explicitly set, the existing behavior (fchmod enforcement) is preserved. This resolves multi-user shared directory workflows without changing behavior for users who don't use ACLs.
Configuration menu - View commit details
-
Copy full SHA for 57251e9 - Browse repository at this point
Copy the full SHA 57251e9View commit details -
🐛 fix(api): detect same-thread self-deadlock (#481)
Add a per-thread registry that tracks which canonical lock paths are held. When a second FileLock instance on the same path attempts a blocking acquire in the same thread, raise RuntimeError instead of hanging. Use os.path.abspath on Windows for canonical paths since os.path.realpath opens handles via CreateFileW with share_mode=0, which blocks concurrent unlink and livelocks SoftFileLock under threaded contention.
Configuration menu - View commit details
-
Copy full SHA for fa6a27b - Browse repository at this point
Copy the full SHA fa6a27bView commit details -
✨ feat(lock): add cancel_check to acquire (#309) (#487)
Lock acquisition can now be cancelled for arbitrary reasons beyond simple timeouts. The new cancel_check callable parameter is polled each iteration of the retry loop and raises Timeout when it returns True. This allows callers to wire up threading.Event, shutdown flags, or any other cancellation mechanism without coupling filelock to a specific library.
Configuration menu - View commit details
-
Copy full SHA for 6c75bf7 - Browse repository at this point
Copy the full SHA 6c75bf7View commit details -
✨ feat(lock): add lifetime parameter for lock expiration (#68) (#486)
Stale lock files left behind by crashed processes can block other processes indefinitely. The new `lifetime` parameter lets callers declare the maximum age of a lock file before it is considered expired. On each acquisition attempt the lock file's mtime is compared against the configured lifetime. When expired, the file is atomically renamed then unlinked so only one competing process wins the break. All errors during the check are suppressed to avoid disrupting normal operation.
Configuration menu - View commit details
-
Copy full SHA for d429e18 - Browse repository at this point
Copy the full SHA d429e18View commit details -
Configuration menu - View commit details
-
Copy full SHA for 2de9380 - Browse repository at this point
Copy the full SHA 2de9380View commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff 3.23.0...3.24.0