{"id":272,"library":"filelock","title":"filelock","description":"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.","status":"active","version":"3.25.2","language":"python","source_language":"en","source_url":"https://github.com/tox-dev/filelock","tags":["file-locking","ipc","concurrency","cross-platform","async","threading","multiprocessing"],"install":[{"cmd":"pip install filelock","lang":"bash","label":"pip"}],"dependencies":[],"imports":[{"note":"Named import is idiomatic; module-level access still works but is verbose and was the old py-filelock style.","wrong":"import filelock; filelock.FileLock(...)","symbol":"FileLock","correct":"from filelock import FileLock"},{"note":"Always catch filelock.Timeout (not built-in TimeoutError) when using acquire(timeout=N).","symbol":"Timeout","correct":"from filelock import Timeout"},{"note":"Use instead of FileLock on network/FUSE mounts where fcntl is unavailable; since 3.24.0 FileLock auto-falls back on ENOSYS.","symbol":"SoftFileLock","correct":"from filelock import SoftFileLock"},{"note":"SQLite-backed multi-reader/single-writer lock added in 3.21.0. Lock file must use a .db extension.","symbol":"ReadWriteLock","correct":"from filelock import ReadWriteLock"},{"note":"Async variant; runs blocking I/O in a thread-pool executor. Use 'async with lock:' not 'with lock:'.","symbol":"AsyncFileLock","correct":"from filelock import AsyncFileLock"},{"note":"Added in 3.25.0. Wraps ReadWriteLock for asyncio; all SQLite ops dispatched to loop.run_in_executor().","symbol":"AsyncReadWriteLock","correct":"from filelock import AsyncReadWriteLock"}],"quickstart":{"code":"from filelock import FileLock, Timeout\n\n# Always lock a *separate* .lock file, not the file you intend to write.\nlock = FileLock(\"data.txt.lock\", timeout=10)\n\ntry:\n    with lock:\n        with open(\"data.txt\", \"a\") as f:\n            f.write(\"safe write\\n\")\nexcept Timeout:\n    print(\"Could not acquire lock within 10 seconds\")\n\n# Reentrant: acquiring the same lock object again inside the block is safe.\nwith lock:\n    with lock:  # internal counter incremented; no deadlock\n        pass\n","lang":"python","description":"Exclusive file lock with timeout; catch Timeout on contention."},"warnings":[{"fix":"Upgrade to Python 3.10+. Pin filelock<3.12 only if you must stay on Python 3.8/3.9 (unsupported path).","message":"Python < 3.10 is no longer supported as of filelock 3.x modern releases. The requires-python constraint is >=3.10.","severity":"breaking","affected_versions":"<3.10 (Python runtime)"},{"fix":"Use a path like 'myfile.txt.lock' and open 'myfile.txt' only inside the lock context.","message":"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.","severity":"gotcha","affected_versions":"all"},{"fix":"Pass timeout=-1 explicitly for infinite wait; pass a positive float for a real deadline; catch filelock.Timeout, not TimeoutError.","message":"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'.","severity":"gotcha","affected_versions":"all"},{"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.","message":"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.","severity":"gotcha","affected_versions":"all (stale detection: >=3.22.0 on Unix, not Windows)"},{"fix":"Use: ReadWriteLock('myresource.db') not ReadWriteLock('myresource.lock').","message":"ReadWriteLock requires the lock file path to use a .db extension (it is backed by SQLite). Passing a plain .lock path raises an error.","severity":"breaking","affected_versions":">=3.21.0"},{"fix":"Release the lock fully before re-acquiring in a different mode.","message":"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.","severity":"gotcha","affected_versions":">=3.21.0"},{"fix":"Use poll_interval=0.05 (or your preferred float) in acquire() calls.","message":"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.","severity":"deprecated","affected_versions":">=3.x"}],"env_vars":null,"last_verified":"2026-05-12T12:41:08.194Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"Install the `filelock` library using pip: `pip install filelock`","cause":"The `filelock` package is not installed in the Python environment being used.","error":"ModuleNotFoundError: No module named 'filelock'"},{"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.","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.","error":"AttributeError: 'FileLock' object has no attribute '_thread_lock'"},{"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.","cause":"The lock could not be acquired within the specified `timeout` period, meaning another process held the lock for too long.","error":"filelock.Timeout"},{"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')`","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.","error":"NotImplementedError: FileSystem does not appear to support flock; user SoftFileLock instead"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.14,"mem_mb":5.1,"disk_size":"18.0M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.1,"mem_mb":5.1,"disk_size":"18M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.23,"mem_mb":6.3,"disk_size":"19.8M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.18,"mem_mb":6.3,"disk_size":"20M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.43,"mem_mb":9,"disk_size":"11.7M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.41,"mem_mb":9,"disk_size":"12M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.42,"mem_mb":9.2,"disk_size":"11.3M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.4,"mem_mb":9.2,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.1,"mem_mb":4.7,"disk_size":"17.4M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.08,"mem_mb":4.7,"disk_size":"18M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}