### Install filelock using pip Source: https://github.com/tox-dev/filelock/blob/main/docs/index.rst Installs the filelock library using pip. This command should be run in your terminal or command prompt. ```bash python -m pip install filelock ``` -------------------------------- ### Run all tox tests Source: https://github.com/tox-dev/filelock/blob/main/CONTRIBUTING.md Execute all defined tests using tox. Ensure tox is installed before running. ```shell tox run ``` -------------------------------- ### TOCTOU Vulnerability Example Source: https://github.com/tox-dev/filelock/blob/main/docs/concepts.rst Demonstrates a TOCTOU vulnerability where a race condition exists between checking for a file's existence and opening it for reading. ```python if os.path.exists("sensitive.txt"): # Check data = open("sensitive.txt").read() # Use (race window here!) ``` -------------------------------- ### Cooperative Locking Example Source: https://github.com/tox-dev/filelock/blob/main/docs/concepts.rst Highlights that locks require cooperation; if a process does not use the lock, it can still interfere with the locked process. ```python # Process A (uses lock) with lock: # Process B might still write at the same time # if Process B doesn't use the lock open("data.txt").write("A") ``` -------------------------------- ### Non-blocking acquire() with Timeout Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst When using 'blocking=False', the 'timeout' parameter is ignored as the lock attempts acquisition only once. This example demonstrates that 'blocking' takes precedence. ```python # This ignores the timeout and tries once with lock.acquire(blocking=False, timeout=10): pass ``` -------------------------------- ### Use FileLock (Recommended) Source: https://github.com/tox-dev/filelock/blob/main/docs/concepts.rst Use the platform-aware FileLock alias for automatic backend selection. This is the recommended choice for most use cases. ```python from filelock import FileLock lock = FileLock("work.lock") ``` -------------------------------- ### Correct FileLock Usage Source: https://github.com/tox-dev/filelock/blob/main/docs/concepts.rst Illustrates the correct way to use FileLock by creating a separate lock file for the resource being protected. ```python lock = FileLock("data.txt.lock") # ✓ Right with lock: data = open("data.txt").read() ``` -------------------------------- ### Basic File Locking with FileLock Source: https://github.com/tox-dev/filelock/blob/main/docs/index.rst Demonstrates how to use FileLock to acquire a lock and write to a file, ensuring exclusive access. The lock is automatically released when exiting the 'with' block. ```python from filelock import FileLock lock = FileLock("high_ground.txt.lock") with lock: with open("high_ground.txt", "a") as f: f.write("You were the chosen one.") ``` -------------------------------- ### Use Async Read/Write Locks Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Demonstrates how to use asynchronous read and write locks with filelock. This is useful for async Python code, especially when interacting with blocking I/O like SQLite. ```python from filelock import AsyncReadWriteLock rw = AsyncReadWriteLock("data.db") async with rw.read_lock(): data = await get_shared_data() async with rw.write_lock(): await update_shared_data() ``` ```python from concurrent.futures import ThreadPoolExecutor executor = ThreadPoolExecutor(max_workers=2) rw = AsyncReadWriteLock("data.db", executor=executor) ``` ```python await rw.acquire_read(timeout=5) try: data = await get_shared_data() finally: await rw.release() ``` -------------------------------- ### Create and Use a File Lock Source: https://github.com/tox-dev/filelock/blob/main/docs/tutorials.rst Demonstrates how to create a FileLock object and use it with a context manager to ensure exclusive access to a resource. The lock is automatically released when exiting the 'with' block. ```python from pathlib import Path from filelock import FileLock lock = FileLock("myapp.lock") with lock: # Inside this block, we hold the lock print("I have the lock!") ``` -------------------------------- ### Migrating from lockfile.PIDLockFile to filelock.SoftFileLock Source: https://github.com/tox-dev/filelock/blob/main/docs/tutorials.rst Demonstrates the equivalent usage of SoftFileLock in filelock compared to PIDLockFile from the lockfile library. SoftFileLock offers enhanced features like context manager support and automatic stale lock detection. ```python # Before (lockfile): from lockfile.pidlockfile import PIDLockFile lock = PIDLockFile("/tmp/myapp.lock") lock.acquire() print(lock.read_pid()) print(lock.is_lock_held_by_us()) lock.release() ``` ```python # After (filelock): from filelock import SoftFileLock lock = SoftFileLock("/tmp/myapp.lock") with lock: print(lock.pid) print(lock.is_lock_held_by_us) ``` -------------------------------- ### Use Async Soft Read/Write Locks Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Shows how to use asynchronous soft read/write locks, which wrap the synchronous SoftReadWriteLock for use in async environments, particularly for network file systems. ```python from filelock import AsyncSoftReadWriteLock rw = AsyncSoftReadWriteLock("/shared/nfs/data.lock") async with rw.read_lock(): data = await get_shared_data() ``` -------------------------------- ### Run other tox commands (e.g., linting) Source: https://github.com/tox-dev/filelock/blob/main/CONTRIBUTING.md Execute custom tox environments such as linting or formatting. The '-e' flag specifies the environment name. ```shell tox -e fix ``` -------------------------------- ### Manual File Lock Acquire and Release Source: https://github.com/tox-dev/filelock/blob/main/docs/tutorials.rst Shows how to manually acquire and release a FileLock using 'acquire()' and 'release()' methods. It emphasizes the importance of using a 'try/finally' block to ensure the lock is always released, even if errors occur. ```python lock.acquire() try: print("I have the lock") finally: lock.release() ``` -------------------------------- ### Correct File Lock Usage with Context Manager Source: https://github.com/tox-dev/filelock/blob/main/docs/tutorials.rst Highlights the recommended way to use FileLock by assigning it to a variable and using the 'with' statement. This ensures the lock is reliably managed and released. ```python lock = FileLock("my.lock") with lock: # ✓ Good # your code here pass ``` -------------------------------- ### Create and Use Singleton FileLock Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Use `is_singleton=True` to ensure multiple references to the same lock file point to the same lock instance. Acquiring and releasing locks through different references correctly manages the lock counter. ```python from filelock import FileLock # First reference creates the lock lock_a = FileLock("work.lock", is_singleton=True) # Second reference returns the same instance lock_b = FileLock("work.lock", is_singleton=True) assert lock_a is lock_b # Same object ``` ```python lock_a.acquire() lock_b.acquire() # Reentrant—lock counter is now 2 lock_b.release() # Lock counter is 1 lock_a.release() # Lock is fully released ``` ```python lock1 = FileLock("work.lock", is_singleton=True, timeout=10) lock2 = FileLock("work.lock", is_singleton=True, timeout=5) # ValueError! ``` -------------------------------- ### Demonstrating a Race Condition Source: https://github.com/tox-dev/filelock/blob/main/docs/concepts.rst Illustrates a race condition where two processes concurrently modifying a file lead to an incorrect final state. ```mermaid sequenceDiagram participant A as Process A participant File as Configuration File participant B as Process B A->>File: Read (value: 1) B->>File: Read (value: 1) Note over A: Increment to 2 Note over B: Increment to 2 A->>File: Write 2 B->>File: Write 2 Note over File: Final value: 2 (should be 3!) ``` -------------------------------- ### File Lock as a Decorator Source: https://github.com/tox-dev/filelock/blob/main/docs/tutorials.rst Demonstrates using FileLock as a decorator to automatically acquire and release a lock around a function's execution. This provides a concise way to protect function calls. ```python @lock def protected_operation(): print("This function runs with the lock held") protected_operation() # Lock is acquired, function runs, lock is released ``` -------------------------------- ### Inspect PID Lock Holder Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Demonstrates how to inspect the PID of the current lock holder using SoftFileLock. This is useful for migrating from older locking mechanisms. ```python from filelock import SoftFileLock lock = SoftFileLock("work.lock") with lock: print(lock.pid) # e.g. 12345 print(lock.pid) # None (lock file removed after release) ``` -------------------------------- ### Use Async Locks with async with Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst For asynchronous code, use AsyncFileLock with 'async with'. Ensure to await acquire() and release() operations as they are coroutines. ```python from pathlib import Path from filelock import AsyncFileLock lock = AsyncFileLock("work.lock") async def read_shared_file(): async with lock: data = Path("data.txt").read_text() return data ``` -------------------------------- ### Detect Stale Locks with SoftFileLock Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Illustrates how SoftFileLock automatically detects and cleans up stale locks when the holding process dies. This ensures lock integrity on all platforms. ```python from filelock import SoftFileLock lock = SoftFileLock("work.lock") with lock: # If the process holding the lock dies, # another process will automatically clean up the stale lock pass ``` -------------------------------- ### Handle Lock Timeouts with acquire() Timeout Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Alternatively, pass the 'timeout' parameter directly to the acquire() method for finer control over the waiting period. ```python lock = FileLock("work.lock") try: with lock.acquire(timeout=5): print("Got the lock!") except Timeout: print("Timeout after 5 seconds") ``` -------------------------------- ### Self-Deadlock Detection in FileLock Source: https://github.com/tox-dev/filelock/blob/main/docs/concepts.rst Demonstrates how filelock detects and prevents deadlocks when multiple FileLock instances for the same file are acquired within the same thread. Use `is_singleton=True` to resolve. ```python lock_a = FileLock("work.lock") lock_b = FileLock("work.lock") with lock_a: with lock_b: # RuntimeError: Deadlock detected! pass ``` -------------------------------- ### Preventing Race Conditions with File Locks Source: https://github.com/tox-dev/filelock/blob/main/docs/concepts.rst Shows how file locks ensure exclusive access to a resource, allowing processes to complete operations without interference and preserving data integrity. ```mermaid sequenceDiagram participant A as Process A participant Lock as File Lock participant File as Configuration File participant B as Process B A->>Lock: Acquire lock activate Lock B->>Lock: Try to acquire (waits...) A->>File: Read (value: 1) Note over A: Increment to 2 A->>File: Write 2 A->>Lock: Release lock deactivate Lock Lock->>B: Lock acquired! B->>File: Read (value: 2) Note over B: Increment to 3 B->>File: Write 3 B->>Lock: Release lock Note over File: Final value: 3 ✓ ``` -------------------------------- ### Incorrect FileLock Usage Source: https://github.com/tox-dev/filelock/blob/main/docs/concepts.rst Shows an incorrect pattern where the lock file is the same as the resource file, leading to unreliable locking. ```python lock = FileLock("data.txt") # ⚠️ Wrong! with lock: data = open("data.txt").read() ``` -------------------------------- ### Protect Shared Data with File Lock Source: https://github.com/tox-dev/filelock/blob/main/docs/tutorials.rst Shows how to use FileLock to protect shared data files from concurrent access by multiple processes. It ensures that only one process modifies the data file at a time, preventing race conditions. ```python from pathlib import Path from filelock import FileLock data_file = Path("data.txt") lock = FileLock("data.txt.lock") # Process A writes a greeting with lock: if not data_file.exists(): data_file.write_text("Hello from Process A\n") # Process B appends another greeting with lock: with data_file.open("a") as f: f.write("Hello from Process B\n") ``` -------------------------------- ### Handle Lock Timeouts with Timeout Parameter Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Use the 'timeout' parameter when acquiring a lock to specify the maximum time to wait. This prevents indefinite waiting if another process holds the lock. ```python from filelock import FileLock, Timeout lock = FileLock("work.lock", timeout=10) try: with lock: # This will wait up to 10 seconds for the lock print("Got the lock!") except Timeout: print("Couldn't get the lock after 10 seconds") ``` -------------------------------- ### Use ReadWriteLock for Concurrent Reads Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Employ `ReadWriteLock` for scenarios with many readers and infrequent writers to allow concurrent read access. The lock file must have a `.db` extension as it's backed by SQLite. ```python from filelock import ReadWriteLock rw = ReadWriteLock("data.db") # Multiple processes can read simultaneously with rw.read_lock(): data = get_shared_data() # Only one process can write at a time with rw.write_lock(): update_shared_data() ``` ```python with rw.read_lock(timeout=5): data = get_shared_data() with rw.write_lock(timeout=10, blocking=True): update_shared_data() ``` ```python rw.acquire_read(timeout=5) try: data = get_shared_data() finally: rw.release() rw.acquire_write(timeout=5) try: update_shared_data() finally: rw.release() ``` ```python with rw.read_lock(): with rw.read_lock(): # OK pass with rw.write_lock(): with rw.write_lock(): # OK pass ``` ```python with rw.read_lock(): with rw.write_lock(): # RuntimeError pass ``` ```python rw = ReadWriteLock("data.db") try: with rw.read_lock(): data = get_shared_data() finally: rw.close() # releases any held lock and closes the SQLite connection ``` -------------------------------- ### Use Non-Blocking Locks Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Set 'blocking=False' to attempt acquiring the lock exactly once. If the lock is immediately available, it's acquired; otherwise, a Timeout exception is raised. ```python from filelock import FileLock, Timeout lock = FileLock("work.lock", blocking=False) try: with lock: print("Got the lock immediately") except Timeout: print("Lock is held by another process") ``` -------------------------------- ### Handle Signals with Force-Release Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Ensure a lock is fully released when a termination signal is received. This uses `lock.release(force=True)` within a signal handler. ```python import signal lock = FileLock("work.lock") def cleanup(signum, frame): lock.release(force=True) raise SystemExit(1) signal.signal(signal.SIGTERM, cleanup) ``` -------------------------------- ### filelock.FileLock Class Source: https://github.com/tox-dev/filelock/blob/main/docs/api.rst The primary class for implementing file-based locks. ```APIDOC ## class filelock.FileLock ### Description A file lock object that provides a platform-independent way to lock files. It can be used as a context manager. ### Attributes - **lock_file** (str) - The path to the file used for locking. - **timeout** (float) - The maximum time in seconds to wait for the lock. ### Methods - **acquire(timeout=None, poll_intervall=0.05)** - Attempts to acquire the lock. - **release(force=False)** - Releases the lock. - **is_locked** (bool) - Returns True if the lock is currently held. ``` -------------------------------- ### Configuring SoftReadWriteLock for long-held locks on NFS Source: https://github.com/tox-dev/filelock/blob/main/docs/tutorials.rst Shows how to adjust the heartbeat interval and stale threshold for SoftReadWriteLock when locks are held for extended periods, such as in HPC environments. This prevents premature lock eviction due to long-running operations. ```python rw = SoftReadWriteLock( "/shared/nfs/work.lock", heartbeat_interval=120, stale_threshold=360, ) ``` -------------------------------- ### Using SoftReadWriteLock for NFS shared file access Source: https://github.com/tox-dev/filelock/blob/main/docs/tutorials.rst Illustrates how to use SoftReadWriteLock for managing concurrent read and write access to files on NFS. This lock type is designed for network file systems and handles cross-host stale lock detection. ```python from filelock import SoftReadWriteLock rw = SoftReadWriteLock("/shared/nfs/work.lock") with rw.read_lock(): # Any number of processes on any host can be here at the same time. data = open("/shared/nfs/data.json").read() with rw.write_lock(): # Exactly one process anywhere can be here. New readers wait behind a pending writer. open("/shared/nfs/data.json", "w").write(new_data) ``` -------------------------------- ### Check Local FileLock State Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Use the `is_locked` property to check if your current lock instance holds the lock and `lock_counter` for the reentrant depth. These properties only reflect the state of your instance. ```python from filelock import FileLock lock = FileLock("work.lock") if not lock.is_locked: with lock: print(f"Lock depth: {lock.lock_counter}") ``` -------------------------------- ### Inspect Reentrant Lock State Source: https://github.com/tox-dev/filelock/blob/main/docs/tutorials.rst Demonstrates how to check the locked status and acquisition count of a FileLock object. This is useful for understanding the current state of a reentrant lock. ```python lock = FileLock("reentrant.lock") print(lock.is_locked) # False print(lock.lock_counter) # 0 lock.acquire() print(lock.is_locked) # True print(lock.lock_counter) # 1 lock.acquire() print(lock.lock_counter) # 2 lock.release() print(lock.lock_counter) # 1 — still locked print(lock.is_locked) # True lock.release() print(lock.lock_counter) # 0 — fully released print(lock.is_locked) # False ``` -------------------------------- ### Force-Release a FileLock Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Immediately release a lock regardless of its reentrant counter by using `force=True`. This is useful for error recovery or cleanup handlers. ```python from filelock import FileLock lock = FileLock("work.lock") lock.acquire() lock.acquire() print(lock.lock_counter) # 2 lock.release(force=True) print(lock.is_locked) # False — fully released ``` -------------------------------- ### Run tox tests for a specific Python version Source: https://github.com/tox-dev/filelock/blob/main/CONTRIBUTING.md Execute tests for a specific Python interpreter version using tox. Replace 'py311' with the desired interpreter name. ```shell tox run -f py311 ``` -------------------------------- ### filelock.Timeout Exception Source: https://github.com/tox-dev/filelock/blob/main/docs/api.rst Exception raised when the lock cannot be acquired within the specified timeout period. ```APIDOC ## exception filelock.Timeout ### Description Raised when the file lock could not be acquired within the timeout period specified during the acquire call. ``` -------------------------------- ### Reentrant File Lock Acquisition Source: https://github.com/tox-dev/filelock/blob/main/docs/tutorials.rst Illustrates the reentrant nature of FileLock, where the same lock can be acquired multiple times within the same process or thread without causing a deadlock. The lock is only fully released when all acquisitions are matched by releases. ```python from filelock import FileLock lock = FileLock("reentrant.lock") def helper_function(): with lock: print("Helper has the lock") with lock: print("Main code has the lock") helper_function() # Can acquire the same lock again print("Still have the lock") ``` -------------------------------- ### Control Polling Interval with acquire() poll_interval Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Pass the 'poll_interval' directly to the acquire() method to set the interval for a specific acquisition attempt. ```python lock = FileLock("work.lock") with lock.acquire(poll_interval=1.0): # Checks every 1 second pass ``` -------------------------------- ### Async Locks with Specific Event Loop Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst You can specify a particular event loop to be used by the async lock, which is useful in scenarios with multiple event loops. ```python import asyncio loop = asyncio.new_event_loop() lock = AsyncFileLock("work.lock", loop=loop) ``` -------------------------------- ### Set FileLock Lifetime Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Create locks that automatically expire after a specified duration. This is useful for preventing deadlocks in distributed systems where a process might crash. ```python from filelock import FileLock # Lock expires after 3600 seconds (1 hour) lock = FileLock("work.lock", lifetime=3600) with lock: # Lock is held, but will auto-expire after 1 hour pass ``` -------------------------------- ### Control Polling Interval with poll_interval Parameter Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Set the 'poll_interval' parameter to increase the time between lock acquisition attempts. This can reduce CPU usage for long-lived locks. ```python lock = FileLock("work.lock", poll_interval=0.25) with lock: # Will check every 0.25 seconds instead of every 0.05 seconds pass ``` -------------------------------- ### Shared Lock Instance Across Threads Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst To have a single lock instance shared across all threads, where reentrant acquisitions are still possible per thread, set 'thread_local=False'. This ensures all threads interact with the same lock state. ```python # If you need one lock instance shared across threads (and reentrant per thread), set "thread_local=False": ``` -------------------------------- ### Check if Another Process Holds the Lock Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Attempt to acquire a lock with `blocking=False` to determine if another process currently holds it. This will raise a Timeout exception if the lock is held. ```python from filelock import FileLock, Timeout lock = FileLock("work.lock") try: with lock.acquire(blocking=False): print("Lock was free") except Timeout: print("Lock is held by another process") ``` -------------------------------- ### Async Locks Without Executor Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Async locks can be configured to run without an executor by setting 'run_in_executor=False'. This is suitable only if your filesystem operations are non-blocking. ```python # Or disable executor (only if your filesystem is non-blocking) lock = AsyncFileLock("work.lock", run_in_executor=False) ``` -------------------------------- ### Async Locks with Custom Executor Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Customize the thread pool executor used by async locks for running blocking I/O operations. This allows for managing concurrency. ```python # Use a custom executor from concurrent.futures import ThreadPoolExecutor executor = ThreadPoolExecutor(max_workers=2) lock = AsyncFileLock("work.lock", executor=executor) ``` -------------------------------- ### Check if Lock is Held by Current Process Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Shows how to check if the current process holds a SoftFileLock. This is useful for conditional logic within applications that manage locks. ```python lock = SoftFileLock("work.lock") print(lock.is_lock_held_by_us) # False with lock: print(lock.is_lock_held_by_us) # True ``` -------------------------------- ### Control FileLock Logging Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Configure Python's logging to control the verbosity of filelock debug messages. You can hide them by setting the logger level to INFO or show all messages by setting it to DEBUG. ```python import logging # Hide filelock debug messages logging.getLogger("filelock").setLevel(logging.INFO) # Or show all messages logging.getLogger("filelock").setLevel(logging.DEBUG) # Configure a handler to see them handler = logging.StreamHandler() logging.getLogger("filelock").addHandler(handler) ``` -------------------------------- ### Thread-Local Locks for Nested Acquisitions Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst By default, FileLock uses thread-local storage, allowing the same thread to acquire the same lock multiple times without blocking. This is useful for nested function calls within a thread. ```python from filelock import FileLock import threading lock = FileLock("work.lock") # thread_local=True by default def worker(): with lock: print(f"{threading.current_thread().name} has the lock") # Each thread can acquire the same lock without blocking threading.Thread(target=worker).start() worker() # Main thread ``` -------------------------------- ### Cancel Lock Acquisition with Timeout Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst Interrupt a waiting lock acquisition by providing a callable to `cancel_check`. The lock will raise a Timeout exception if the callable returns True between retries. ```python import threading from filelock import FileLock, Timeout shutdown = threading.Event() lock = FileLock("work.lock") try: with lock.acquire(timeout=-1, cancel_check=shutdown.is_set): print("Got the lock") except Timeout: print("Acquisition canceled") # From another thread: shutdown.set() # causes the acquire loop to stop ``` -------------------------------- ### Change Poll Interval Dynamically Source: https://github.com/tox-dev/filelock/blob/main/docs/how-to.rst The poll interval can be modified at any time by setting the 'poll_interval' property on the lock object. ```python lock.poll_interval = 0.5 ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.