FileLock Unix implementation for releasing the lock:
def _release(self) -> None:
# Do not remove the lockfile:
# https://github.com/tox-dev/py-filelock/issues/31
# https://stackoverflow.com/questions/17708885/flock-removing-locked-file-without-race-condition
fd = cast(int, self._context.lock_file_fd)
self._context.lock_file_fd = None
fcntl.flock(fd, fcntl.LOCK_UN)
os.close(fd)
FileLock Windows implementation for releasing the lock:
def _release(self) -> None:
fd = cast(int, self._context.lock_file_fd)
self._context.lock_file_fd = None
msvcrt.locking(fd, msvcrt.LK_UNLCK, 1)
os.close(fd)
with suppress(OSError): # Probably another instance of the application hat acquired the file lock.
Path(self.lock_file).unlink()
TLDR: the Windows version of _release() deletes the lock file, while the Unix version doesn't. So on Windows the additional call of Path(lock_path).unlink() after exiting FileLock context causes an exception because the file is not present anymore.
Good thing is unlink() accepts the argument missing_ok=True. This argument makes unlink(missing_ok=True) not to throw an exception if the file is not found, resolving the problem.
FileLock
Unix implementation for releasing the lock:FileLock
Windows implementation for releasing the lock:TLDR: the Windows version of
_release()
deletes the lock file, while the Unix version doesn't. So on Windows the additional call ofPath(lock_path).unlink()
after exitingFileLock
context causes an exception because the file is not present anymore.Good thing is
unlink()
accepts the argumentmissing_ok=True
. This argument makesunlink(missing_ok=True)
not to throw an exception if the file is not found, resolving the problem.