from__future__importannotationsimportosimportsysfromcontextlibimportsuppressfromerrnoimportENOSYSfrompathlibimportPathfromtypingimportcastfrom._apiimportBaseFileLockfrom._utilimportensure_directory_exists#: a flag to indicate if the fcntl API is availablehas_fcntl=Falseifsys.platform=="win32":# pragma: win32 coverclassUnixFileLock(BaseFileLock):"""Uses the :func:`fcntl.flock` to hard lock the lock file on unix systems."""def_acquire(self)->None:raiseNotImplementedErrordef_release(self)->None:raiseNotImplementedErrorelse:# pragma: win32 no covertry:importfcntlexceptImportError:passelse:has_fcntl=True
[docs]classUnixFileLock(BaseFileLock):"""Uses the :func:`fcntl.flock` to hard lock the lock file on unix systems."""def_acquire(self)->None:ensure_directory_exists(self.lock_file)open_flags=os.O_RDWR|os.O_TRUNCifnotPath(self.lock_file).exists():open_flags|=os.O_CREATfd=os.open(self.lock_file,open_flags,self._context.mode)withsuppress(PermissionError):# This locked is not owned by this UIDos.fchmod(fd,self._context.mode)try:fcntl.flock(fd,fcntl.LOCK_EX|fcntl.LOCK_NB)exceptOSErrorasexception:os.close(fd)ifexception.errno==ENOSYS:# NotImplemented errormsg="FileSystem does not appear to support flock; use SoftFileLock instead"raiseNotImplementedError(msg)fromexceptionelse:self._context.lock_file_fd=fddef_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-conditionfd=cast(int,self._context.lock_file_fd)self._context.lock_file_fd=Nonefcntl.flock(fd,fcntl.LOCK_UN)os.close(fd)