NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #44 most downloaded on PyPI
A platform independent file lock.
Last release today
03 Oct 2026
Release timing varies
gaps range from 8 days to 2 months
Nearly every release is documented
notes for 60 of the last 60 stable releases
2 versions withdrawn
withdrawn after publishing
12 years old
128 releases · first in 2014
♻️ refactor(util): test helpers via public locks by @gaborbernat in #764
Full Changelog: 4.0.9...4.0.10
Reusing a singleton AsyncFileLock with another loop, executor or run_in_executor, or a singleton SoftFileLease with another lease_duration, heartbeat_interval or on_compromise, now raises ValueError instead of returning the lock with its original options. 765
One column per quarter.
📝 docs(util): correct write and break guarantees by @pralav-25 in #762
Full Changelog: 4.0.8...4.0.9
ReadWriteLock and AsyncReadWriteLock close the descriptor that checks the database path once SQLite has connected, so on PyPy a dropped lock leaves no descriptor open until garbage collection runs. 763
ReadWriteLock and AsyncReadWriteLock refuse a symlink at the database path instead of following it, so a user who can create names in a shared lock directory cannot point the lock at another file (GHSA-j8f7-rjxc-mr56).
🐛 fix(read-write): refuse cross-thread write release by @feiiiiii5 in #761
Full Changelog: 4.0.7...4.0.8
ReadWriteLock.release() and SoftReadWriteLock.release() from a thread that does not hold the write lock now raise RuntimeError instead of dropping the holder's lock and letting a second writer in. 761
🐛 fix(mode): require owner read and write by @gaborbernat in #760
Full Changelog: 4.0.6...4.0.7
File locks now raise ValueError at construction when mode denies the owner read or write, such as mode=0o444, instead of failing on a later acquire and staying broken until someone deletes the lock file. 760
fix(read-write): validate reentrant timeouts by @feiiiiii5 in #756
Full Changelog: 4.0.5...4.0.6
Reject negative blocking timeouts other than -1 before reentrant ReadWriteLock and SoftReadWriteLock acquisition. Preserve unlimited waits and nonblocking acquisition. 756
fix(marker): preserve live owners by @DawnofGenX in #751
Full Changelog: 4.0.4...4.0.5
Fix MarkerSoftFileLock acquisition and prevent contenders from evicting live protocol-2 owners after two seconds. Reclaim recognized records after owner death; preserve unknown contracts. 749
Honor instance timeout and blocking settings in sync and async ReadWriteLock acquisition, including waits between tasks on one instance. Preserve explicit per-call overrides. 750
Skip access-denial checks when the process can read mode-0o000 files. Keep mode-bit checks enabled for privileged processes on filesystems that support POSIX permissions. 753
Skip vanished StrictSoftFileLock claims after a read-permission retry expires. Recheck the directory before raising a protocol error so concurrent removal does not turn a stale claim listing into an acquisition failure. 754
Reject negative timeouts other than -1 in blocking AsyncReadWriteLock and AsyncSoftReadWriteLock acquisitions. Keep -1 as an unlimited wait and ignore timeouts when blocking=False. 755
🐛 fix(identity): digest the cut tail of long hostnames by @feiiiiii5 in #748
Full Changelog: 4.0.3...4.0.4
Hostnames that still differ after their first 253 escaped characters now publish distinct owners, so a soft lock no longer takes another such host's live holder for its own and reclaims its marker. 748
🐛 fix(api): skip the fork audit hook on CPython <3.12 by @gaborbernat in #747
Full Changelog: 4.0.2...4.0.3
Importing filelock on CPython 3.10 or 3.11 no longer makes new threads fail with RuntimeError: Cannot install a trace function while another trace function is being installed under coverage or a debugger. filelock skips its fork-safety audit hook there, so forking from inside a thread's own lock-state transition no longer raises immediately on those versions. 747
docs: create the data directory in the async cache example by @agammann in #740
Full Changelog: 4.0.1...4.0.2
Concurrent acquire() and release() on a thread_local=False lock no longer leak the OS lock, close a descriptor twice, drop a lease token, or leave a false deadlock after a cross-thread release (744). 745
~filelock.AsyncReadWriteLock and ~filelock.AsyncSoftReadWriteLock now give each asyncio task its own hold, so tasks sharing one instance no longer enter the write lock together. 746
Correct the async cache example to create its data directory and clarify automatic creation of lock-file parent directories. 740
Exclude sphinx-llm 1.1.0 from documentation dependencies because its Markdown builder emits unknown-node warnings. 742
fix: reject invalid poll_interval before sleep by @Pitchfork-and-Torch in #739
Full Changelog: 4.0.0...4.0.1
poll_interval is now validated at construction, on the setter, and on acquire(): a negative, non-finite, or non-numeric value raises ValueError/TypeError immediately instead of failing inside time.sleep. 739
🐛 fix(soft-rw): replace the state mutex with a generation log by @gaborbernat in #738
Full Changelog: 3.32.7...4.0.0
The ~filelock.SoftReadWriteLock on-disk protocol is a generation log under <path>.rw, and a process running an earlier release does not see it: an old and a new participant on one lock path do not exclude each other. Stop every participant, upgrade them all, then restart them; the new code ignores leftover .state, .write and .readers/ files, and you can delete them. The filesystem must provide no-replace hard links, as it must for ~filelock.StrictSoftFileLock, so a runtime without os.link raises ~filelock.SoftFileLockProtocolError on acquire. Constructing a singleton again with a different on_compromise, or with poll_interval at or above stale_threshold, now raises ValueError. 735
~filelock.SoftReadWriteLock exposes ~filelock.SoftReadWriteLock.generation as a fencing token for the protected resource and reports a lost hold through on_compromise and ~filelock.SoftReadWriteLock.compromise. 735
~filelock.SoftReadWriteLock no longer deadlocks when a holder dies on another host mid-transition, and release() no longer waits on a mutex a dead host left behind (725, 735). The state mutex is gone. Each transition is one atomic snapshot commit, and liveness is a heartbeat nonce read on the observer's own clock rather than an mtime read against another host's. 735
Fix final symlink test on musl by @lprnmns in #737
Validate final-symlink refusal by error number so the test works across libc implementations. 737
Document that ~filelock.BaseFileLock.acquire reads blocking=None as the lock's blocking attribute and raises ~filelock.Timeout after one attempt when blocking=False. 733
🐛 fix(lease): reject a duration no marker can carry by @lprnmns in #723
Full Changelog: 3.32.5...3.32.6
SoftFileLease and AsyncSoftFileLease now reject a boolean or non-finite lease_duration, which used to publish an owner record their own owner property reads back as malformed. 723
Reject non-finite heartbeat, stale, and polling intervals in SoftReadWriteLock and AsyncSoftReadWriteLock, including cached singleton construction and overflow in the default stale threshold. 724
Honor acquisition timeouts and blocking=False during SoftReadWriteLock state-mutex contention, including failed writer cleanup. Cross-host recovery of an abandoned .state marker remains unsupported. 726
Allow acquiring existing lock files that grant write access through group permissions or an ACL even when their owner-write mode bit is unset. 728
Preserve exception notes and custom attributes when copying or pickling Timeout and SoftFileLockProtocolError. 729
🧪 test(fork): report where a stalled fork stops by @gaborbernat in #715
Full Changelog: 3.32.4...3.32.5
SoftFileLease.token and AsyncSoftFileLease.token now read None after a failed acquisition, so a contender turned away by a live holder no longer reports a token for a claim it never published. 721
Document that mode has no setter: unlike poll_interval, timeout, blocking and lifetime, it is fixed at construction and lock.mode = ... raises AttributeError. 716
🐛 fix: retry transient denials on open and claim read by @gaborbernat in #705
Full Changelog: 3.32.3...3.32.4
StrictSoftFileLock always retries a claim read whose first attempt reports the claim as pending, so a first read that itself outlasts the retry grace no longer fails closed on a claim it could have read. 705
WindowsFileLock waits out a transient STATUS_ACCESS_DENIED from NtCreateFile for up to half a second before raising PermissionError, since a peer unlinking the lock file as it releases can answer that for a moment; a real denial still fails fast. 705
Every lock class now escapes the hostname it publishes, so a host whose socket.gethostname() carries a space, a newline or a byte outside UTF-8 no longer writes a marker it reads back as malformed. Such a host used to lose a held SoftReadWriteLock read slot to a peer and could not take a write slot or a StrictSoftFileLock at all. 709
🧪 test(strict): deflake close-fault injections on graalpy by @gaborbernat in #697
Full Changelog: 3.32.2...3.32.3
The fork-safety audit hook no longer prints Exception ignored in audit hook with a TypeError when an audit event fires during interpreter shutdown, after CPython has already cleared the module globals. 701
Fix test failures on NetBSD ( #689 ) by @gaborbernat in #693
Full Changelog: 3.32.1...3.32.2
A SoftReadWriteLock or SoftFileLease acquire whose heartbeat thread fails to start now unlinks its marker and hands the claim back, instead of leaving an unrefreshed marker a peer takes while the caller believes it still holds the lock. 691
👷 ci: add Python 3.15 to the test matrix by @gaborbernat in #683
Full Changelog: 3.31.2...3.32.0
SoftReadWriteLock closes the directory handle it opens to scan for readers as soon as a scan stops early, rather than holding it until the generator is collected. 685
Declare support for Python 3.15 and run the test suite against it and its free-threaded build, both currently in beta. 683
The source distribution ships the capability probes the tests import, and reading one no longer needs coverage installed, so the suite runs from an unpacked sdist instead of failing on a missing coverage_pragmas. 685
🐛 fix(strict): tolerate an errno without ENOTSUP by @gaborbernat in #681
Full Changelog: 3.31.1...3.31.2
filelock imports again on runtimes whose errno omits ENOTSUP, such as GraalPy, where importing the package raised ImportError. It probes the code instead, preferring ENOTSUP, falling back to EOPNOTSUPP where that name is absent, and dropping to ENOSYS/EXDEV where neither exists. Platforms defining ENOTSUP keep their behavior. 681
♻️ refactor(coverage): key exclusions on probed capability by @gaborbernat in #679
Full Changelog: 3.31.0...3.31.1
A SoftFileLease acquired on one thread keeps its claim when another thread fails to acquire the same lease object, so its heartbeat carries on refreshing the marker instead of being torn down and letting a peer take the live claim. 680
✨ feat(platform): support Termux/Android by @gaborbernat in #678
Full Changelog: 3.30.3...3.31.0
Support Termux/Android, whose CPython ships without os.link and reports sys.platform == "android". import filelock and both FileLock and SoftFileLock now work there, StrictSoftFileLock reports its missing hard-link support only when acquired, and process liveness reads /proc on Android instead of PID-only checks. 678
StrictSoftFileLock no longer lets two processes hold the lock at once under heavy contention. A holder now keeps its intent claim for the whole hold, so a contender whose directory scan races the holder's freshly linked claim can no longer miss it and win alongside it. A held lock now exposes both an intent and a held claim. 678
Keep both tables of contents on screen at any browser font size by @gaborbernat in #673
Full Changelog: 3.30.2...3.30.3
AsyncFileLock and AsyncSoftFileLock no longer raise a deadlock RuntimeError when a different asyncio task waits for a lock they hold; the check now scopes holders to the owning task, so only a same-task reacquire is refused. 676
Keep both tables of contents on screen at any browser font size. The widened body column sized itself in em against the reader's font size while the breakpoints that fold the layout resolve em against a fixed 16px, so a reader whose default font is larger than 16px had the right-hand table of contents clipped off the edge. The body column now flexes instead, and the right-hand table of contents hides only at the mobile breakpoint. 673
Color the mermaid diagrams from whichever theme is active. They previously carried a light palette baked into each diagram's source, which stayed light on a dark page. 674
Document every lock type, and stop evicting a marker we cannot read by @gaborbernat in #672
Full Changelog: 3.30.1...3.30.2
Stop ~filelock.SoftFileLease deleting a live marker whose mode it does not implement. An unrecognized mode now names its owner instead of reading as malformed, so a record written by a newer filelock survives the grace window rather than being evicted after two seconds. 672
Stop ~filelock.StrictSoftFileLock and ~filelock.AsyncStrictSoftFileLock calling themselves a native OS lock when they warn that they ignore lifetime; they now say a strict claim is only ever cleared by force_break(). 672
Cover every lock type in the tutorials and how-to guides, with examples drawn from projects that use filelock, and color the mermaid diagrams. Correct the claims that StrictSoftFileLock exposes owner, that ~filelock.SoftFileLock evicts a strict sentinel, that ~filelock.ReadWriteLock requires a .db extension, and that every log record is DEBUG. 672
<!-- Release notes generated using configuration in .github/release.yaml at 3.30.1 -->
<!-- Release notes generated using configuration in .github/release.yaml at 3.30.1 -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.30.0...3.30.1
StrictSoftFileLock and AsyncStrictSoftFileLock no longer abort acquisition when a peer's claim vanishes as an NFSv3 stale filehandle instead of a clean removal; the reader revalidates and skips it, so strict locks hold mutual exclusion across independent NFSv3 client caches. 669
SoftFileLease reads a marker whose lease duration is nan or inf as malformed rather than as a valid lease, so such a marker ages out through the grace window instead of raising LeaseSettingsMismatch on every contender. 670
<!-- Release notes generated using configuration in .github/release.yaml at 3.30.0 -->
<!-- Release notes generated using configuration in .github/release.yaml at 3.30.0 -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.29.7...3.30.0
Add context_error_policy to surface body and release failures as a BaseExceptionGroup. 618
Add close_error_policy to control an os.close failure after the OS unlock. 619
Add ~filelock.lock_descriptor and ~filelock.unlock_descriptor to lock a caller-owned file descriptor. 620
Add fallback_to_soft to fail closed instead of downgrading to ~filelock.SoftFileLock on ENOSYS. 622
Add preserve_lock_file so native locks keep the lock pathname on release. 624
Add an on_acquired hook that runs a callback on the locked descriptor once the lock is held. 625
Add StrictSoftFileLock, which treats every marker it did not publish as contention, and SoftFileLease, whose claim expires and whose holder learns through on_compromise when it is lost. SoftFileLock(lifetime=...) now warns and names them. Both publish a record SoftFileLock evicts, so do not mix contracts on one path. 636
Add StrictSoftFileLock and AsyncStrictSoftFileLock with owner-specific hard-linked claims. Strict mode fails closed on claim damage, exposes each recovery token, and requires an exact claim name for a force break. 637
Ignore lifetime on native locks with a warning; only ~filelock.SoftFileLock honors it. 593
Stop mutating the Unix lock file before fcntl.flock is held. 594
Bind the Windows reparse-point check to the locked handle to close a symlink-swap race. 596
Evict a non-regular soft lock file without reading it. 597
Write a soft lock's holder record atomically so a short write cannot create overlapping holders. 614
Make native lock release transactional so a failed unlock is retried, not dropped. 615
Open the Windows lock file via NtCreateFile so a real access denial is raised, not reported as a timeout. 617
Canonicalize singleton keys so equivalent path spellings share an instance, without following a final symlink. 621
Preserve parent lock ownership across fork(). A child closes an inherited descriptor only while its identity still matches, so it neither unlocks nor unlinks the parent's lock. It clears inherited ownership state and singleton caches, then requires a new lock instance before acquiring. Fork-time construction replaces inherited cache mutexes and omits an instance whose construction crossed into the child from the cache. If fstat() cannot establish the identity, child cleanup skips the descriptor number because an earlier fork callback may have reused it. Descriptor tracking also covers third-party backends that fail after assigning a descriptor. 634
Open a SQLite connection per outer acquisition and close it on final release, so a forked child can no longer close its parent's handle. A child rejects inherited databases until exec(), and a PyPy child rejects read-write locks once the parent has used SQLite. 635
Keep executor-backed lock operations alive until they finish when a caller cancels. Serialize acquisitions on the same async lock so cancellation rollback cannot release a later caller's hold. Roll back acquisitions that finish after cancellation and surface release failures. SQLite read-write locks keep their state until rollback ends the transaction; callers can retry cleanup with release(force=True) or another acquisition. 640
Reject negative and non-finite lifetime values during lock construction and assignment. 644
Read the saved Windows process-probe error before deciding that a soft-lock holder has exited. 645
Reject non-default lock options that a narrow subclass constructor cannot honor, and forward all options through subclasses that accept arbitrary keyword arguments. 646
Release now removes the path identity that acquisition recorded instead of resolving a symlinked parent again. When acquisition raises, its rollback no longer deletes the holder's deadlock record. 647
Remove the body error from implicit context on the release error before adding both errors to an exception group. 648
Relinquish a soft lock's descriptor before one close attempt so a later release cannot close a reused descriptor number, and honor close_error_policy while still attempting marker cleanup. 649
Raise OSError(errno.ENOSYS) from descriptor locks when fcntl is unavailable, and reject invalid blocking poll intervals before attempting a lock. 650
SoftFileLock and SoftFileLease record the holder's process start time on every platform and reclaim a stale marker only when the recorded owner is provably gone. A reused PID on Unix no longer breaks a live lock or wedges acquisition, matching the recycled-PID detection Windows already had. 660
SoftReadWriteLock and SoftFileLease ride out a transient filesystem error during a heartbeat instead of dropping the lock or reporting a false compromise, and report a lost claim only once refresh cannot recover before the lease would lapse. SoftFileLease also reclaims a malformed or partial marker that used to block every contender, and a Linux marker distinguishes a PID reused across a reboot. 661
BaseFileLock.__del__ suppresses a release error rather than raising it during garbage collection, where it surfaced as an unraisable-exception warning attributed to unrelated code. 665
Correct the Unix lock-file cleanup and fcntl.flock documentation. 623
Drop automated bot entries from the changelog and link its code references to the API docs and the Python standard library. 638
Refresh the documentation to the current code: a new trust-boundaries and ownership-scope section (same-UID boundary, advisory native locks, strict claims and lease fencing, a filesystem support matrix, migration off timed stale breaking), the lock-selection flowchart and comparison tables extended with StrictSoftFileLock and SoftFileLease, and the cross-platform process start token replacing the Windows-only description throughout. 663
The filesystem support matrix records mutual exclusion measured across two independent client caches in CI: NFS (v4 and v3) for the native, soft, and strict locks, and SMB for the native and soft locks. 665
Build the changelog from towncrier news fragments, render pending fragments as an Unreleased docs section, and refuse to publish a tag the changelog does not document. 626
<!-- Release notes generated using configuration in .github/release.yaml at main -->
<!-- Release notes generated using configuration in .github/release.yaml at main -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.29.6...3.29.7
_util: drop the dead st_mtime=0 short-circuit in raise_on_not_writable_file 589 - by HrachShah
soft_rw: evict a non-regular write marker without reading it 588
asyncio: detect cross-instance reentrant deadlocks before the poll loop 586 - by HrachShah
test: silence fork DeprecationWarning on 3.15 by @gaborbernat in https://github.com/tox-dev/filelock/pull/585
<!-- Release notes generated using configuration in .github/release.yaml at main -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.29.5...3.29.6
test: silence fork DeprecationWarning on 3.15 585
_util: drop the dead st_mtime=0 short-circuit in raise_on_not_writable_file 582 - by HrachShah
serialize singleton construction in FileLockMeta 581 - by dxbjavid
surface GitHub Sponsors and thanks.dev
<!-- Release notes generated using configuration in .github/release.yaml at main -->
<!-- Release notes generated using configuration in .github/release.yaml at main -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.29.4...3.29.5
lifetime: reject negative, non-numeric, and bool values at the setter 573 - by HrachShah
roll back a read acquire's open transaction when its SELECT fails 575 - by dxbjavid
keep Unix lock files after release 577 - by itscloud0
use a private break name in break_lock_file 576 - by dxbjavid
don't complete a writer acquire on a peer's reclaimed marker 571 - by dxbjavid
don't follow symlinks in raise_on_not_writable_file 567 - by dxbjavid
only unlink the writer marker on release if it is still ours 566 - by dxbjavid
don't follow symlinks when refreshing soft read/write lock markers 565 - by dxbjavid
serialize read/write release rollback against a concurrent acquire 563 - by dxbjavid
<!-- Release notes generated using configuration in .github/release.yaml at 3.29.4 -->
<!-- Release notes generated using configuration in .github/release.yaml at 3.29.4 -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.29.3...3.29.4
keep the read/write heartbeat alive on a transient touch error 562 - by dxbjavid
verify inode in break_lock_file before unlinking a stale lock 561 - by dxbjavid
<!-- Release notes generated using configuration in .github/release.yaml at 3.29.3 -->
<!-- Release notes generated using configuration in .github/release.yaml at 3.29.3 -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.29.2...3.29.3
🐛 fix(ci): restore release environment on tag job 559
validate pid range in _parse_lock_holder 556 - by dxbjavid
🔧 ci(release): publish to PyPI on tag push 557
<!-- Release notes generated using configuration in .github/release.yaml at 3.29.2 -->
<!-- Release notes generated using configuration in .github/release.yaml at 3.29.2 -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.29.1...3.29.2
check hostname in is_lock_held_by_us 553 - by dxbjavid
🔒 fix(soft): harden stale-lock breaking and self-heal malformed locks 551
open marker reads non-blocking to refuse attacker-placed fifo 549 - by dxbjavid
<!-- Release notes generated using configuration in .github/release.yaml at 3.29.1 -->
<!-- Release notes generated using configuration in .github/release.yaml at 3.29.1 -->
release() by @MrAnno in https://github.com/tox-dev/filelock/pull/540Full Changelog: https://github.com/tox-dev/filelock/compare/3.29.0...3.29.1
🐛 fix(soft): refuse to follow symlinks when reading the lock file 548 - by dxbjavid
chore: improve filelock maintenance path 545 - by lphuc2250gma
chore: improve filelock maintenance path 544 - by lphuc2250gma
chore: improve filelock maintenance path 542 - by lphuc2250gma
docs: clarify per-thread scope of ~filelock.FileLock configuration 543 - by Gares95
docs: fix API docs of ~filelock.BaseFileLock.release 540 - by MrAnno
<!-- Release notes generated using configuration in .github/release.yaml at 3.29.0 -->
<!-- Release notes generated using configuration in .github/release.yaml at 3.29.0 -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.28.0...3.29.0
✨ feat(soft): enable stale lock detection on Windows 534
🐛 fix(async): use single-thread executor for lock consistency 533
<!-- Release notes generated using configuration in .github/release.yaml at 3.28.0 -->
<!-- Release notes generated using configuration in .github/release.yaml at 3.28.0 -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.27.0...3.28.0
<!-- Release notes generated using configuration in .github/release.yaml at 3.25.2 -->
<!-- Release notes generated using configuration in .github/release.yaml at 3.25.2 -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.25.1...3.25.2
<!-- Release notes generated using configuration in .github/release.yaml at 3.25.1 -->
<!-- Release notes generated using configuration in .github/release.yaml at 3.25.1 -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.25.0...3.25.1
🐛 fix(win): restore best-effort lock file cleanup on release 511
📝 docs(logo): add branded project logo 507
<!-- Release notes generated using configuration in .github/release.yaml at 3.25.0 -->
<!-- Release notes generated using configuration in .github/release.yaml at 3.25.0 -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.24.4...3.25.0
✨ feat(async): add ~filelock.AsyncReadWriteLock 506
Standardize .github files to .yaml suffix
Move SECURITY.md to .github/SECURITY.md
Add security policy
Add permissions to check workflow 500
<!-- Release notes generated using configuration in .github/release.yml at 3.24.3 -->
<!-- Release notes generated using configuration in .github/release.yml at 3.24.3 -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.24.2...3.24.3
🐛 fix(unix): handle ENOENT race on FUSE/NFS during acquire 495
🐛 fix(ci): add trailing blank line after changelog entries 492
<!-- Release notes generated using configuration in .github/release.yml at 3.24.2 -->
<!-- Release notes generated using configuration in .github/release.yml at 3.24.2 -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.24.1...3.24.2
🐛 fix(rw): close sqlite3 cursors and skip ~filelock.SoftFileLock Windows race 491
🐛 fix(test): resolve flaky write non-starvation test 490
📝 docs: restructure using Diataxis framework 489
<!-- Release notes generated using configuration in .github/release.yml at 3.24.1 -->
<!-- Release notes generated using configuration in .github/release.yml at 3.24.1 -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.24.0...3.24.1
<!-- Release notes generated using configuration in .github/release.yml at 3.24.0 -->
<!-- Release notes generated using configuration in .github/release.yml at 3.24.0 -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.23.0...3.24.0
✨ feat(lock): add lifetime parameter for lock expiration (#68) 486
✨ feat(lock): add cancel_check to ~filelock.BaseFileLock.acquire (#309) 487
🐛 fix(api): detect same-thread self-deadlock 481
✨ feat(mode): respect POSIX default ACLs (#378) 483
🐛 fix(win): eliminate lock file race in threaded usage 484
✨ feat(lock): add poll_interval to constructor 482
🐛 fix(unix): auto-fallback to ~filelock.SoftFileLock on ENOSYS 480
<!-- Release notes generated using configuration in .github/release.yml at 3.23.0 -->
<!-- Release notes generated using configuration in .github/release.yml at 3.23.0 -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.22.0...3.23.0
📝 docs: move from Unlicense to MIT 479
📝 docs: add fasteners to similar libraries 478
<!-- Release notes generated using configuration in .github/release.yml at 3.22.0 -->
<!-- Release notes generated using configuration in .github/release.yml at 3.22.0 -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.21.2...3.22.0
🐛 fix(soft): skip stale detection on Windows 477
✨ feat(soft): detect and break stale locks 476
<!-- Release notes generated using configuration in .github/release.yml at 3.21.2 -->
<!-- Release notes generated using configuration in .github/release.yml at 3.21.2 -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.21.1...3.21.2
<!-- Release notes generated using configuration in .github/release.yml at 3.21.1 -->
<!-- Release notes generated using configuration in .github/release.yml at 3.21.1 -->
sqlite3 when importing ReadWriteLock by @bayandin in https://github.com/tox-dev/filelock/pull/473Full Changelog: https://github.com/tox-dev/filelock/compare/3.21.0...3.21.1
🐛 fix: gracefully handle missing sqlite3 when importing ~filelock.ReadWriteLock 473 - by bayandin
🐛 fix(ci): make release workflow robust
<!-- Release notes generated using configuration in .github/release.yml at 3.21.0 -->
<!-- Release notes generated using configuration in .github/release.yml at 3.21.0 -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.20.3...3.21.0
🐛 fix(ci): make release workflow robust
👷 ci(release): commit changelog and use release config 472
👷 ci(release): consolidate to two jobs 471
✨ feat(unix): delete lock file on release 408 - by sbc100
✨ feat(lock): add SQLite-based ~filelock.ReadWriteLock 399 - by leventov
🔧 chore: modernize tooling and bump deps 470
<!-- Release notes generated using configuration in .github/release.yml at 3.20.4 -->
<!-- Release notes generated using configuration in .github/release.yml at 3.20.4 -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.20.3...3.20.4
Fix TOCTOU symlink vulnerability in SoftFileLock by @gaborbernat in https://github.com/tox-dev/filelock/pull/465
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.20.2...3.20.3
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.20.1...3.20.2
CVE-2025-68146: Fix TOCTOU symlink vulnerability in lock file creation by @gaborbernat in https://github.com/tox-dev/filelock/pull/461
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.20.0...3.20.1
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.19.1...3.20.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.19.0...3.19.1
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.17.0...3.18.0
Support fcntl check on Emscripten 398.
Indicate that locks are exclusive/write locks 394.
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.16.1...3.17.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.16.0...3.16.1
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.15.4...3.16.0
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
file_lock as positional argument by @kwist-sgr in https://github.com/tox-dev/filelock/pull/347Full Changelog: https://github.com/tox-dev/filelock/compare/3.15.3...3.15.4
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
TypeError: _CountedFileLock.__init__() got an unexpected keyword argument 'timeout' by @kwist-sgr in https://github.com/tox-dev/filelock/pull/345Full Changelog: https://github.com/tox-dev/filelock/compare/3.15.2...3.15.3
Fix TypeError: _CountedFileLock.__init__() got an unexpected keyword argument 345.
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.15.1...3.15.2
<!-- Release notes generated using configuration in .github/release.yml at main -->
<!-- Release notes generated using configuration in .github/release.yml at main -->
Full Changelog: https://github.com/tox-dev/filelock/compare/3.15.0...3.15.1
Restore __init__ method; more robust initialization for singleton locks 338.
Your coding agent can read these notes before it upgrades. Set up the MCP server →