Changelog¶
Unreleased (2026-10-27)¶
Packaging¶
Releases now run on the shared tox-dev/github-workflows pipeline, with a locked release toolchain and generated GitHub Release notes.
4.2.4 (2026-10-19)¶
4.2.3 (2026-10-19)¶
Fixed¶
Creating a lock on a Python 3.15 interpreter without
types.LazyImportTypeno longer triggersAttributeErrorat exit. PR #861 - by @gaborbernat.Handle
EFTYPEwhen a no-follow open refuses a symlink in a soft reader/writer lock’s protocol tree, so heartbeat reports lost ownership rather than a transient refresh error. PR #859 - by @edsonsims.
4.2.2 (2026-10-18)¶
Fixed¶
Fix a lock on a relative path that stayed held after a later
with lock:ended, when an earlieracquire()had failed because the working directory no longer exists. That call still raisesFileNotFoundError, and it now leaves the lock’s hold count unchanged. PR #856 - by @spicysharkco.
4.2.1 (2026-10-17)¶
Fixed¶
On a singleton wrapper,
AsyncReadWriteLock.close()andAsyncSoftReadWriteLock.close()end only the holds that tasks acquired through that wrapper. A reader that arrives duringclose()gets the closed error instead of joining the ending hold. After synchronous code closes or force-releases the shared lock, the wrappers refuse to admit readers into the ended hold, andclose()on such a wrapper returns. Closing one wrapper no longer ends a task’s nested hold taken through another wrapper on the same path. PR #832 - by @gaborbernat.ReadWriteLocklocks again after arelease()that an exception from a signal handler interrupted. The async read-write wrappers stop admitting readers into such a level. The async read-write locks forget a hold whose backend release failed after the backend let go, and they free the memory of each acquire that times out or is canceled.AsyncFileLockreturns fromrelease()after a few hundred acquires gave up behind a waiting one. An exception from a signal handler delivered while anAsyncFileLockcall joins its queue no longer blocks every later call on that lock. PR #833 - by @gaborbernat.Fix
ReadWriteLockacting on-journal,-walor-shmfiles another process puts beside its database: a write could land in another file, a reader could get in beside a writer, and an acquire could fail. SQLite now opens the database by name only in a directory no other account can write, and through a private hard link elsewhere. On Windows the directory’s access control list decides. Where hard links are unavailable, keep the database in a directory other accounts cannot write, such as one under%LOCALAPPDATA%. The lock removes link directories through a checked descriptor rather than by name, reads a link directory’s name only when the locking account owns it, and leaves alone a directory with other content renamed onto a link directory’s name. A database whose schema takes more than a few kilobytes to load raisesValueErrorinstead of running past the acquire timeout. PR #834 - by @gaborbernat.Fix five bugs in opening the lock file.
UnixFileLockno longer truncates a file it did not create, such as one renamed to the lock path, and no longer appliesmodeto it. Anon_acquiredhook that writes holder metadata now truncates the file itself. A lease (Linux) or an oplock (Windows) on the lock file or a soft lock’s marker no longer holdsacquire()past itstimeoutorblocking=False, and an oplock no longer holdsrelease();ReadWriteLockon Windows waits for itstimeoutand raisesTimeout. On Windows, amodewithout group and other bits, such as0o600, now creates the lock file with an owner-only permission list; theReadWriteLockdatabase gets the same. The soft locks’ writability check no longer follows a symlink swapped in at the lock path. On a filesystem withoutflock, a contender from another account now waits on a marker it cannot write instead of raisingPermissionError. PR #835 - by @gaborbernat.Fix
SoftFileLock,MarkerSoftFileLockandSoftFileLeaseremoving a live holder’s marker in three cases: the holder and the contender run in Linux time namespaces with different boottime offsets; only one of them can read the boot id; a process other than the owner rewrote the marker. Soft markers no longer carry group or other write bits. A process name containing a carriage return or another line separator no longer makes the stale check raiseValueError. When/proc/self/ns/timeexists but cannot be read, the stale check no longer compares start times and keeps the marker. PR #836 - by @gaborbernat.The async read-write locks record their hold under a task owner, so synchronous code on the executor thread that took the hold can no longer re-enter or release it.
AsyncSoftReadWriteLockgives back one level on release, so synchronous readers of a shared singleton keep theirs.SoftReadWriteLocktracks read levels per thread:release()from a thread that holds none raisesRuntimeError. After its heartbeat recorded a lost hold, it refuses new acquires until that hold is released. PR #838 - by @gaborbernat.StrictSoftFileLockcreates<path>.filelockand itsclaimsdirectory with the lock’smodeand sets the sticky bit (a directory flag that lets only a file’s owner remove it) on both. On the next acquisition it narrows a directory it owns that an earlier release created wider; it leaves a directory of another account as it is, so remove such leftovers by hand. It reachesclaimsthrough a descriptor opened without following symlinks; on Windows it holds both directories open and refuses a junction (a directory that points at another directory). Under a sticky parent such as/tmpit refuses a coordination directory of another account, asSoftReadWriteLockdoes for<path>.rw. One read grace now covers a whole claim scan, a failed claim cleanup no longer leaves the sentinel descriptor open, and a non-regular node at a sentinel private-record name raisesSoftFileLockProtocolError. On Windows, contenders read claims without blocking their owner’s unlink. PR #839 - by @gaborbernat.Fix a lock reporting a hold the OS had dropped after a signal handler raised during
acquire()orrelease(). A release that a signal handler cuts short after it has started now completes before the error propagates. A handler that acquires the lock its own thread is releasing now getsRuntimeErrorinstead of a hold that stays held. The singleton cache no longer hands out anis_singleton=Truelock or aReadWriteLockwhose finalizer is running, which released the new holder’s lock. A signal duringos.fork()no longer leaves the other threads blocked in their next lock call, and a fork from another thread no longer waits for aReadWriteLockacquire on a busy database. PR #840 - by @gaborbernat.Fix a lock on a relative path locking a file in the directory the process changed to while the lock waited, and leaving its marker behind on release after such a change. The path resolved when an acquisition starts stays in use until the hold ends. An
is_singleton=Truelookup no longer returns a cached lock whose relative path now resolves to another file; a held lock still matches the file it holds. A rename of the lock’s directory during a hold no longer leaves the marker behind or reports a false lease compromise, and a waiter no longer creates a second lock file in a directory that was renamed away. PR #841 - by @gaborbernat.SoftReadWriteLockreaches its records through descriptors of<path>.rwandgenorholdersopened without following symlinks. On Windows it holds those directories open and refuses a junction (a directory that points at another directory). A tree swapped in after an earlier acquire therefore cannot redirect them. Its heartbeat rewrites a holder record only when the name still leads to the file it created, and does not block on a FIFO (a named pipe). A heartbeat that finds<path>.rwreplaced by a symlink or junction reports the hold lost instead of ending the heartbeat thread. A live lock object repeats the ownership check whenever the tree it opens is not the one it prepared. PR #842 - by @gaborbernat.Fix
SoftFileLock,MarkerSoftFileLockandSoftFileLeaseremoving or displacing a live holder’s marker in five cases. ext4 gave a freed inode number to the next marker. A stalledFileLockremoved itsENOSYSplaceholder after a peer replaced it. A failed acquire cleaned up after a successor took the path. A stale break left the lock path empty while it checked the marker it had moved. Alifetimebreak judged a marker by a reused inode number. On Linux and macOS a stale marker now changes hands in one atomic exchange. On other platforms without one, except Windows, including NFS and SMB, the marker stays in place and waits fortimeoutorbreak_lock(). Restoring a marker no longer follows a symlink found under the break name. A holder that releases while a peer’s exchange has its marker aside leaves a record no lock parses, so the put-back lands a marker that ages out. A lease heartbeat that finds another file at the lock path once, while a peer’s break has its marker aside, waits for the next refresh before it reports a compromise. A contender that finds a dead breaker’s marker puts back the marker that breaker left under its break name. A marker is the breaker’s own only when it names the breaker’s process on this host; the same process number on another host is a holder. A contender takes a stranded marker under a name of its own before it puts the marker back, so two contenders no longer reverse each other’s exchange and remove the live holder’s marker. A claim left behind by a failed put-back is retried on the next poll. PR #843 - by @gaborbernat.Canceling an
AsyncReadWriteLockorAsyncSoftReadWriteLockacquire that waits for another process now stops the wait and raises the cancellation. It used to wait until that process released, or raiseTimeout. Athread_local=TrueAsyncFileLockthat threads with their own event loops share no longer deadlocks when one thread waits for the lock while another holds it. PR #844 - by @gaborbernat.SoftReadWriteLockrefuses a commit that lands a whole retention window behind the log, so two committers stalled at adjacent generations can no longer admit a second writer. Its stale check samples the clock before it reads a holder record, so a pause between the two no longer counts as time the record stayed unchanged. PR #845 - by @gaborbernat.Fix a
SoftFileLockcontender evicting an empty marker after two seconds while its owner held the lock. The owner is aSoftFileLockbefore 3.22, which writes nothing into its marker, or a current one still writing its record. An empty marker now reads as held, andtimeout,lifetimeorbreak_lock()clears it. A contender that finds an empty marker a dead breaker left aside puts it back instead of removing it. PR #846 - by @gaborbernat.Fix
ReadWriteLockon Windows acting on-journaland-walfiles another account places beside its database: an acquire could fail withsqlite3.OperationalError, or SQLite could replay the journal and delete the file it names. The lock now reads the database directory’s access control list. Where an account other than the locking account,SYSTEMandAdministratorscan add or remove names, SQLite opens a hard link inside a directory only those accounts can write. A filesystem without hard links raisesOSError. PR #854 - by @gaborbernat.Fix
SoftReadWriteLocksubclasses sharing singleton instances with the base class or sibling subclasses. Each concrete class now keeps its own cache and construction guard, including after fork, while preserving cooperative class-definition keywords. PR #855 - by @AryanRG.
4.2.0 (2026-10-14)¶
Fixed¶
Fix
StrictSoftFileLockraisingSoftFileLockProtocolErroron Windows when a contender read a claim whose owner was still finishing its unlink. PR #829 - by @gaborbernat.
Performance¶
import filelockis about twice as fast: lock types other thanFileLockload on first use. PR #831 - by @gaborbernat.
4.1.2 (2026-10-14)¶
Fixed¶
Fix read-lock acquisition on SQLite versions older than 3.33.0 by using
sqlite_masterfor the schema probe. PR #827 - by @DawnofGenX.Raise
IsADirectoryError(orPermissionErroron Windows) for a directory lock path regardless of its write permissions. PR #822 - by @feiiiiii5.Fix a forked child hanging at exit on PyPy when the parent forked while an
AsyncReadWriteLockworker thread was between two operations. PR #828 - by @gaborbernat.Hash all cache keys in the lock filename recipe so short path-like keys stay in the chosen directory. The example also accepts path-derived surrogate escapes and works before the cache directory exists. PR #824 - by @xiehuanyi.
4.1.1 (2026-10-11)¶
Fixed¶
Avoid the macOS
/dev/fdlookup implicated in a kernel panic by opening SQLite through a validated hard link. The database directory must be writable and support hard links; alias creation failure raisesOSError. PR #820 - by @gaborbernat.Ignore non-ASCII PID or start-time fields and out-of-range PIDs in
ReadWriteLockhard-link directory names so forged owners cannot abort acquisition. PR #821 - by @dxbjavid.
4.1.0 (2026-10-09)¶
Added¶
Import
OwnerMode,CompromiseReasonandhas_fcntlfromfilelock. PR #790 - by @gaborbernat.AcquireReturnProxyis generic in the lock type, sowith lock.acquire() as held:typesheldas the lock’s own class. PR #803 - by @gaborbernat.A
Timeoutfrom a soft lock names a holder on another host or in another PID namespace, which no contender ever reclaims. PR #815 - by @gaborbernat.Every option given in seconds takes a
DecimalorFraction, as a file lock’stimeoutalready did, and a read-write lock or lease refuses aboolor string one. PR #815 - by @gaborbernat.
Fixed¶
is_lock_held_by_usandis_lock_held_by_usreturnFalsefor a marker an earlier process with the same PID left behind. PR #774 - by @lprnmns.SoftFileLockremoves its marker when writing it fails and closing the descriptor fails too, so the lock path no longer stays blocked. PR #775 - by @harbinresearcher.acquire()andacquire()no longer wait pasttimeoutwhenpoll_intervalis longer than the time left. PR #777 - by @feiiiiii5.SoftReadWriteLockignores a generation-log entry whose name is not 20 ASCII digits, which used to stop its heartbeat thread or delete real generations. PR #778 - by @dxbjavid.ReadWriteLock,SoftReadWriteLockand their async wrappers treat amath.inftimeout like-1and raiseValueErrorfor a blockingnanone. PR #779 - by @darrenhuai.ReadWriteLockandSoftReadWriteLockaccept a timeout abovethreading.TIMEOUT_MAXinstead of raisingOverflowError. PR #780 - by @darrenhuai.acquire()raisesValueErrorfor a blockingnantimeout or apoll_intervalabovethreading.TIMEOUT_MAX, and treats amath.inftimeout like-1. PR #781 - by @gaborbernat.SoftFileLockandMarkerSoftFileLocktreat a marker cut before its final newline as malformed, so a crash-truncated record self-heals and a read mid-write no longer breaks a live lock. PR #782 - by @gaborbernat.UnixFileLockno longer deletes another process’s live marker when it falls back to a soft lock onENOSYS, and on macOS a lock path ending in a separator raisesFileNotFoundErrorinstead of retrying. PR #785 - by @gaborbernat.SoftFileLockandSoftFileLeaseput back a live successor’s marker that a racing stale break moved aside, so a third contender no longer acquires beside the successor. PR #786 - by @gaborbernat.StrictSoftFileLockremoves every claim a failed acquire published, counts anEEXISTlink that landed as published, and no longer reportsis_lockedafter a failed claim cleanup. PR #787 - by @gaborbernat.On Python 3.10 without the
exceptiongroupbackport, a release failure under the defaultcontext_error_policyno longer turns intoModuleNotFoundError; cleanup failures chain instead of grouping, andon_acquiredis allowed. PR #788 - by @gaborbernat.AsyncReadWriteLockandAsyncSoftReadWriteLockdrop a task’s hold when a caller cancels it during a release that still completes, instead of blocking every later writer. PR #789 - by @gaborbernat.SoftFileLeasereleases a lease dropped while held, at garbage collection or interpreter exit, and raisesValueErrorfor aheartbeat_intervalabovethreading.TIMEOUT_MAX. PR #791 - by @gaborbernat.StrictSoftFileLockjudges an abandoned private record’s age by the filesystem’s clock, so a client clock ahead of an NFS server no longer aborts live publications. PR #792 - by @gaborbernat.BaseAsyncFileLockraisesRuntimeErrorinstead ofasyncio.CancelledErrorwhen its executor shuts down with the call still queued, and a waiter interrupted by anything else no longer wedges later calls. PR #793 - by @gaborbernat.Constructing or closing a second
ReadWriteLockon a held database no longer drops the holder’s lock, so other processes stay excluded. PR #794 - by @gaborbernat.SoftReadWriteLockno longer admits a second writer after<path>.rwis removed under a live instance, and flushes each snapshot before publishing it so a crash cannot leave an empty one that wedges every peer. PR #795 - by @gaborbernat.SoftFileLeasereclaims a deadMarkerSoftFileLockowner, and expires a lease or a malformed soft marker after it stays unchanged on the contender’s own monotonic clock, so clock skew cannot break it. PR #796 - by @gaborbernat.A soft lock marker written in a Linux container records its PID namespace with the hostname, so a sibling container that shares the hostname and volume no longer breaks a live lock. PR #797 - by @gaborbernat.
SoftReadWriteLock.close()makes an acquire still waiting in another thread raiseRuntimeError, where it used to take the lock on the closed instance and hold it until the process exited. PR #798 - by @gaborbernat.SoftReadWriteLockreads the head fromgen/HEAD, so a client whose cached directory listing is more than 64 generations stale no longer takes an old generation for the head and forks the log. PR #799 - by @gaborbernat.When the garbage collector finalizes a held
BaseAsyncFileLock, it releases on alooprunning in another thread, or in place once no loop is left; thelifetimecheck and path resolution now run in the executor. PR #800 - by @gaborbernat.SoftReadWriteLockwaits out a holder’s ownstale_thresholdbefore evicting it, keys its singleton on the path its log sits beside, and no longer leaks ledger entries or the holder record of a failed acquire. PR #801 - by @gaborbernat.lock_descriptor()raisesValueErrorfor a blockingpoll_intervalabovethreading.TIMEOUT_MAXup front, instead ofOverflowErroronce the descriptor is contended. PR #802 - by @sricharanreddycheruku.BaseFileLockrejects aboolor string timeout, an out-of-rangemodeand a non-boolblockingset at any time, rejects unknown options on a singleton cache hit, and tracks anon_acquiredreacquire. PR #803 - by @gaborbernat.StrictSoftFileLockraisesSoftFileLockProtocolErrornaming a directory, symlink or exited soft-lock owner’s marker at the lock path, andlock_path_occupantshows what blocks it. PR #804 - by @gaborbernat.ReadWriteLockraisesValueErrorfor a WAL-mode database instead ofdisk I/O error, and its/dev/fdfallback links beside the database, so a lock off the TMPDIR filesystem no longer fails withEXDEV. PR #805 - by @gaborbernat.ReadWriteLock.release()from a thread that holds no read level raisesRuntimeErrorinstead of ending another thread’s read lock and letting a writer in. PR #806 - by @gaborbernat.SoftFileLockLifetimeWarningderives fromFutureWarninginstead ofDeprecationWarning, so Python shows it by default outside__main__. PR #807 - by @gaborbernat.SoftFileLockapplies an explicitmodepast the umask asUnixFileLockdoes, and reads a marker number spelled other than in ASCII digits, or a lease with an empty token, as malformed. PR #807 - by @gaborbernat.ReadWriteLockraisesOSErrorwhen its database is unlinked or replaced while an acquisition waits, instead of taking a lock that no later opener sees. PR #808 - by @gaborbernat.On a thread-local synchronous lock,
release()withforce=Trueand garbage collection release holds exited threads left, and arelease()re-entered from a signal handler closes the descriptor once. PR #810 - by @gaborbernat.SoftFileLeaserecords alease_durationgiven as afloatsubclass, such as NumPy’s, in a form every contender parses, so a live lease is no longer evicted as malformed. PR #815 - by @gaborbernat.StrictSoftFileLockraisesSoftFileLockProtocolErrorfor a file at the lock path it cannot parse once it stays unchanged for two seconds, instead of waiting on it forever. PR #815 - by @gaborbernat.A lock finalized at interpreter exit no longer hangs when a daemon thread stopped inside filelock’s fork bookkeeping. PR #815 - by @gaborbernat.
Setting
BaseFileLock.timeoutfrom a string emits aDeprecationWarningand from aboolraisesTypeError; pass the number of seconds instead. PR #815 - by @gaborbernat.Every lock raises
ValueErrorfor a timeout too large for afloat, and a singleton accepts a timeout that waits as long as the cached one, such asinffor-1. PR #815 - by @gaborbernat.On macOS,
ReadWriteLockconnects through a private hard link, so cycling a lock beside a holder no longer adds an open descriptor per connection. PR #815 - by @gaborbernat.SoftFileLockandSoftFileLeasere-check a stale marker right before breaking it, so a marker recreated since the check is no longer moved aside for a third contender to take the path. PR #815 - by @gaborbernat.An acquire a signal handler starts while its thread is still acquiring the same lock raises
RuntimeError, where it used to hang that thread or leave the lock held after the outer release. PR #815 - by @gaborbernat.A
BaseAsyncFileLocksingleton the garbage collector finalizes leaves the singleton cache first, so a new lock on the path waits for its release instead of re-entering a hold that release then drops. PR #815 - by @gaborbernat.A finalized thread-local
BaseAsyncFileLockreleases every thread’s hold, including one on a daemon thread’s event loop at interpreter exit, instead of leaving it held. PR #815 - by @gaborbernat.A soft lock in the host’s PID namespace no longer breaks a live marker written from a container sharing the hostname while the kernel shows its owner running in another namespace under the recorded PID and start time. PR #815 - by @gaborbernat.
SoftFileLockand its marker and lease variants no longer leave their marker behind when a signal handler interrupts a release; the retried release, or the next acquire on Windows, removes it. PR #815 - by @gaborbernat.SoftReadWriteLockraisesValueErrorfor aheartbeat_intervalabovethreading.TIMEOUT_MAX, which killed its heartbeat thread, and an interrupted release still removes its record. PR #815 - by @gaborbernat.AsyncReadWriteLockreleases only its own hold on a singleton it shares with synchronous users, where it used to end their read transaction too. PR #815 - by @gaborbernat.
Documentation¶
The documentation’s canonical link,
og:urland sitemap entries point at the versioned page on Read the Docs instead of a domain-root URL that returns 404. PR #813 - by @gaborbernat.
4.0.12 (2026-10-05)¶
Fixed¶
Fix read-lock acquisition on SQLite versions older than 3.33.0 by using
sqlite_masterfor the schema probe. PR #769 - by @Vikram12301.
4.0.11 (2026-10-05)¶
Fixed¶
ReadWriteLockandAsyncReadWriteLockuse a validated private hard link when/dev/fdhas no entry for the database descriptor, supporting NetBSD’s static descriptor directory beyond descriptor 63. The temporary location must share a filesystem with the database. The symlink refusal test accepts NetBSD’s error wording - by @gaborbernat.
4.0.10 (2026-10-03)¶
Fixed¶
Reusing a singleton
AsyncFileLockwith anotherloop,executororrun_in_executor, or a singletonSoftFileLeasewith anotherlease_duration,heartbeat_intervaloron_compromise, now raisesValueErrorinstead of returning the lock with its original options. PR #765 - by @kokotatan.
4.0.9 (2026-10-01)¶
Fixed¶
ReadWriteLockandAsyncReadWriteLockclose 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. PR #763 - by @gaborbernat.
Security¶
ReadWriteLockandAsyncReadWriteLockrefuse 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) - by @gaborbernat.
4.0.8 (2026-10-01)¶
Fixed¶
ReadWriteLock.release()andSoftReadWriteLock.release()from a thread that does not hold the write lock now raiseRuntimeErrorinstead of dropping the holder’s lock and letting a second writer in. PR #761 - by @feiiiiii5.
4.0.7 (2026-09-29)¶
Fixed¶
File locks now raise
ValueErrorat construction whenmodedenies the owner read or write, such asmode=0o444, instead of failing on a later acquire and staying broken until someone deletes the lock file. PR #760 - by @gaborbernat.
4.0.6 (2026-09-28)¶
Fixed¶
Reject negative blocking timeouts other than
-1before reentrantReadWriteLockandSoftReadWriteLockacquisition. Preserve unlimited waits and nonblocking acquisition. PR #756 - by @feiiiiii5.
4.0.5 (2026-09-28)¶
Fixed¶
Fix
MarkerSoftFileLockacquisition and prevent contenders from evicting live protocol-2 owners after two seconds. Reclaim recognized records after owner death; preserve unknown contracts. PR #751 - by @DawnofGenX.Honor instance
timeoutandblockingsettings in sync and asyncReadWriteLockacquisition, including waits between tasks on one instance. Preserve explicit per-call overrides. PR #752 - by @DawnofGenX.Skip access-denial checks when the process can read mode-
0o000files. Keep mode-bit checks enabled for privileged processes on filesystems that support POSIX permissions. PR #753 - by @pasmud.Skip vanished
StrictSoftFileLockclaims 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. PR #754 - by @januththedev.Reject negative timeouts other than
-1in blockingAsyncReadWriteLockandAsyncSoftReadWriteLockacquisitions. Keep-1as an unlimited wait and ignore timeouts whenblocking=False. PR #755 - by @pasmud.
4.0.4 (2026-09-26)¶
Fixed¶
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. PR #748 - by @feiiiiii5.
4.0.3 (2026-09-23)¶
Fixed¶
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 installedunder 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. PR #747 - by @gaborbernat.
4.0.2 (2026-09-23)¶
Fixed¶
Concurrent
acquire()andrelease()on athread_local=Falselock no longer leak the OS lock, close a descriptor twice, drop a lease token, or leave a false deadlock after a cross-thread release (issue #744). PR #745 - by @gaborbernat.AsyncReadWriteLockandAsyncSoftReadWriteLocknow give eachasynciotask its own hold, so tasks sharing one instance no longer enter the write lock together. PR #746 - by @gaborbernat.Correct the async cache example to create its data directory and clarify automatic creation of lock-file parent directories. PR #740 - by @agammann.
4.0.1 (2026-09-19)¶
Fixed¶
poll_intervalis now validated at construction, on the setter, and onacquire(): a negative, non-finite, or non-numeric value raisesValueError/TypeErrorimmediately instead of failing insidetime.sleep. PR #739 - by @Pitchfork-and-Torch.
4.0.0 (2026-09-17)¶
Added¶
SoftReadWriteLockexposesgenerationas a fencing token for the protected resource and reports a lost hold throughon_compromiseandcompromise. PR #738 - by @gaborbernat.
Fixed¶
The
SoftReadWriteLockon-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,.writeand.readers/files, and you can delete them. The filesystem must provide no-replace hard links, as it must forStrictSoftFileLock, so a runtime withoutos.linkraisesSoftFileLockProtocolErroron acquire. Constructing a singleton again with a differenton_compromise, or withpoll_intervalat or abovestale_threshold, now raisesValueError. PR #738 - by @gaborbernat.SoftReadWriteLockno longer deadlocks when a holder dies on another host mid-transition, andrelease()no longer waits on a mutex a dead host left behind. 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 anmtimeread against another host’s. PR #738 - by @gaborbernat.
3.32.7 (2026-09-16)¶
Fixed¶
3.32.6 (2026-09-08)¶
Added¶
Allow acquiring existing lock files that grant write access through group permissions or an ACL even when their owner-write mode bit is unset. PR #728 - by @jackwalkerlabs.
Fixed¶
SoftFileLeaseandAsyncSoftFileLeasenow reject a boolean or non-finitelease_duration, which used to publish an owner record their ownownerproperty reads back as malformed. PR #723 - by @lprnmns.Reject non-finite heartbeat, stale, and polling intervals in
SoftReadWriteLockandAsyncSoftReadWriteLock, including cached singleton construction and overflow in the default stale threshold. PR #724 - by @lprnmns.Honor acquisition timeouts and
blocking=FalseduringSoftReadWriteLockstate-mutex contention, including failed writer cleanup. Cross-host recovery of an abandoned.statemarker remains unsupported. PR #726 - by @Sohel2309.Preserve exception notes and custom attributes when copying or pickling
TimeoutandSoftFileLockProtocolError. PR #729 - by @jackwalkerlabs.
3.32.5 (2026-08-31)¶
Fixed¶
SoftFileLease.tokenandAsyncSoftFileLease.tokennow readNoneafter a failed acquisition, so a contender turned away by a live holder no longer reports a token for a claim it never published. PR #721 - by @lprnmns.Document that
modehas no setter: unlikepoll_interval,timeout,blockingandlifetime, it is fixed at construction andlock.mode = ...raisesAttributeError. PR #716 - by @Gares95.
3.32.4 (2026-08-23)¶
Fixed¶
StrictSoftFileLockalways 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. PR #705 - by @gaborbernat.WindowsFileLockwaits out a transientSTATUS_ACCESS_DENIEDfromNtCreateFilefor up to half a second before raisingPermissionError, since a peer unlinking the lock file as it releases can answer that for a moment; a real denial still fails fast. PR #705 - by @gaborbernat.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 heldSoftReadWriteLockread slot to a peer and could not take a write slot or aStrictSoftFileLockat all. PR #709 - by @dxbjavid.
3.32.3 (2026-08-13)¶
Fixed¶
The fork-safety audit hook no longer prints
Exception ignored in audit hookwith aTypeErrorwhen an audit event fires during interpreter shutdown, after CPython has already cleared the module globals. PR #703 - by @gaborbernat.
3.32.2 (2026-07-29)¶
Fixed¶
A
SoftReadWriteLockorSoftFileLeaseacquire 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. PR #691 - by @dxbjavid.Canceling an
AsyncSoftReadWriteLockacquire now releases the claim instead of leaking a marker whose heartbeat wedges every contender. PR #686 - by @dxbjavid.
3.32.0 (2026-07-21)¶
Added¶
Declare support for Python 3.15 and run the test suite against it and its free-threaded build, both currently in beta. PR #683 - by @gaborbernat.
Fixed¶
SoftReadWriteLockcloses 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. PR #685 - by @gaborbernat.
3.31.2 (2026-07-21)¶
Fixed¶
filelockimports again on runtimes whoseerrnoomitsENOTSUP, such as GraalPy, where importing the package raisedImportError. It probes the code instead, preferringENOTSUP, falling back toEOPNOTSUPPwhere that name is absent, and dropping toENOSYS/EXDEVwhere neither exists. Platforms definingENOTSUPkeep their behavior. PR #681 - by @gaborbernat.
3.31.1 (2026-07-20)¶
Fixed¶
3.31.0 (2026-07-18)¶
Added¶
Support Termux/Android, whose CPython ships without
os.linkand reportssys.platform == "android".import filelockand bothFileLockandSoftFileLocknow work there,StrictSoftFileLockreports its missing hard-link support only when acquired, and process liveness reads/procon Android instead of PID-only checks. PR #678 - by @gaborbernat.
Fixed¶
StrictSoftFileLockno 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 anintentand aheldclaim. PR #678 - by @gaborbernat.
3.30.3 (2026-07-17)¶
Fixed¶
Documentation¶
Keep both tables of contents on screen at any browser font size. The widened body column sized itself in
emagainst the reader’s font size while the breakpoints that fold the layout resolveemagainst 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. PR #673 - by @gaborbernat.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. PR #674 - by @gaborbernat.
3.30.2 (2026-07-16)¶
Fixed¶
Stop
SoftFileLeasedeleting a live marker whosemodeit 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. PR #672 - by @gaborbernat.Stop
StrictSoftFileLockandAsyncStrictSoftFileLockcalling themselves a native OS lock when they warn that they ignorelifetime; they now say a strict claim is only ever cleared byforce_break(). PR #672 - by @gaborbernat.
Documentation¶
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
StrictSoftFileLockexposesowner, thatSoftFileLockevicts a strict sentinel, thatReadWriteLockrequires a.dbextension, and that every log record isDEBUG. PR #672 - by @gaborbernat.
3.30.1 (2026-07-16)¶
Fixed¶
StrictSoftFileLockandAsyncStrictSoftFileLockno 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. PR #669 - by @gaborbernat.SoftFileLeasereads a marker whose lease duration isnanorinfas malformed rather than as a valid lease, so such a marker ages out through the grace window instead of raisingLeaseSettingsMismatchon every contender. PR #670 - by @dxbjavid.
3.30.0 (2026-07-16)¶
Added¶
Add
context_error_policyto surface body and release failures as aBaseExceptionGroup. PR #618 - by @gaborbernat.Add
close_error_policyto control anos.close()failure after the OS unlock. PR #619 - by @gaborbernat.Add
lock_descriptor()andunlock_descriptor()to lock a caller-owned file descriptor. PR #620 - by @gaborbernat.Add
fallback_to_softto fail closed instead of downgrading toSoftFileLockonENOSYS. PR #622 - by @gaborbernat.Add
preserve_lock_fileso native locks keep the lock pathname on release. PR #624 - by @gaborbernat.Add an
on_acquiredhook that runs a callback on the locked descriptor once the lock is held. PR #625 - by @gaborbernat.Add
StrictSoftFileLock, which treats every marker it did not publish as contention, andSoftFileLease, whose claim expires and whose holder learns throughon_compromisewhen it is lost.SoftFileLock(lifetime=...)now warns and names them. Both publish a recordSoftFileLockevicts, so do not mix contracts on one path. PR #658 - by @gaborbernat.Add
StrictSoftFileLockandAsyncStrictSoftFileLockwith 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. PR #659 - by @gaborbernat.
Changes¶
Make native lock release transactional so a failed unlock is retried, not dropped. PR #615 - by @gaborbernat.
Fixed¶
Ignore
lifetimeon native locks with a warning; onlySoftFileLockhonors it. PR #593 - by @gaborbernat.Stop mutating the Unix lock file before
fcntl.flock()is held. PR #594 - by @gaborbernat.Evict a non-regular soft lock file without reading it. PR #597 - by @dxbjavid.
Write a soft lock’s holder record atomically so a short write cannot create overlapping holders. PR #614 - by @gaborbernat.
Open the Windows lock file via
NtCreateFileso a real access denial is raised, not reported as a timeout. PR #617 - by @gaborbernat.Canonicalize singleton keys so equivalent path spellings share an instance, without following a final symlink. PR #621 - by @gaborbernat.
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. Iffstat()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. PR #652 - by @gaborbernat.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. PR #657 - by @gaborbernat.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. PR #652 - by @gaborbernat.Reject negative and non-finite
lifetimevalues during lock construction and assignment. PR #644 - by @gaborbernat.Read the saved Windows process-probe error before deciding that a soft-lock holder has exited. PR #645 - by @gaborbernat.
Reject non-default lock options that a narrow subclass constructor cannot honor, and forward all options through subclasses that accept arbitrary keyword arguments. PR #646 - by @gaborbernat.
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. PR #647 - by @gaborbernat.
Remove the body error from implicit context on the release error before adding both errors to an exception group. PR #648 - by @gaborbernat.
Relinquish a soft lock’s descriptor before one close attempt so a later release cannot close a reused descriptor number, and honor
close_error_policywhile still attempting marker cleanup. PR #649 - by @gaborbernat.Raise
OSError(errno.ENOSYS)from descriptor locks whenfcntlis unavailable, and reject invalid blocking poll intervals before attempting a lock. PR #650 - by @gaborbernat.SoftFileLockandSoftFileLeaserecord 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. PR #660 - by @gaborbernat.SoftReadWriteLockandSoftFileLeaseride 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.SoftFileLeasealso reclaims a malformed or partial marker that used to block every contender, and a Linux marker distinguishes a PID reused across a reboot. PR #661 - by @gaborbernat.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. PR #665 - by @gaborbernat.
Documentation¶
Correct the Unix lock-file cleanup and
fcntl.flock()documentation. PR #623 - by @gaborbernat.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
StrictSoftFileLockandSoftFileLease, and the cross-platform process start token replacing the Windows-only description throughout. PR #663 - by @gaborbernat.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. PR #665 - by @gaborbernat.
Security¶
Bind the Windows reparse-point check to the locked handle to close a symlink-swap race. PR #596 - by @gaborbernat.
3.29.7 (2026-07-07)¶
Fixed¶
Evict a non-regular write marker without reading it PR #588 - by @gaborbernat.
Detect cross-instance reentrant deadlocks before the poll loop https://github.com/tox-dev/filelock/commit/616400e382cdc9cc8c95823014e4d2d61a70095c - by @HrachShah
3.29.6 (2026-07-06)¶
Fixed¶
3.29.5 (2026-07-02)¶
Changes¶
Fixed¶
Reject negative, non-numeric, and bool values at the setter https://github.com/tox-dev/filelock/commit/be562277636140c26578a98a2a487fdb6f446ee6 - by @HrachShah
Roll back a read acquire’s open transaction when its SELECT fails PR #575 - by @dxbjavid
Keep Unix lock files after release PR #577 - by @itscloud0
Don’t complete a writer acquire on a peer’s reclaimed marker PR #571 - by @dxbjavid
Don’t follow symlinks in
raise_on_not_writable_filePR #567 - by @dxbjavidOnly unlink the writer marker on release if it is still ours PR #566 - by @dxbjavid
Don’t follow symlinks when refreshing soft read/write lock markers PR #565 - by @dxbjavid
Serialize read/write release rollback against a concurrent acquire PR #563 - by @dxbjavid
3.29.4 (2026-06-13)¶
Fixed¶
3.29.3 (2026-06-10)¶
Fixed¶
3.29.2 (2026-06-10)¶
Fixed¶
Recover malformed soft-lock markers without breaking a live lock. PR #551 - by @gaborbernat.
Security¶
3.29.1 (2026-06-03)¶
Documentation¶
Security¶
3.29.0 (2026-04-19)¶
Added¶
Detect stale soft locks on Windows. PR #534 - by @gaborbernat.
Fixed¶
Use one executor thread for async lock operations to keep acquisition and release ordered. PR #533 - by @gaborbernat.
3.28.0 (2026-04-14)¶
Added¶
Inspect a soft lock’s owner PID and break stale locks. PR #524 - by @gaborbernat.
Add
SoftReadWriteLockfor NFS and HPC clusters. PR #528 - by @gaborbernat.
Fixed¶
Handle
__exit__and event-loop shutdown forBaseAsyncFileLock. PR #518 - by @naarob.
3.25.2 (2026-03-11)¶
Fixed¶
Suppress
EIOwhen closing a Unix lock on a Docker bind mount. PR #513 - by @gaborbernat.
3.25.1 (2026-03-09)¶
Fixed¶
Restore best-effort lock file cleanup on Windows. PR #511 - by @gaborbernat.
Documentation¶
Add the project logo to the documentation. PR #507 - by @gaborbernat.
3.25.0 (2026-03-01)¶
Added¶
Add
AsyncReadWriteLock. PR #506 - by @gaborbernat.
Fixed¶
Suppress
ValueErrorwhile checking a corrupt stale-lock marker. PR #496 - by @bysiberFix nonblocking transaction-lock acquisition with a timeout. PR #498 - by @gaborbernat
3.24.3 (2026-02-19)¶
Fixed¶
Handle an
ENOENTrace while acquiring a lock on FUSE or NFS. PR #495 - by @gaborbernat.
3.24.2 (2026-02-16)¶
Fixed¶
Close SQLite cursors and avoid a
SoftFileLockrace on Windows. PR #491 - by @gaborbernat.
Documentation¶
Organize the documentation into tutorials, how-to guides, reference, and explanations. PR #489 - by @gaborbernat.
3.24.1 (2026-02-15)¶
Fixed¶
Fix a soft-lock deadlock on Windows. PR #488 - by @gaborbernat.
3.24.0 (2026-02-14)¶
Added¶
Add a
lifetimeparameter for lock expiration (issue #68). PR #486 - by @gaborbernat.Add
cancel_checktoacquire()(issue #309). PR #487 - by @gaborbernat.Honor POSIX default ACLs when creating a lock file (issue #378). PR #483 - by @gaborbernat.
Add
poll_intervalto the lock constructor. PR #482 - by @gaborbernat.
Fixed¶
Detect a same-thread self-deadlock. PR #481 - by @gaborbernat.
Fix a lock file race between threads on Windows. PR #484 - by @gaborbernat.
Fall back to
SoftFileLockwhen native locking fails withENOSYS. PR #480 - by @gaborbernat.
3.23.0 (2026-02-14)¶
Changes¶
Change the project license from Unlicense to MIT. PR #479 - by @gaborbernat.
Documentation¶
List fasteners among the similar libraries in the documentation. PR #478 - by @gaborbernat.
3.22.0 (2026-02-14)¶
Added¶
Detect and break stale soft locks. PR #476 - by @gaborbernat.
Fixed¶
Disable stale-lock detection on Windows until its implementation is safe. PR #477 - by @gaborbernat.
3.21.2 (2026-02-13)¶
Fixed¶
Handle
ImportErrorwhen thesqlite3C library is unavailable. PR #475 - by @gaborbernat.
3.21.1 (2026-02-12)¶
Fixed¶
Import
ReadWriteLockwhensqlite3is unavailable. PR #473 - by @bayandin.
3.21.0 (2026-02-12)¶
v3.20.4 (2026-03-23)¶
Added¶
Add a SQLite-backed
ReadWriteLock. PR #399 - by @leventovAllow Unix lock files to be removed after release. PR #408 - by @sbc100
v3.20.3 (2026-01-09)¶
Security¶
Fix TOCTOU symlink vulnerability in
SoftFileLockPR #465 - by @gaborbernat.
v3.20.2 (2026-01-02)¶
Added¶
Support Unix systems without
os.O_NOFOLLOWPR #463 - by @mwilliamson.
v3.20.1 (2025-12-15)¶
Security¶
Fix TOCTOU symlink vulnerability in lock file creation PR #461 - by @gaborbernat.
v3.20.0 (2025-10-08)¶
Added¶
Add Python 3.14 support, drop 3.9 PR #448 - by @gaborbernat.
v3.19.1 (2025-08-14)¶
Added¶
Add support for Python 3.14 PR #432 - by @gaborbernat.
v3.18.0 (2025-03-11)¶
Added¶
Fixed¶
Indicate that locks are exclusive/write locks PR #394 - by @bicarlsen.
v3.17.0 (2025-01-21)¶
Added¶
Drop Python 3.8 support PR #388.
v3.16.1 (2024-09-17)¶
v3.16.0 (2024-09-07)¶
Added¶
Add Python 3.13 to CI PR #359 - by @gaborbernat.
v3.15.4 (2024-06-22)¶
Fixed¶
Pass
file_lockas positional argument PR #347 - by @kwist-sgr.
v3.15.3 (2024-06-19)¶
Fixed¶
Fix
TypeError: _CountedFileLock.__init__() got an unexpected keyword argumentPR #345 - by @kwist-sgr.
v3.15.2 (2024-06-19)¶
Changes¶
Use a metaclass to implement the singleton pattern PR #340 - by @kwist-sgr.
v3.15.1 (2024-06-12)¶
Fixed¶
v3.15.0 (2024-06-11)¶
Added¶
Fixed¶
Don’t re-initialize
BaseFileLockwhen returning existing singleton instance PR #334 - by @ethanbb.
v3.14.0 (2024-04-27)¶
Added¶
v3.13.4 (2024-04-09)¶
Fixed¶
v3.13.3 (2024-03-25)¶
Changes¶
v3.13.2 (2024-03-25)¶
Fixed¶
Fix permission denied error when lock file is placed in
/tmpPR #317 - by @kota-iizuka.
v3.13.1 (2023-10-30)¶
Added¶
v3.13.0 (2023-10-27)¶
Added¶
v3.12.4 (2023-09-13)¶
Packaging¶
v3.12.3 (2023-08-28)¶
Added¶
v3.12.2 (2023-06-12)¶
Fixed¶
v3.12.1 (2023-06-10)¶
Added¶
Add Python 3.12 support PR #237 - by @gaborbernat.
v3.12.0 (2023-04-18)¶
Changes¶
Fixed¶
v3.11.0 (2023-04-06)¶
Changes¶
v3.10.7 (2023-03-27)¶
Fixed¶
Use
os.fchmod()to avoid aos.chmod()failure on PyPy via Anaconda. PR #214 - by @jfennick.
v3.10.6 (2023-03-25)¶
Fixed¶
Raise unexpected file-opening errors from
SoftFileLockinstead of repeatedly waiting for a lock that cannot be acquired. PR #213 - by @jahrules and @gaborbernat.
v3.10.5 (2023-03-25)¶
Added¶
Raise
NotImplementedErrorwhen a Unix filesystem does not supportflockinstead of waiting indefinitely. PR #212 - by @jahrules.
v3.10.4 (2023-03-24)¶
Fixed¶
v3.10.3 (2023-03-23)¶
Fixed¶
Fix permission issue - by @jahrules.
v3.10.2 (2023-03-22)¶
Fixed¶
Bug fix for using filelock with threaded programs causing undesired file permissions - by @jahrules.
v3.10.1 (2023-03-22)¶
Fixed¶
v3.10.0 (2023-03-15)¶
Added¶
v3.9.1 (2023-03-14)¶
Changes¶
Use
time.perf_counter()instead oftime.monotonic()to calculate timeouts. PR #194 - by @zpz.
v3.9.0 (2022-12-28)¶
v3.8.2 (2022-12-05)¶
Packaging¶
v3.8.1 (2022-12-04)¶
Fixed¶
Make
FileLockvalid in mypy type annotations. PR #177 - by @gaborbernat.
v3.8.0 (2022-12-04)¶
Added¶
Add Python 3.11 support. PR #158 - by @gaborbernat.
Documentation¶
State timeout units in the API docstrings. PR #148 - by @jnordberg.
v3.7.1 (2022-05-31)¶
Documentation¶
Point README documentation links to the site index - by @gaborbernat.
v3.7.0 (2022-05-13)¶
Added¶
Allow a lock attempt to return immediately when the lock cannot be acquired. PR #142 - by @myheroyuki.
v3.6.0 (2022-02-17)¶
Fixed¶
Fix pylint warning “Abstract class
WindowsFileLockwith abstract methods instantiated” PR #135 - by @vonschultzFix pylint warning “Abstract class
UnixFileLockwith abstract methods instantiated” PR #135 - by @vonschultz
v3.5.1 (2022-02-16)¶
Fixed¶
v3.5.0 (2022-02-15)¶
Added¶
Allow a lock to be used as a context decorator. PR #128 - by Hirsch Alter.
v3.4.2 (2021-12-16)¶
Added¶
Drop Python 3.6 support. PR #125 - by @gaborbernat.
v3.4.1 (2021-12-16)¶
Fixed¶
Point argument deprecation warnings at the caller by setting
stacklevel. PR #121 - by @XuehaiPan.
v3.4.0 (2021-11-16)¶
Deprecated¶
Add correct spelling of poll interval parameter for
acquire()method, raise deprecation warning when using the misspelled form PR #119 - by @XuehaiPan.
v3.3.2 (2021-10-29)¶
Added¶
Accept
pathlib.Pathandpathlib.PurePathin theFileLockconstructor. PR #110 - by @f-koehler.
v3.3.1 (2021-10-15)¶
Fixed¶
Leave the log level of the
filelocklogger as not set (previously was set to warning) PR #108 - by @gaborbernat
Documentation¶
Add changelog to the documentation PR #108 - by @gaborbernat
v3.3.0 (2021-10-03)¶
Added¶
Drop Python 2.7 and 3.5 support. PR #100 - by @gaborbernat.
Add type annotations. PR #100 - by @gaborbernat.
Documentation¶
Document asyncio support - by @gaborbernat
v3.2.1 (2021-10-02)¶
Fixed¶
Documentation¶
Add a tutorial covering lock acquisition, timeouts, and recursive use - by @gaborbernat.
v3.2.0 (2021-09-30)¶
Changes¶
Move lock acquire/release log from INFO to DEBUG PR #95 - by @gaborbernat
Fixed¶
Raise when trying to acquire in R/O or missing folder PR #96 - by @gaborbernat
v3.1.0 (2021-09-27)¶
Documentation¶
Fix the LICENSE link. PR #63 - by @sharkwouter.
Update links for the project’s move to tox-dev. PR #88 - by @hugovk.
v3.0.12 (2019-05-18)¶
Fixed¶
Fix package setup on Python 2 - by Benedikt Schmitt.
Documentation¶
Correct the timeout documentation: zero means no wait, while a negative value waits indefinitely. issue #49 - by Benedikt Schmitt; reported by @AnkurTank.
Packaging¶
Fix package upload to PyPI by keeping the license summary on one line - by Benedikt Schmitt.
Update the published PyPI classifiers - by @hugovk.
v3.0.10 (2018-11-01)¶
Documentation¶
Fix README rendering on PyPI - by @adamchainz.
v3.0.9 (2018-10-02)¶
v3.0.8 (2018-09-09)¶
Fixed¶
Fix a memory leak when acquiring locks on Python 2. issue #37 - by Benedikt Schmitt.
v3.0.6 (2018-08-22)¶
v3.0.4 (2018-02-01)¶
v3.0.3 (2018-01-30)¶
Documentation¶
Render the animated README example through a raw image URL on PyPI - by Benedikt Schmitt.
v3.0.2 (2018-01-30)¶
Fixed¶
Keep the Unix lock file after release to avoid a race between processes. issue #31 - by Benedikt Schmitt.
Documentation¶
Add navigation to the README - by Benedikt Schmitt.
Clarify when to use a separate lock file in the documentation. issue #22 - by Benedikt Schmitt.
v3.0.0 (2018-01-05)¶
Changes¶
Remove the Unix lock file after
release()- by @spokorski.
Fixed¶
Reraise lock errors correctly on Python 3 - by Benedikt Schmitt.
v2.0.13 (2017-11-05)¶
Fixed¶
Acquire the logger only when first needed. issue #24 - by Benedikt Schmitt.
v2.0.12 (2017-09-02)¶
v2.0.11 (2017-07-19)¶
Added¶
Add official Python 2 support. issue #20 - by Benedikt Schmitt.
v2.0.10 (2017-06-07)¶
v2.0.9 (2017-06-07)¶
Fixed¶
Documentation¶
Explain why the protected file needs a separate lock path. issue #19 - by Benedikt Schmitt.
Correct the Read the Docs URL - by Benedikt Schmitt.
v2.0.8 (2017-01-24)¶
Added¶
Add logging for lock operations - by @expobrain.
v2.0.7 (2016-11-05)¶
Packaging¶
Keep the README and license out of the installed environment root while including them in the source archive. issue #14 - by Benedikt Schmitt.
v2.0.6 (2016-05-01)¶
Fixed¶
Clear the lock descriptor before unlocking on Unix and Windows, avoiding a repeated release. - by @cottsay.
v2.0.5 (2015-11-11)¶
Fixed¶
Keep the lock file after release - by @kramarz.
Added¶
Export
BaseFileLockas a public class - by Benedikt Schmitt.
Documentation¶
Show the complete public API in the reference page - by Benedikt Schmitt.
v2.0.4 (2015-07-29)¶
Added¶
Export the platform-specific lock classes consistently through
__all__- by Benedikt Schmitt.
v2.0.1 (2015-06-13)¶
Fixed¶
Documentation¶
Add a documentation site with recursive locking examples and an API reference - by Benedikt Schmitt.
v2.0.0 (2015-05-25)¶
Added¶
Allow a default timeout at lock construction. issue #2 - by Benedikt Schmitt.
v1.0.3 (2015-04-22)¶
Fixed¶
Handle an exception while acquiring a lock - by Benedikt Schmitt.
v1.0.2 (2015-04-22)¶
Fixed¶
Do not time out when the same lock object already holds the lock - by Benedikt Schmitt.
v1.0.1 (2015-04-22)¶
Fixed¶
Return immediately after a successful first acquire instead of waiting one poll interval. issue #1 - by Benedikt Schmitt.
v1.0.0 (2015-04-07)¶
Added¶
Add a lock counter so the same lock object can acquire recursively - by Benedikt Schmitt.
v0.2.2 (2015-03-25)¶
Packaging¶
Include the renamed README and license files in the source distribution - by Benedikt Schmitt.
v0.2.1 (2015-03-25)¶
Packaging¶
Publish the README and license as reStructuredText so package metadata can render them - by Benedikt Schmitt.
v0.2.0 (2014-07-06)¶
Added¶
Add file locks for Unix and Windows - by Benedikt Schmitt.