unstale

pypi / filelock

filelock

What changed in filelock 4, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-18.

3 breaking3 security1 performance1 behavior and defaults22 fixes and other

See which of these apply to your code, ranked, in your agent:

npx @unstale/cli init

@unstale/cli 0.1.1 on npm

filelock 430 changes

Breaking changes 3

  • On Windows, a mode without group and other bits creates the lock file with an owner-only permission list.

    4.2.1release notes

  • Records are reached through descriptors opened without following symlinks, Windows junctions are refused, and heartbeats verify ownership before rewriting records.

    4.2.1release notes

  • The lock directory and claims directory are created with the lock's mode and the sticky bit; a later acquisition narrows a wider directory it owns.

    4.2.1release notes

Security 3

  • On Windows, a mode without group and other bits now creates the database with an owner-only permission list.

    4.2.1release notes

  • SQLite database access avoids journal, WAL, or shared-memory files placed beside the database by another account; unsafe directories use a private hard link, and unavailable hard links raise OSError on Windows.

    4.2.1release notes

  • Claims are reached through descriptors opened without following symlinks, Windows junctions are refused, and a coordination directory owned by another account under a sticky parent is refused.

    4.2.1release notes

Performance 1

  • Importing filelock is about twice as fast because lock types other than FileLock load on first use.

    4.2.0release notes

Behavior and default changes 1

  • On Linux and macOS, stale markers change hands in one atomic exchange; on other platforms without one, except Windows, the marker stays in place and waits for timeout or break_lock().

    4.2.1release notes

Fixes and other changes 22

  • A failed acquire on a relative path whose working directory no longer exists now leaves the lock's hold count unchanged, so a later with lock block can release the lock correctly. The failed call still raises FileNotFoundError.

    4.2.2release notes

  • Signal-handler exceptions while joining the queue no longer block later calls, and release returns after many acquires give up behind a waiter.

    4.2.1release notes

  • A thread_local=True lock shared by threads with their own event loops no longer deadlocks when one thread waits while another holds it.

    4.2.1release notes

  • Canceling an acquire waiting for another process now stops the wait and raises cancellation instead of waiting for release or raising Timeout.

    4.2.1release notes

  • Async read-write locks associate holds with their task owner, forget holds after a backend release that already let go, and free acquire memory on timeout or cancellation.

    4.2.1release notes

  • Async read-write wrappers stop admitting readers into a level whose release was interrupted.

    4.2.1release notes

  • Release gives back one level so synchronous readers of a shared singleton keep their own holds.

    4.2.1release notes

  • A lookup no longer returns a cached lock whose relative path now resolves to another file, or a lock whose finalizer is running.

    4.2.1release notes

  • A release interrupted by a signal handler no longer leaves the lock dropped, and the lock is reacquired after an interrupted release.

    4.2.1release notes

  • A database schema taking more than a few kilobytes to load raises ValueError rather than running past the acquire timeout.

    4.2.1release notes

  • On Windows, acquisition waits for its timeout and raises Timeout; a fork from another thread no longer waits for an acquire on a busy database.

    4.2.1release notes

  • The path resolved when acquisition starts remains in use until the hold ends, avoiding locks or markers being redirected when the process changes directory.

    4.2.1release notes

  • Closing a wrapper ends only holds acquired through that wrapper; wrappers refuse readers joining an ended hold, and closing one wrapper no longer ends another wrapper's nested hold.

    4.2.1release notes

  • Lease markers are no longer removed or displaced while live because of marker replacement, reused inode numbers, time-namespace differences, or stale-break races.

    4.2.1release notes

  • Soft lock markers are no longer removed or displaced while live because of empty marker contents, reused inode numbers, time-namespace differences, unreadable boot IDs, or marker replacement races.

    4.2.1release notes

  • An empty marker is treated as held, preventing contenders from evicting markers belonging to older versions or owners still writing their record.

    4.2.1release notes

  • Read levels are tracked per thread, so release by a thread holding none raises RuntimeError; after its heartbeat records a lost hold, it refuses new acquires until that hold is released.

    4.2.1release notes

  • A commit a whole retention window behind the log is refused, preventing adjacent stalled generations from admitting a second writer; stale checks sample the clock before reading a holder record.

    4.2.1release notes

  • Each concrete subclass now keeps its own singleton cache and construction guard, including after fork.

    4.2.1release notes

  • A non-regular node at a sentinel private-record name raises SoftFileLockProtocolError.

    4.2.1release notes

  • Opening the lock file no longer truncates a file the lock did not create or applies mode to it; an on_acquired hook writing holder metadata now truncates the file itself.

    4.2.1release notes

  • Fixes StrictSoftFileLock raising SoftFileLockProtocolError on Windows when a contender reads a claim while its owner is finishing the unlink.

    4.2.0release notes