Registry / database / flufl-lock

flufl-lock

JSON →
library9.1.0pypypi✓ verified 26d ago

The flufl.lock library provides an NFS-safe, file-based locking algorithm for POSIX and Windows systems, heavily influenced by the GNU/Linux open(2) manpage's O_EXCL option. It aims to prevent race conditions on NFS file systems by using atomic file operations with robust timeouts and lock-breaking capabilities. Currently at version 9.0.0, the library is under active development with regular updates and maintenance releases.

pip install flufl.lock
INSTALL
IMPORT
SIG · FLUFL-LOCK
F
flufl-lock
databasepythonv9.1.0
Install
1.8s avg
Import
92ms
Disk
17MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v9.1.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.096s · 18.7MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.8s · import 0.088s · 19MB
17MB installed
● package 17MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Lock
from flufl.lock import Lock
AlreadyLockedError
from flufl.lock import AlreadyLockedError
NotLockedError
from flufl.lock import NotLockedError

This quickstart demonstrates basic lock acquisition and release using both context managers and explicit `lock()`/`unlock()` calls. It also shows how to handle `AlreadyLockedError` and refresh a lock. A temporary file is used for demonstration purposes; in production, you would use a stable, shared file path.

import tempfile import os from flufl.lock import Lock, AlreadyLockedError # Create a temporary file to use as the lock file # In a real application, use a persistent path accessible to all processes with tempfile.NamedTemporaryFile(delete=False) as tmp_lock_file: lock_file_path = tmp_lock_file.name try: # Acquire the lock using a context manager for automatic release # default lifetime is 15 seconds with Lock(lock_file_path) as lock: print(f"Lock acquired on {lock_file_path}") print(f"Is locked: {lock.is_locked}") print("Performing some locked operation...") # Simulate another process trying to acquire the same lock try: with Lock(lock_file_path, default_timeout=1) as other_lock: print("This should not be reached if the lock is held.") except AlreadyLockedError: print("Another process correctly detected the lock is held.") # The lock is automatically released when exiting the 'with' block print("Lock released.") # Acquire and release manually lock = Lock(lock_file_path) lock.lock() print("Lock acquired manually.") lock.refresh() print("Lock refreshed (lifetime extended).") lock.unlock() print("Lock released manually.") finally: # Clean up the temporary lock file if os.path.exists(lock_file_path): os.remove(lock_file_path) # The library might create a claim file; ensure it's also cleaned. # For this simple example, we assume lock_file_path is sufficient.
Debug
Known issues
gotchaChoosing an appropriate 'lifetime' for a lock is crucial. If too long, stale locks (from crashed processes) will block others excessively. If too short, other processes might prematurely break an active lock, leading to data corruption.
fix
Carefully consider the maximum expected duration of your critical section and set the `lifetime` parameter accordingly. Use `lock.refresh()` to extend the lock's lifetime if operations take longer than anticipated.
affects: All versions
gotchaFor distributed (NFS) environments, proper clock synchronization between participating machines is essential. Inaccurate clocks can lead to incorrect lock expiration calculations, causing stale locks to persist or active locks to be prematurely broken.
fix
Ensure all systems accessing the shared lock file have their clocks synchronized, e.g., using NTP.
affects: All versions
breakingVersion 9.0.0 removed support for Python 3.9. Previous major versions also dropped support for older Python versions (e.g., 8.0 dropped 3.7).
fix
Upgrade your Python environment to 3.10 or newer (for flufl.lock 9.x) if you need to use the latest version of the library. Check the changelog for specific version requirements if targeting older flufl.lock releases.
affects: 9.0.0+
gotchaSome applications (e.g., DVC) have reported `pkg_resources.DistributionNotFound` errors when using `flufl.lock` version 8.0 or newer due to potential changes in how its metadata is packaged or resolved by downstream tools.
fix
If encountering `DistributionNotFound` issues, particularly with tools that rely on older setuptools mechanisms, consider pinning `flufl.lock < 8.0` or checking the downstream application's compatibility matrix.
affects: 8.0+
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'flufl.lock'
The Python interpreter cannot find the 'flufl.lock' package, typically because it was not installed, or the environment where the code is run does not have access to the installed package.
fix
Install the package using pip: `pip install flufl-lock`
flufl.lock.TimeOutError
The lock acquisition attempt failed because the specified timeout interval expired before the lock could be obtained.
fix
Increase the timeout duration when instantiating the Lock object or when calling the `lock()` method, or ensure the lock file is not perpetually held by another process or stale: `lock = Lock('mylockfile.lock', default_timeout=timedelta(minutes=5))` or `lock.lock(timeout=timedelta(seconds=60))`
flufl.lock.AlreadyLockedError
An attempt was made to acquire a lock by a process that already holds that specific lock.
fix
Ensure the lock is only acquired once per process or use a `try...except AlreadyLockedError` block if re-acquisition attempts are part of the logic, though typically, a check like `if not lock.is_locked: lock.lock()` is preferred.
flufl.lock.NotLockedError
This error occurs when trying to release or refresh a lock that the current process does not hold, either because it was never acquired, it was already released, or another process broke it.
fix
Verify that the lock is currently held by the process using `lock.is_locked` before attempting to unlock or refresh it, or ensure `unlock()` is called only when the lock is active: `if lock.is_locked: lock.unlock()`
pkg_resources.DistributionNotFound: The 'flufl.lock>=X.X' distribution was not found
This issue typically arises due to incompatibilities with how `pkg_resources` (a component of `setuptools`) resolves package metadata, especially with newer packaging standards (like PDM) used by `flufl.lock` versions, leading to a failure to correctly identify the installed `flufl.lock` version.
fix
Upgrade `setuptools` and related packaging tools (`pip install --upgrade setuptools pip`) and consider using `importlib_resources` for metadata if still encountering issues, or downgrade `flufl.lock` to a version known to be compatible with your existing dependency resolver if possible. The root cause is often outdated packaging tools or a clash in how different tools interpret package metadata.
Upgrade
Version history
9.1.0latest on PyPI · released Apr 27, 2026
Audit
Dependencies

No dependency data recorded yet.

Agent activity
14 hits · last 30 days
node
12
Resources
flufl-lock — pip install flufl-lock · libregistry