filelock — filelock 3.3.1
This package contains a single module, which implements a platform independent file lock in Python, which provides a simple way of inter-process communication:
from filelock import Timeout, FileLock lock = FileLock("high_ground.txt.lock") with lock: open("high_ground.txt", "a").write("You were the chosen one.")
Don't use a FileLock to lock the file you want to write to, instead create a separate .lock file as shown above. [image: Example gif] [image]
Perhaps you are looking for something like:
- the pid 3rd party library,
- for Windows the msvcrt module in the standard library,
- for UNIX the fcntl module in the standard library.
filelock is available via PyPI, so you can pip install it:
python -m pip install filelock
A FileLock is used to indicate another process of your application that a resource or working directory is currently used. To do so, create a FileLock first:
from filelock import Timeout, FileLock file_path = "high_ground.txt" lock_path = "high_ground.txt.lock" lock = FileLock(lock_path, timeout=1)
The lock object supports multiple ways for acquiring the lock, including the ones used to acquire standard Python thread locks:
with lock: open(file_path, "a").write("Hello there!") lock.acquire() try: open(file_path, "a").write("General Kenobi!") finally: lock.release()
The acquire method accepts also a timeout parameter. If the lock cannot be acquired within timeout seconds, a Timeout exception is raised:
try: with lock.acquire(timeout=10): open(file_path, "a").write("I have a bad feeling about this.") except Timeout: print("Another instance of this application currently holds the lock.")
The lock objects are recursive locks, which means that once acquired, they will not block on successive lock requests:
def cite1(): with lock: open(file_path, "a").write("I hate it when he does that.") def cite2(): with lock: open(file_path, "a").write("You don't want to sell me death sticks.") # The lock is acquired here. with lock: cite1() cite2() # And released here.
All log messages by this library are made using the DEBUG_ level, under the filelock name. On how to control displaying/hiding that please consult the logging documentation of the standard library. E.g. to hide these messages you can use:
Filelock VS Softfilelock
The FileLock is platform dependent while the SoftFileLock is not. Use the FileLock if all instances of your application are running on the same host and a SoftFileLock otherwise.
The SoftFileLock only watches the existence of the lock file. This makes it ultra portable, but also more prone to dead locks if the application crashes. You can simply delete the lock file in such cases.
This library currently does not support asyncio. We'd recommend adding an asyncio variant though if someone can make a pull request for it, see here.
Contributions and Issues
Contributions are always welcome, please make sure they pass all tests before creating a pull request. This module is hosted on GitHub. If you have any questions or suggestions, don't hesitate to open a new issue 😊. There's no bad question, just a missed opportunity to learn more.
A platform independent file lock that supports the with-statement.
version of the project as a string
alias of filelock._unix.UnixFileLock
- class filelock.SoftFileLock(lock_file, timeout=- 1)
Simply watches the existence of the lock file.
- exception filelock.Timeout(lock_file)
Raised when the lock could not be acquired in timeout seconds.
The path of the file lock.
- class filelock.UnixFileLock(lock_file, timeout=- 1)
Uses the fcntl.flock() to hard lock the lock file on unix systems.
- class filelock.WindowsFileLock(lock_file, timeout=- 1)
Bases: filelock._api.BaseFileLock, abc.ABC
Uses the msvcrt.locking() function to hard lock the lock file on windows systems.
- class filelock.BaseFileLock(lock_file, timeout=- 1)
Abstract base class for a file lock object.
- property lock_file
- Return type
path to the lock file
- property timeout
- Return type
the default timeout value
New in version 2.0.0.
- property is_locked
- Return type
A boolean indicating if the lock file is holding the lock currently.
Changed in version 2.0.0: This was previously a method and is now a property.
- acquire(timeout=None, poll_intervall=0.05)
Try to acquire the file lock.
- timeout (typing.Optional[float, None]) -- maximum wait time for acquiring the lock, None means use the default timeout is and if timeout < 0, there is no timeout and this method will block until the lock could be acquired
- poll_intervall (float) -- interval of trying to acquire the lock file
Timeout -- if fails to acquire lock within the timeout period
- Return type
a context object that will unlock the file when the context is exited
# You can use this method in the context manager (recommended) with lock.acquire(): pass # Or use an equivalent try-finally construct: lock.acquire() try: pass finally: lock.release()
Changed in version 2.0.0: This method returns now a proxy object instead of self, so that it can be used in a with statement without side effects.
Releases the file lock. Please note, that the lock is only completely released, if the lock counter is 0. Also note, that the lock file itself is not automatically deleted.
force (bool) -- If true, the lock counter is ignored and the lock is released in every case/
- Return type
- class filelock.AcquireReturnProxy(lock)
A context aware object that will release the lock file when exiting.
py-filelock is public domain:
This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to <http://unlicense.org>
- Add changelog to the documentation PR #108 - by @gaborbernat
- Leave the log level of the filelock logger as not set (previously was set to warning) PR #108 - by @gaborbernat
- Drop python 2.7 and 3.5 support, add type hints PR #100 - by @gaborbernat
- Document asyncio support - by @gaborbernat
- fix typo PR #98 - by @jugmac00
- Improve documentation
- Changed logger name from filelock._api to filelock PR #97 - by @hkennyv
- Raise when trying to acquire in R/O or missing folder PR #96 - by @gaborbernat
- Move lock acquire/release log from INFO to DEBUG PR #95 - by @gaborbernat
- Fix spelling and remove ignored flake8 checks - by @gaborbernat
- Split main module PR #94 - by @gaborbernat
- Move test suite to pytest PR #93 - by @gaborbernat
- Update links for new home at tox-dev PR #88 - by @hugovk
- Fixed link to License file PR #63 - by @sharkwouter
- Adopt tox-dev organization best practices PR #87 - by @gaborbernat
- Ownership moved from @benediktschmitt to the tox-dev organization (new primary maintainer @gaborbernat)
- fixed setuptools and twine/warehouse error by making the license only 1 line long
- update version for pypi upload
- fixed python2 setup error
- added test.py module to MANIFEST and made tests available in the setup commands issue #48
- fixed documentation thanks to @AnkurTank issue #49
- Update Trove classifiers for PyPI
- test: Skip test_del on PyPy since it hangs
- Fix README rendering on PyPI
- PR #38 from cottsay/shebang
- updated docs config for older sphinx compatibility
- removed misleading shebang from module
- updated use setuptools
- fixed garbage collection (issue #37)
- fix travis ci badge (use rst not markdown)
- changed travis uri
- clean up
- Fixed unit test for Python 2.7
- Added Travis banner
- Added Travis CI support
- Corrected the prequel reference
- updated README
- updated readme
- updated README (added navigation)
- updated documentation issue #22
- fix the SoftFileLock test was influenced by the test for FileLock
- undo cb1d83d issue #31
- updated major version number due to issue #29 and issue #27
- fixed use proper Python3 reraise method
- Attempting to clean up lock file on Unix after release
- changed The logger is now acquired when first needed. issue #24
- correct spelling mistake
- added official support for python 2 issue #20
- updated readme
- updated readme issue #19
- added example PR #16
- updated readthedocs url
- updated change order of the examples (PR #16)
- Added logging
- Removed unused imports
- fixed issue #14 (moved license and readme file to MANIFEST)
- changed unlocking sequence to fix transient test failures
- changed threads in tests so exceptions surface
- added test lock file cleanup
- Don't remove file after releasing lock
- updated docs
- added the new classes to __all__
- added The SoftFileLock is now always tested
- The filelock classes are now always available and have been moved out of the if msvrct: ... elif fcntl ... else clauses.
- fixed issue #5
- updated test cases
- updated documentation
- fixed issue #2 which has been introduced with the lock counter
- added default timeout (fixes issue #2)
- added new test case, fixed unhandled exception
- fixed a timeout could still be thrown if the lock is already acquired
- fixed issue #1
- added lock counter, added unittest, updated to version 1
- changed filenames
- updated version for pypi
- updated README, License (changed format from md to rst)
- added MANIFEST to gitignore
- added os independent file lock ; changed setup.py for pypi
- Update README.md
- initial version