Search code examples
pythonexceptionlockingfcntl

File locking in Python with fcntl


I am trying to define functions to ease the locking of files with the fcntl module. When I manually run

fcntl.lockf(lock_file, fcntl.LOCK_EX | fcntl.LOCK_NB)

in two separate instances of Python, I get the expected exception

BlockingIOError: [Errno 11] Resource temporarily unavailable

but when I define functions to automate this in mylock.py:

import fcntl

def lock(filepath):
    lock_file = open(filepath, "a")
    try:
        fcntl.lockf(lock_file, fcntl.LOCK_EX | fcntl.LOCK_NB)
    except OSError or BlockingIOError:
        return False
    return True

def unlock(filepath):
    lock_file = open(filepath, "a")
    try:
        fcntl.lockf(lock_file, fcntl.LOCK_UN)
    except OSError or BlockingIOError:
        return False
    return True

and then import this into two separate python instances and do

mylock.lock("test.txt")

which unexpectedly returns True in both instances. Is my error handling inappropriate? I have also tried except IOError:, except Exception: and except: -- I don't understand why the BlockingIOError raised when I run the fcntl commands in isolation doesn't cause the except logic to be executed.


Solution

  • So, the problem seems to have been that the file was being garbage collected, since the handle lock_file was not being used after the function. If the return statement is modified to return lock_file then the desired behaviour is achieved.