The `lockfile` package (version 0.12.2) provides a platform-independent API for locking files across Unix and Windows, relying on atomic system calls like `link` (Unix) and `mkdir` (Windows). This package is **deprecated**, with its last release in November 2015. Users are strongly advised to use alternatives like `fasteners` or `oslo.concurrency` for file locking needs.
Install & Compatibility
Where this runs
tested against v0.12.2 · 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
muslpy 3.10–3.925 runs
installs and imports cleanly · install 0.0s · import 0.012s · 17.9MB
glibcpy 3.10–3.925 runs
installs and imports cleanly · install 1.5s · import 0.010s · 18MB
16MB installed
● package 16MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
LockFile
✓ from lockfile import LockFile
✗ import lockfile
While 'import lockfile' works, accessing LockFile directly from the top-level package is the common pattern.
LinkFileLock
✓ from lockfile.linklockfile import LinkFileLock
✗ from lockfile import LinkFileLock
As of version 0.9, classes like LinkFileLock were moved into submodules, though the old top-level import was retained for backward compatibility until 1.0.
MkdirFileLock
✓ from lockfile.mkdirlockfile import MkdirFileLock
✗ from lockfile import MkdirFileLock
Similar to LinkFileLock, MkdirFileLock was moved to a submodule in version 0.9.
This quickstart demonstrates how to acquire and release a file lock using `LockFile`. It includes a timeout mechanism and proper error handling for when the lock cannot be acquired or is already held. The `os.environ.get` is used for the lock file path for potential external configuration.
from lockfile import LockFile
import os
lock_path = os.environ.get('LOCK_FILE_PATH', 'my_app.lock')
lock = LockFile(lock_path)
try:
print(f"Attempting to acquire lock for {lock.path}...")
lock.acquire(timeout=10) # Wait up to 10 seconds
print(f"Lock acquired for {lock.path}. Performing critical operation...")
# Simulate work
with open('shared_resource.txt', 'a') as f:
f.write('Critical operation performed.\n')
print("Critical operation complete.")
except lock.AlreadyLocked: # Using lock.AlreadyLocked for consistency across versions
print(f"Could not acquire lock for {lock.path}: Already locked by another process.")
except Exception as e:
print(f"An error occurred: {e}")
finally:
if lock.is_locked():
lock.release()
print(f"Lock released for {lock.path}.")
else:
print(f"Lock was not acquired, so no release needed for {lock.path}.")
Debug
Known issues
breakingThe API underwent significant changes in version 0.9. Classes like `LinkFileLock`, `MkdirFileLock`, and `SQLiteFileLock` were moved from the top-level `lockfile` module into their own submodules (e.g., `lockfile.linklockfile.LinkFileLock`). The class naming convention also reversed, changing from `SomethingFileLock` to `SomethingLockFile`.fixUpdate import paths and class names to reflect the new structure (e.g., `from lockfile.linklockfile import LinkLockFile`). For backward compatibility, the old module-level definitions were retained until the 1.0 release, but direct submodule imports are recommended.
affects: 0.9.x to 0.12.2
deprecatedThis `lockfile` package is officially deprecated and has not been updated since November 2015. It is highly recommended to migrate to actively maintained alternatives.fixMigrate to modern, actively maintained file locking libraries such as `fasteners` or `oslo.concurrency`.
affects: All versions, especially 0.12.2 and earlier
gotchaThe `LockFile` implementation relies on the atomic nature of `link()` on Unix and `mkdir()` on Windows. While providing cross-platform compatibility, this mechanism might not be suitable for all network file systems (e.g., NFS), where atomic guarantees can be an issue.fixFor applications requiring robust locking over network file systems, consider alternatives explicitly designed for such environments or more advanced coordination primitives. For instance, `flufl.lock` is noted as NFS-safe for POSIX systems.
affects: All versions
gotchaCalling `release()` on an already unlocked `LockFile` instance will raise a `LockError`. This can occur if the lock is released prematurely or if there's a logic error in handling lock states, particularly in complex multi-process scenarios or when mixing explicit `acquire`/`release` with context managers.fixEnsure `release()` is only called when the lock is known to be held. Using the `with` statement for `LockFile` instances is the safest approach, as it automatically handles acquisition and release, reducing the chance of `LockError` from manual management. If manual control is necessary, check `lock.is_locked()` before calling `release()`.
affects: All versions
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'lockfile'
The 'lockfile' package is not installed in the current Python environment.
fixRun `pip install lockfile` or `pip3 install lockfile`. Note that the `lockfile` package is deprecated; consider using alternatives like `fasteners` or `oslo.concurrency` for new projects.
ImportError: No module named lockfile.pidlockfile
This error typically occurs when another package, such as `python-daemon`, expects a specific sub-module (`pidlockfile`) from `lockfile` that is either not installed, or there is an incompatibility with the versions of the dependent package and `lockfile`.
fixEnsure `lockfile` is installed via `pip install lockfile`. If the error persists, try reinstalling the dependent package (e.g., `python-daemon`) or check its compatibility requirements. It is highly recommended to migrate to actively maintained libraries like `fasteners` or `oslo.concurrency`.
lockfile.LockTimeout: Lock held by another process
The `acquire()` method was called with a specified timeout, but the lock could not be obtained within that duration because another process or thread was holding the lock.
fixYou can either increase the `timeout` value when calling `acquire()`, implement a retry mechanism, or cautiously use `lock.break_lock()` if you are certain the existing lock is stale. For robust solutions, consider migrating to `fasteners` or `oslo.concurrency`.
lockfile.AlreadyLocked: File is already locked
This exception is raised when `lockfile.acquire()` is called in a non-blocking mode (e.g., with `timeout=0` or a negative value), and the file is already locked by another process or thread.
fixHandle the `AlreadyLocked` exception in your code, or call `acquire()` without a timeout for a blocking operation, or provide a positive timeout value. It is advisable to use modern, maintained alternatives like `fasteners` or `oslo.concurrency`.
IO error: Could not lock file
A low-level operating system error occurred (e.g., 'Resource temporarily unavailable', errno 11) preventing `lockfile` from creating or acquiring the lock. This often indicates another process holds a conflicting lock, or there are insufficient file system permissions.
fixCheck for other processes that might be holding a lock on the target file or directory and terminate them if necessary. Verify that the Python process has appropriate read/write permissions for the directory where the lock file is created. For better reliability and features, consider switching to `fasteners` or `oslo.concurrency`.
Audit
Dependencies
No dependency data recorded yet.