filelock

A platform-independent file lock for Python that supports the with-statement.

Library
PyPI
v4.2.4
981 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
87 /100 Excellent
Development Activity 100
Maintenance 96
Community 64
Maturity 60
Momentum 28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
85 /100 Excellent
Architecture 88
Code Quality 90
Innovation 80
Learning Curve 82

filelock provides a simple, dependable way to coordinate access to a shared resource across processes and threads using lock files. It ships multiple lock strategies — a strict OS-native lock backed by fcntl/msvcrt, a soft lock that relies on atomic file creation, and async variants for asyncio-based applications — all behind a consistent context-manager API.

The library is a foundational dependency in the Python packaging ecosystem (used by tox, pip, virtualenv, and many CI tools) precisely because it solves a narrow problem extremely well: preventing two processes from stepping on the same file or directory at the same time, on any platform, without requiring a database or external service.

What You Get

  • A FileLock class that picks the right backend automatically (fcntl on Unix, msvcrt on Windows, atomic-create soft lock as a fallback)
  • Context-manager and explicit acquire/release APIs with configurable timeouts and polling intervals
  • AsyncFileLock and related async primitives for use inside asyncio event loops without blocking the loop
  • Strict and soft lock variants, including a StrictSoftFileLock that layers ownership/staleness checks on top of the soft lock
  • Reentrant (recursive) lock acquisition within the same thread, with reference counting
  • Read-write lock support (ReadWriteLock) for shared vs exclusive access patterns

Common Use Cases

  • Preventing concurrent CI/test runners (e.g. tox, pytest-xdist workers) from corrupting a shared cache or virtualenv directory
  • Guarding a single-instance script or cron job so overlapping runs don’t clobber shared state
  • Coordinating writes to a shared config or data file across multiple processes on the same host
  • Serializing access to a downloaded/extracted dependency cache in packaging and build tools

Under The Hood

Architecture filelock separates concerns cleanly across _api.py (the shared BaseFileLock context-manager contract and acquire/release/timeout logic), platform-specific backends (_unix.py using fcntl, _windows.py using msvcrt, _soft.py using atomic O_CREAT|O_EXCL file creation), and a parallel async stack (asyncio.py, _async.py) that wraps the same backends behind coroutine-friendly acquire/release calls run off the event loop thread. A _strict.py module layers ownership/staleness detection (via _marker.py and _identity.py process-identity records) on top of the soft lock to detect and recover from crashed lock holders, and _read_write.py/_async_read_write.py add a separate reader-writer lock built on SQLite for cross-process shared/exclusive semantics.

Tech Stack Pure Python (99.9%) with zero runtime dependencies, targeting Python 3.10+ per pyproject.toml. Uses hatchling/hatch-vcs for the build backend and version derivation from git tags. Platform integration is via stdlib-only modules (fcntl, msvcrt, sqlite3) rather than third-party bindings, keeping the dependency footprint at zero.

Code Quality Extensive test suite (40+ files in tests/) covering async cancellation semantics, fork safety, strict/soft lock races, lock expiry, and platform-specific fallback behavior — well beyond typical coverage for a library this size. Code is fully typed, uses from __future__ import annotations, and is organized into small, single-responsibility modules with private (_-prefixed) internals and a curated public __all__ export list.

API Design The public API is deliberately minimal: a single FileLock (or AsyncFileLock) alias resolves to the right backend for the current platform, used identically via with lock: or await lock.acquire(). Advanced variants (SoftFileLock, StrictSoftFileLock, ReadWriteLock) follow the same constructor/acquire/release shape, so users can start with the simple case and opt into stronger guarantees without relearning the API. Documentation is hosted on Read the Docs with runnable examples for both sync and async usage.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers