.. towncrier-draft-entries:: Unreleased
- Fix read-lock acquisition on SQLite versions older than 3.33.0 by using
sqlite_master for the schema probe. :pr:`769`
ReadWriteLock and AsyncReadWriteLock use a validated private hard link when /dev/fd has 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.
- 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. :pr:`765`
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. :pr:`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).
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. :pr:`761`
- 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. :pr:`760`
- Reject negative blocking timeouts other than
-1 before reentrant ReadWriteLock and SoftReadWriteLock
acquisition. Preserve unlimited waits and nonblocking acquisition. :pr:`756`
- Fix
MarkerSoftFileLock acquisition and prevent contenders from evicting live protocol-2 owners after two seconds.
Reclaim recognized records after owner death; preserve unknown contracts. :pr:`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. :pr:`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. :pr:`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. :pr:`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. :pr:`755`
- 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`
- 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. :pr:`747`
- 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 (:issue:`744`). :pr:`745`
- :class:`~filelock.AsyncReadWriteLock` and :class:`~filelock.AsyncSoftReadWriteLock` now give each
asyncio task its
own hold, so tasks sharing one instance no longer enter the write lock together. :pr:`746`
- Correct the async cache example to create its data directory and clarify automatic creation of lock-file parent directories. :pr:`740`
- Exclude sphinx-llm 1.1.0 from documentation dependencies because its Markdown builder emits unknown-node warnings. :pr:`742`
poll_interval is now validated at construction, on the setter, and on acquire(): a negative, non-finite, or
non-numeric value raises :class:`ValueError`/:class:`TypeError` immediately instead of failing inside time.sleep. :pr:`739`
- The :class:`~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 :class:`~filelock.StrictSoftFileLock`, so a runtime without os.link raises
:class:`~filelock.SoftFileLockProtocolError` on acquire. Constructing a singleton again with a different
on_compromise, or with poll_interval at or above stale_threshold, now raises :class:`ValueError`. :pr:`735`
- :class:`~filelock.SoftReadWriteLock` exposes :attr:`~filelock.SoftReadWriteLock.generation` as a fencing token for
the protected resource and reports a lost hold through
on_compromise and
:attr:`~filelock.SoftReadWriteLock.compromise`. :pr:`735`
- :class:`~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 (:pr:`725`, :pr:`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. :pr:`735`
- Validate final-symlink refusal by error number so the test works across libc implementations. :pr:`737`
- Document that :meth:`~filelock.BaseFileLock.acquire` reads
blocking=None as the lock's blocking attribute and
raises :class:`~filelock.Timeout` after one attempt when blocking=False. :pr:`733`
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. :pr:`723`
- Reject non-finite heartbeat, stale, and polling intervals in
SoftReadWriteLock and AsyncSoftReadWriteLock,
including cached singleton construction and overflow in the default stale threshold. :pr:`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. :pr:`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. :pr:`728`
- Preserve exception notes and custom attributes when copying or pickling
Timeout and SoftFileLockProtocolError. :pr:`729`
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. :pr:`721`
- Document that
mode has no setter: unlike poll_interval, timeout, blocking and lifetime, it is fixed at construction and lock.mode = ... raises AttributeError. :pr:`716`
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. :pr:`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. :pr:`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. :pr:`709`
- 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. :pr:`701`
- 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. :pr:`691`
- Canceling an
AsyncSoftReadWriteLock acquire now releases the claim instead of leaking a marker whose heartbeat
wedges every contender. :pr:`686`
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. :pr:`685`
- Declare support for Python 3.15 and run the test suite against it and its free-threaded build, both currently in beta. :pr:`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. :pr:`685`
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. :pr:`681`
- 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. :pr:`680`
- 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. :pr:`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. :pr:`678`
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. :pr:`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. :pr:`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. :pr:`674`
- Stop :class:`~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. :pr:`672`
- Stop :class:`~filelock.StrictSoftFileLock` and :class:`~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(). :pr:`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 :class:`~filelock.SoftFileLock` evicts a strict sentinel, that :class:`~filelock.ReadWriteLock` requires a .db extension, and that every log record is DEBUG. :pr:`672`
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. :pr:`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. :pr:`670`
- Add
context_error_policy to surface body and release failures as a :exc:`BaseExceptionGroup`. :pr:`618`
- Add
close_error_policy to control an :func:`os.close` failure after the OS unlock. :pr:`619`
- Add :func:`~filelock.lock_descriptor` and :func:`~filelock.unlock_descriptor` to lock a caller-owned file descriptor. :pr:`620`
- Add
fallback_to_soft to fail closed instead of downgrading to :class:`~filelock.SoftFileLock` on ENOSYS. :pr:`622`
- Add
preserve_lock_file so native locks keep the lock pathname on release. :pr:`624`
- Add an
on_acquired hook that runs a callback on the locked descriptor once the lock is held. :pr:`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. :pr:`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. :pr:`637`
- Ignore
lifetime on native locks with a warning; only :class:`~filelock.SoftFileLock` honors it. :pr:`593`
- Stop mutating the Unix lock file before :func:`fcntl.flock` is held. :pr:`594`
- Bind the Windows reparse-point check to the locked handle to close a symlink-swap race. :pr:`596`
- Evict a non-regular soft lock file without reading it. :pr:`597`
- Write a soft lock's holder record atomically so a short write cannot create overlapping holders. :pr:`614`
- Make native lock release transactional so a failed unlock is retried, not dropped. :pr:`615`
- Open the Windows lock file via
NtCreateFile so a real access denial is raised, not reported as a timeout. :pr:`617`
- Canonicalize singleton keys so equivalent path spellings share an instance, without following a final symlink. :pr:`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. :pr:`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. :pr:`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. :pr:`640`
- Reject negative and non-finite
lifetime values during lock construction and assignment. :pr:`644`
- Read the saved Windows process-probe error before deciding that a soft-lock holder has exited. :pr:`645`
- 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`
- 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`
- Remove the body error from implicit context on the release error before adding both errors to an exception group. :pr:`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. :pr:`649`
- Raise
OSError(errno.ENOSYS) from descriptor locks when fcntl is unavailable, and reject invalid blocking poll
intervals before attempting a lock. :pr:`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. :pr:`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. :pr:`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. :pr:`665`
- Correct the Unix lock-file cleanup and :func:`fcntl.flock` documentation. :pr:`623`
- Drop automated bot entries from the changelog and link its code references to the API docs and the Python standard library. :pr:`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. :pr:`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. :pr:`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. :pr:`626`
- _util: drop the dead
st_mtime=0 short-circuit in raise_on_not_writable_file :pr:`589` - by :user:`HrachShah`
- soft_rw: evict a non-regular write marker without reading it :pr:`588`
- asyncio: detect cross-instance reentrant deadlocks before the poll loop :pr:`586` - by :user:`HrachShah`
- test: silence fork DeprecationWarning on 3.15 :pr:`585`
- _util: drop the dead
st_mtime=0 short-circuit in raise_on_not_writable_file :pr:`582` - by :user:`HrachShah`
- serialize singleton construction in
FileLockMeta :pr:`581` - by :user:`dxbjavid`
- surface GitHub Sponsors and thanks.dev
- lifetime: reject negative, non-numeric, and bool values at the setter :pr:`573` - by :user:`HrachShah`
- roll back a read acquire's open transaction when its SELECT fails :pr:`575` - by :user:`dxbjavid`
- keep Unix lock files after release :pr:`577` - by :user:`itscloud0`
- use a private break name in
break_lock_file :pr:`576` - by :user:`dxbjavid`
- don't complete a writer acquire on a peer's reclaimed marker :pr:`571` - by :user:`dxbjavid`
- don't follow symlinks in
raise_on_not_writable_file :pr:`567` - by :user:`dxbjavid`
- only unlink the writer marker on release if it is still ours :pr:`566` - by :user:`dxbjavid`
- don't follow symlinks when refreshing soft read/write lock markers :pr:`565` - by :user:`dxbjavid`
- serialize read/write release rollback against a concurrent acquire :pr:`563` - by :user:`dxbjavid`
- keep the read/write heartbeat alive on a transient touch error :pr:`562` - by :user:`dxbjavid`
- verify inode in
break_lock_file before unlinking a stale lock :pr:`561` - by :user:`dxbjavid`
- 🐛 fix(ci): restore release environment on tag job :pr:`559`
- validate pid range in
_parse_lock_holder :pr:`556` - by :user:`dxbjavid`
- 🔧 ci(release): publish to PyPI on tag push :pr:`557`
- check hostname in
is_lock_held_by_us :pr:`553` - by :user:`dxbjavid`
- 🔒 fix(soft): harden stale-lock breaking and self-heal malformed locks :pr:`551`
- open marker reads non-blocking to refuse attacker-placed fifo :pr:`549` - by :user:`dxbjavid`
- 🐛 fix(soft): refuse to follow symlinks when reading the lock file :pr:`548` - by :user:`dxbjavid`
- chore: improve filelock maintenance path :pr:`545` - by :user:`lphuc2250gma`
- chore: improve filelock maintenance path :pr:`544` - by :user:`lphuc2250gma`
- chore: improve filelock maintenance path :pr:`542` - by :user:`lphuc2250gma`
- docs: clarify per-thread scope of :class:`~filelock.FileLock` configuration :pr:`543` - by :user:`Gares95`
- docs: fix API docs of :meth:`~filelock.BaseFileLock.release` :pr:`540` - by :user:`MrAnno`
- ✨ feat(soft): enable stale lock detection on Windows :pr:`534`
- 🐛 fix(async): use single-thread executor for lock consistency :pr:`533`
- 🐛 fix(ci): unbreak release workflow, publish to PyPI again :pr:`529`
- 🐛 fix(asyncio): add
__exit__ to :class:`~filelock.BaseAsyncFileLock` and fix __del__ loop handling :pr:`518` - by :user:`naarob`
- ✨ feat(soft): add PID inspection and lock breaking :pr:`524`
- Remove persist-credentials: false from release job :pr:`520`
- 🔒 ci(workflows): add zizmor security auditing :pr:`517`
- 🐛 fix(unix): suppress
EIO on close in Docker bind mounts :pr:`513`
- 🐛 fix(win): restore best-effort lock file cleanup on release :pr:`511`
- 📝 docs(logo): add branded project logo :pr:`507`
- ✨ feat(async): add :class:`~filelock.AsyncReadWriteLock` :pr:`506`
- Standardize .github files to .yaml suffix
- Move SECURITY.md to .github/SECURITY.md
- Add security policy
- Add permissions to check workflow :pr:`500`
- 🐛 fix(unix): handle
ENOENT race on FUSE/NFS during acquire :pr:`495`
- 🐛 fix(ci): add trailing blank line after changelog entries :pr:`492`
- 🐛 fix(rw): close :mod:`sqlite3` cursors and skip :class:`~filelock.SoftFileLock` Windows race :pr:`491`
- 🐛 fix(test): resolve flaky write non-starvation test :pr:`490`
- 📝 docs: restructure using Diataxis framework :pr:`489`
- 🐛 fix(soft): resolve Windows deadlock and test race condition :pr:`488`
- ✨ feat(lock): add
lifetime parameter for lock expiration (#68) :pr:`486`
- ✨ feat(lock): add
cancel_check to :meth:`~filelock.BaseFileLock.acquire` (#309) :pr:`487`
- 🐛 fix(api): detect same-thread self-deadlock :pr:`481`
- ✨ feat(mode): respect POSIX default ACLs (#378) :pr:`483`
- 🐛 fix(win): eliminate lock file race in threaded usage :pr:`484`
- ✨ feat(lock): add
poll_interval to constructor :pr:`482`
- 🐛 fix(unix): auto-fallback to :class:`~filelock.SoftFileLock` on
ENOSYS :pr:`480`
- 📝 docs: move from Unlicense to MIT :pr:`479`
- 📝 docs: add fasteners to similar libraries :pr:`478`
- 🐛 fix(soft): skip stale detection on Windows :pr:`477`
- ✨ feat(soft): detect and break stale locks :pr:`476`
- 🐛 fix: catch :exc:`ImportError` for missing :mod:`sqlite3` C library :pr:`475`
- 🐛 fix: gracefully handle missing :mod:`sqlite3` when importing :class:`~filelock.ReadWriteLock` :pr:`473` - by :user:`bayandin`
- 🐛 fix(ci): make release workflow robust
- 🐛 fix(ci): make release workflow robust
- 👷 ci(release): commit changelog and use release config :pr:`472`
- 👷 ci(release): consolidate to two jobs :pr:`471`
- ✨ feat(unix): delete lock file on release :pr:`408` - by :user:`sbc100`
- ✨ feat(lock): add SQLite-based :class:`~filelock.ReadWriteLock` :pr:`399` - by :user:`leventov`
- 🔧 chore: modernize tooling and bump deps :pr:`470`
- Fix TOCTOU symlink vulnerability in :class:`~filelock.SoftFileLock` :pr:`465`.
- Support Unix systems without :data:`os.O_NOFOLLOW` :pr:`463`.
- Fix TOCTOU symlink vulnerability in lock file creation :pr:`461`.
- Add Python 3.14 support, drop 3.9 :pr:`448`.
- Add
tox.toml to sdist :pr:`436`.
- Increase test coverage :pr:`434`.
- Add support for Python 3.14 :pr:`432`.
- Support :mod:`fcntl` check on Emscripten :pr:`398`.
- Indicate that locks are exclusive/write locks :pr:`394`.
- Drop Python 3.8 support :pr:`388`.
- CI improvements :pr:`362`.
- Add Python 3.13 to CI :pr:`359`.
- Pass
file_lock as positional argument :pr:`347`.
- Fix
TypeError: _CountedFileLock.__init__() got an unexpected keyword argument :pr:`345`.
- Use a metaclass to implement the singleton pattern :pr:`340`.
- Restore
__init__ method; more robust initialization for singleton locks :pr:`338`.
- Add asyncio support :pr:`332`.
- Don't re-initialize :class:`~filelock.BaseFileLock` when returning existing singleton instance :pr:`334`.
- Add
blocking parameter on lock constructor :pr:`325`.
- Raise error on incompatible singleton
timeout and mode arguments :pr:`320`.
- Make singleton class instance dict unique per subclass :pr:`318`.
- Fix permission denied error when lock file is placed in
/tmp :pr:`317`.
- Allow users to subclass :class:`~filelock.FileLock` with custom keyword arguments :pr:`284`.
- Support reentrant locking on lock file path via optional
is_singleton instance :pr:`283`.
- Change
typing-extensions to be installed only with the [typing] extra :pr:`276`.
- Add
tox.ini to sdist :pr:`265`.
- Create parent directories if necessary :pr:`254`.
- Restore
if TYPE_CHECKING syntax for :class:`~filelock.FileLock` definition :pr:`245`.
- Add Python 3.12 support :pr:`237`.
- Use ruff for linting :pr:`244`.
- Make the thread local behavior something the caller can enable/disable via a flag during the lock creation, it's on by
default.
- Better error handling on Windows.
- Make the lock thread local.
- Use :func:`os.fchmod` instead of :func:`os.chmod` to work around bug in PyPy via Anaconda.
- Enhance the robustness of the try/catch block in _soft.py. by :user:`jahrules`.
- Add explicit error check as certain UNIX filesystems do not support flock. by :user:`jahrules`.
- Update os.open to preserve mode= for certain edge cases. by :user:`jahrules`.
- Fix permission issue - by :user:`jahrules`.
- Bug fix for using filelock with threaded programs causing undesired file permissions - by :user:`jahrules`.
- Handle pickle for :class:`~filelock.Timeout` :pr:`203` - by :user:`TheMatt2`.
- Add support for explicit file modes for lockfiles :pr:`192` - by :user:`jahrules`.
- Use :func:`time.perf_counter` instead of :func:`time.monotonic` for calculating timeouts.
- Move build backend to
hatchling :pr:`185` - by :user:`gaborbernat`.
- Fix mypy does not accept :class:`~filelock.FileLock` as a valid type
- Bump project dependencies
- Add timeout unit to docstrings
- Support 3.11
- Make the readme documentation point to the index page
- Add ability to return immediately when a lock cannot be obtained
- Fix pylint warning "Abstract class :class:`~filelock.WindowsFileLock` with abstract methods
instantiated" :pr:`135` - by :user:`vonschultz`
- Fix pylint warning "Abstract class :class:`~filelock.UnixFileLock` with abstract methods instantiated"
:pr:`135` - by :user:`vonschultz`
- Use :func:`time.monotonic` instead of :func:`time.time` for calculating timeouts.
- Enable use as context decorator
- Drop support for python
3.6
- Add
stacklevel to deprecation warnings for argument name change
- Add correct spelling of poll interval parameter for :meth:`~filelock.BaseFileLock.acquire` method, raise
deprecation warning when using the misspelled form :pr:`119` - by :user:`XuehaiPan`.
- Accept path types (like :class:`pathlib.Path` and :class:`pathlib.PurePath`) in the constructor for :class:`~filelock.FileLock` objects.
- Add changelog to the documentation :pr:`108` - by :user:`gaborbernat`
- Leave the log level of the
filelock logger as not set (previously was set to warning) :pr:`108` - by
:user:`gaborbernat`
- Drop python 2.7 and 3.5 support, add type hints :pr:`100` - by :user:`gaborbernat`
- Document asyncio support - by :user:`gaborbernat`
- fix typo :pr:`98` - by :user:`jugmac00`
- Improve documentation
- Changed logger name from
filelock._api to filelock :pr:`97` - by :user:`hkennyv`
- Raise when trying to acquire in R/O or missing folder :pr:`96` - by :user:`gaborbernat`
- Move lock acquire/release log from INFO to DEBUG :pr:`95` - by :user:`gaborbernat`
- Fix spelling and remove ignored flake8 checks - by :user:`gaborbernat`
- Split main module :pr:`94` - by :user:`gaborbernat`
- Move test suite to pytest :pr:`93` - by :user:`gaborbernat`
- Update links for new home at tox-dev :pr:`88` - by :user:`hugovk`
- Fixed link to LICENSE file :pr:`63` - by :user:`sharkwouter`
- Adopt tox-dev organization best practices :pr:`87` - by :user:`gaborbernat`
- Ownership moved from :user:`benediktschmitt` to the tox-dev organization (new primary maintainer :user:`gaborbernat`)
- fixed setuptools and twine/warehouse error by making the license only 1 line long
- update version for pypi upload
- fixed python2 setup error
- added test.py module to MANIFEST and made tests available in the setup commands :issue:`48`
- fixed documentation thanks to :user:`AnkurTank` :issue:`49`
- Update Trove classifiers for PyPI
- test: Skip test_del on PyPy since it hangs
- Fix README rendering on PyPI
- :pr:`38` from cottsay/shebang
- updated docs config for older sphinx compatibility
- removed misleading shebang from module
- fixed garbage collection (:issue:`37`)
- fix travis ci badge (use rst not markdown)
- changed travis uri
- clean up
- Fixed unit test for Python 2.7
- Added Travis banner
- Added Travis CI support
- Corrected the prequel reference
- updated README (added navigation)
- updated documentation :issue:`22`
- fix the :class:`~filelock.SoftFileLock` test was influenced by the test for :class:`~filelock.FileLock`
- undo
cb1d83d :issue:`31`
- updated major version number due to :issue:`29` and :issue:`27`
- fixed use proper Python3
reraise method
- Attempting to clean up lock file on Unix after :meth:`~filelock.BaseFileLock.release`
- changed The logger is now acquired when first needed. :issue:`24`
- added official support for python 2 :issue:`20`
- updated readme :issue:`19`
- added example :pr:`16`
- updated readthedocs url
- updated change order of the examples (:pr:`16`)
- Added logging
- Removed unused imports
- fixed :issue:`14` (moved license and readme file to
MANIFEST)
- changed unlocking sequence to fix transient test failures
- changed threads in tests so exceptions surface
- added test lock file cleanup
- Don't remove file after releasing lock
- updated docs
- added the new classes to
__all__
- added The :class:`~filelock.SoftFileLock` is now always tested
- The filelock classes are now always available and have been moved out of the
if msvrct: ... elif fcntl ... else
clauses.
- fixed :issue:`5`
- updated test cases
- updated documentation
- fixed :issue:`2` which has been introduced with the lock counter
- added default timeout (fixes :issue:`2`)
- added new test case, fixed unhandled exception
- fixed a timeout could still be thrown if the lock is already acquired
- added lock counter, added unittest, updated to version 1
- changed filenames
- updated version for pypi
- updated README, LICENSE (changed format from md to rst)
- added MANIFEST to gitignore
- added os independent file lock ; changed setup.py for pypi
- Update README.md
- initial version