Fasteners
raw JSON → 0.20 verified Tue May 12 auth: no python install: verified
Fasteners is a Python package that provides useful cross-platform synchronization primitives. It extends Python's standard library by offering inter-process exclusive locks, inter-process reader-writer locks, and thread-based reader-writer locks. The library aims to simplify concurrent programming across processes and threads. The current version is 0.20, with releases occurring periodically, often tied to Python version support updates.
pip install fasteners Common errors
error ModuleNotFoundError: No module named 'fasteners' ↓
cause The 'fasteners' package is not installed in the Python environment being used.
fix
Install the package using pip:
pip install fasteners error AttributeError: 'builtin_function_or_method' object has no attribute 'acquire' ↓
cause This error occurs when trying to call the `acquire` method on the `InterProcessLock` or `InterProcessReaderWriterLock` class itself, instead of an instantiated object of that class.
fix
Instantiate the lock class by adding parentheses:
lock = fasteners.InterProcessLock('path/to/lock.file') instead of lock = fasteners.InterProcessLock error fasteners InterProcessLock reentrant deadlock ↓
cause The `fasteners.InterProcessLock` is not reentrant, meaning a process cannot acquire a lock it already holds. Attempting to do so will result in a deadlock or crash.
fix
Design code to avoid recursive acquisition of
InterProcessLock. If reentrancy is required, consider using Python's standard library threading.RLock for thread-level reentrant locks, or refactor the process-level logic. error fasteners InterProcessReaderWriterLock upgrade deadlock ↓
cause The `fasteners.InterProcessReaderWriterLock` does not support upgrading a read lock to a write lock (or downgrading a write lock to a read lock) while holding the initial lock. This can lead to deadlocks or crashes.
fix
Explicitly release the first lock (e.g., read lock) before attempting to acquire the second lock (e.g., write lock). Ensure distinct acquisition patterns to prevent concurrent upgrades/downgrades.
error fasteners.InterProcessLock acquire timeout ↓
cause The `acquire()` method of `InterProcessLock` or `InterProcessReaderWriterLock` returns `False` if the lock cannot be acquired within the specified timeout, rather than raising an exception, which can lead to unexpected behavior if not handled.
fix
Always check the boolean return value of
acquire(timeout=...) to determine if the lock was successfully obtained, and handle the case where it returns False. Example: if lock.acquire(timeout=10): ... else: handle_timeout() Warnings
breaking Python version support is periodically dropped. Version 0.20 removed support for Python 3.8, 3.9, and PyPy 3.9. Previous versions (0.19, 0.18) also dropped support for older Python releases. ↓
fix Ensure your project uses a Python version compatible with your installed `fasteners` version. Refer to the official documentation or release notes for precise compatibility matrix.
gotcha `InterProcessLock` instances are *not reentrant*. Attempting to acquire a lock already held by the same process can lead to deadlocks or crashes upon release. ↓
fix Avoid recursive acquisition of `InterProcessLock`. Design your code so that a process either acquires the lock once or uses alternative reentrant locking mechanisms if recursion is necessary.
gotcha `InterProcessReaderWriterLock` instances are *not upgradable*. You cannot acquire a read lock while holding a write lock, or vice versa, without risking deadlocks or crashes. ↓
fix Ensure distinct acquisition patterns. If you need to upgrade a read lock to a write lock (or downgrade), you must explicitly release the first lock before attempting to acquire the second.
gotcha `InterProcessLock` and `InterProcessReaderWriterLock` provide guarantees *only between processes*, not between threads within a single process. They are not inherently thread-safe for intra-process concurrency. ↓
fix When using inter-process locks, ensure that any code within the locked section that involves multiple threads in the *same process* is protected by standard Python `threading` locks (e.g., `threading.Lock`) to prevent race conditions.
gotcha When using `InterProcessLock` or `InterProcessReaderWriterLock`, the `path` argument to the constructor is critical. Different processes must use the exact same string path to refer to the same underlying lock. Mismatched paths will result in independent locks. ↓
fix Always use an absolute and consistent file path for your inter-process lock files across all participating processes. Consider using `os.path.join` with a well-known directory or a configuration variable to ensure consistency.
Install compatibility verified last tested: 2026-05-12
python os / libc status wheel install import disk
3.10 alpine (musl) wheel - 0.03s 17.9M
3.10 alpine (musl) - - 0.03s 17.9M
3.10 slim (glibc) wheel 1.5s 0.02s 18M
3.10 slim (glibc) - - 0.02s 18M
3.11 alpine (musl) wheel - 0.06s 19.8M
3.11 alpine (musl) - - 0.08s 19.8M
3.11 slim (glibc) wheel 1.5s 0.06s 20M
3.11 slim (glibc) - - 0.05s 20M
3.12 alpine (musl) wheel - 0.05s 11.7M
3.12 alpine (musl) - - 0.06s 11.7M
3.12 slim (glibc) wheel 1.4s 0.05s 12M
3.12 slim (glibc) - - 0.06s 12M
3.13 alpine (musl) wheel - 0.05s 11.4M
3.13 alpine (musl) - - 0.05s 11.3M
3.13 slim (glibc) wheel 1.4s 0.04s 12M
3.13 slim (glibc) - - 0.05s 12M
3.9 alpine (musl) wheel - 0.03s 17.4M
3.9 alpine (musl) - - 0.03s 17.4M
3.9 slim (glibc) wheel 1.8s 0.03s 18M
3.9 slim (glibc) - - 0.03s 18M
Imports
- InterProcessLock
from fasteners import InterProcessLock - InterProcessReaderWriterLock
from fasteners import InterProcessReaderWriterLock - ReaderWriterLock
from fasteners import ReaderWriterLock - interprocess_locked wrong
@fasteners.interprocess_lockedcorrectfrom fasteners import interprocess_locked - locked wrong
@fasteners.lockedcorrectfrom fasteners import locked
Quickstart last tested: 2026-04-24
import time
import fasteners
import os
# For inter-process locks, a file path is required.
# Use a temporary file path for demonstration.
lock_file_path = os.path.join(os.getcwd(), 'my_app.lock')
@fasteners.interprocess_locked(lock_file_path)
def protected_function(worker_id):
print(f"Worker {worker_id}: Acquired lock. Performing exclusive task...")
time.sleep(2) # Simulate work
print(f"Worker {worker_id}: Released lock.")
if __name__ == "__main__":
print(f"Attempting to run protected_function for worker 1...")
protected_function(1)
print(f"Attempting to run protected_function for worker 2...")
protected_function(2)
# Example with context manager for more control
print("\n--- Using context manager ---")
my_lock = fasteners.InterProcessLock(lock_file_path + '.ctx')
with my_lock:
print("Main process: Acquired lock via context manager.")
time.sleep(1)
print("Main process: Released lock via context manager.")
# Clean up lock files (optional, as fasteners typically handles this on exit)
if os.path.exists(lock_file_path):
os.remove(lock_file_path)
if os.path.exists(lock_file_path + '.ctx'):
os.remove(lock_file_path + '.ctx')