filelock
raw JSON → 3.25.2 verified Tue May 12 auth: no python install: verified quickstart: verified
filelock is a platform-independent file locking library for Python that provides inter-process synchronization via OS-level primitives (fcntl on Unix, msvcrt on Windows) with automatic fallback to soft (file-existence) locking. It supports exclusive locks (FileLock, SoftFileLock), SQLite-backed read-write locks (ReadWriteLock, added in 3.21.0), and async variants (AsyncFileLock, AsyncReadWriteLock, added in 3.25.0). The current stable version is 3.25.2, released March 2026; the project ships multiple releases per month and requires Python ≥ 3.10.
pip install filelock Common errors
error ModuleNotFoundError: No module named 'filelock' ↓
cause The `filelock` package is not installed in the Python environment being used.
fix
Install the
filelock library using pip: pip install filelock error AttributeError: 'FileLock' object has no attribute '_thread_lock' ↓
cause This error often occurs due to a breaking change in the `filelock` library's internal API between versions, where an internal attribute like `_thread_lock` or `_lock_file` was removed or renamed.
fix
Upgrade
filelock to the latest version (pip install --upgrade filelock) or, if the problem persists, try downgrading to a known stable version that is compatible with your other dependencies (e.g., pip install filelock==3.19.1 if a newer version is causing the issue). Ensure all related packages are also up to date. error filelock.Timeout ↓
cause The lock could not be acquired within the specified `timeout` period, meaning another process held the lock for too long.
fix
Increase the
timeout value when creating the FileLock object or implement retry logic with a backoff strategy. Alternatively, ensure that processes holding the lock release it promptly. error NotImplementedError: FileSystem does not appear to support flock; user SoftFileLock instead ↓
cause The underlying operating system or filesystem (e.g., some network file systems) does not support the `fcntl.flock` system call used by the default `FileLock` for hard locking.
fix
Use
SoftFileLock instead of FileLock, as SoftFileLock relies on file existence (a soft lock) which is more portable across various filesystems, including network mounts: from filelock import SoftFileLock; lock = SoftFileLock('my_file.lock') Warnings
breaking Python < 3.10 is no longer supported as of filelock 3.x modern releases. The requires-python constraint is >=3.10. ↓
fix Upgrade to Python 3.10+. Pin filelock<3.12 only if you must stay on Python 3.8/3.9 (unsupported path).
gotcha Never lock the file you intend to write; create a separate companion .lock file. Locking the target file directly causes undefined behaviour because filelock may truncate or interfere with it. ↓
fix Use a path like 'myfile.txt.lock' and open 'myfile.txt' only inside the lock context.
gotcha Timeout=None (the default) and timeout=-1 both mean 'block forever'. A timeout of 0 means exactly one non-blocking attempt. Passing timeout=0 does NOT mean 'no timeout'. ↓
fix Pass timeout=-1 explicitly for infinite wait; pass a positive float for a real deadline; catch filelock.Timeout, not TimeoutError.
gotcha SoftFileLock can leave stale lock files if a process crashes. On network/FUSE mounts where fcntl is unsupported, FileLock silently falls back to SoftFileLock (since 3.24.0), which is only stale-safe on same-host contention. ↓
fix For cross-host NFS/FUSE use-cases, rely on SoftFileLock's built-in PID+hostname stale detection (>=3.22.0) and set a sensible timeout.
breaking ReadWriteLock requires the lock file path to use a .db extension (it is backed by SQLite). Passing a plain .lock path raises an error. ↓
fix Use: ReadWriteLock('myresource.db') not ReadWriteLock('myresource.lock').
gotcha ReadWriteLock upgrading or downgrading lock mode (read→write or write→read) within the same thread raises RuntimeError. The lock is reentrant only within the same mode. ↓
fix Release the lock fully before re-acquiring in a different mode.
deprecated The poll_intervall parameter (double-l spelling) in acquire() is deprecated in favour of poll_interval (single-l). Both are accepted for backward compatibility but the old spelling will eventually be removed. ↓
fix Use poll_interval=0.05 (or your preferred float) in acquire() calls.
Install compatibility verified last tested: 2026-05-12
python os / libc status wheel install import disk
3.10 alpine (musl) - - 0.14s 18.0M
3.10 slim (glibc) - - 0.10s 18M
3.11 alpine (musl) - - 0.23s 19.8M
3.11 slim (glibc) - - 0.18s 20M
3.12 alpine (musl) - - 0.43s 11.7M
3.12 slim (glibc) - - 0.41s 12M
3.13 alpine (musl) - - 0.42s 11.3M
3.13 slim (glibc) - - 0.40s 12M
3.9 alpine (musl) - - 0.10s 17.4M
3.9 slim (glibc) - - 0.08s 18M
Imports
- FileLock wrong
import filelock; filelock.FileLock(...)correctfrom filelock import FileLock - Timeout
from filelock import Timeout - SoftFileLock
from filelock import SoftFileLock - ReadWriteLock
from filelock import ReadWriteLock - AsyncFileLock
from filelock import AsyncFileLock - AsyncReadWriteLock
from filelock import AsyncReadWriteLock
Quickstart verified last tested: 2026-04-23
from filelock import FileLock, Timeout
# Always lock a *separate* .lock file, not the file you intend to write.
lock = FileLock("data.txt.lock", timeout=10)
try:
with lock:
with open("data.txt", "a") as f:
f.write("safe write\n")
except Timeout:
print("Could not acquire lock within 10 seconds")
# Reentrant: acquiring the same lock object again inside the block is safe.
with lock:
with lock: # internal counter incremented; no deadlock
pass