re-format with black
This commit is contained in:
+50
-20
@@ -65,10 +65,21 @@ if not hasattr(threading, "current_thread"):
|
||||
if not hasattr(threading.Thread, "get_name"):
|
||||
threading.Thread.get_name = threading.Thread.getName
|
||||
|
||||
__all__ = ['Error', 'LockError', 'LockTimeout', 'AlreadyLocked',
|
||||
'LockFailed', 'UnlockError', 'NotLocked', 'NotMyLock',
|
||||
'LinkFileLock', 'MkdirFileLock', 'SQLiteFileLock',
|
||||
'LockBase', 'locked']
|
||||
__all__ = [
|
||||
"Error",
|
||||
"LockError",
|
||||
"LockTimeout",
|
||||
"AlreadyLocked",
|
||||
"LockFailed",
|
||||
"UnlockError",
|
||||
"NotLocked",
|
||||
"NotMyLock",
|
||||
"LinkFileLock",
|
||||
"MkdirFileLock",
|
||||
"SQLiteFileLock",
|
||||
"LockBase",
|
||||
"locked",
|
||||
]
|
||||
|
||||
|
||||
class Error(Exception):
|
||||
@@ -80,6 +91,7 @@ class Error(Exception):
|
||||
... except Exception:
|
||||
... pass
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -92,6 +104,7 @@ class LockError(Error):
|
||||
... except Error:
|
||||
... pass
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -103,6 +116,7 @@ class LockTimeout(LockError):
|
||||
... except LockError:
|
||||
... pass
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -114,6 +128,7 @@ class AlreadyLocked(LockError):
|
||||
... except LockError:
|
||||
... pass
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -125,6 +140,7 @@ class LockFailed(LockError):
|
||||
... except LockError:
|
||||
... pass
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -137,6 +153,7 @@ class UnlockError(Error):
|
||||
... except Error:
|
||||
... pass
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -148,6 +165,7 @@ class NotLocked(UnlockError):
|
||||
... except UnlockError:
|
||||
... pass
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -159,6 +177,7 @@ class NotMyLock(UnlockError):
|
||||
... except UnlockError:
|
||||
... pass
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@@ -209,6 +228,7 @@ class _SharedBase(object):
|
||||
|
||||
class LockBase(_SharedBase):
|
||||
"""Base class for platform-specific lock classes."""
|
||||
|
||||
def __init__(self, path, threaded=True, timeout=None):
|
||||
"""
|
||||
>>> lock = LockBase('somefile')
|
||||
@@ -223,7 +243,7 @@ class LockBase(_SharedBase):
|
||||
# Thread objects in Python 2.4 and earlier do not have ident
|
||||
# attrs. Worm around that.
|
||||
ident = getattr(t, "ident", hash(t))
|
||||
self.tname = "-%x" % (ident & 0xffffffff)
|
||||
self.tname = "-%x" % (ident & 0xFFFFFFFF)
|
||||
else:
|
||||
self.tname = ""
|
||||
dirname = os.path.dirname(self.lock_file)
|
||||
@@ -235,11 +255,10 @@ class LockBase(_SharedBase):
|
||||
# and overwriting the already existing lock-file, then one
|
||||
# gets unlocked, deleting both lock-file and unique file,
|
||||
# finally the last lock errors out upon releasing.
|
||||
self.unique_name = os.path.join(dirname,
|
||||
"%s%s.%s%s" % (self.hostname,
|
||||
self.tname,
|
||||
self.pid,
|
||||
hash(self.path)))
|
||||
self.unique_name = os.path.join(
|
||||
dirname,
|
||||
"%s%s.%s%s" % (self.hostname, self.tname, self.pid, hash(self.path)),
|
||||
)
|
||||
self.timeout = timeout
|
||||
|
||||
def is_locked(self):
|
||||
@@ -261,13 +280,15 @@ class LockBase(_SharedBase):
|
||||
raise NotImplemented("implement in subclass")
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s: %r -- %r>" % (self.__class__.__name__, self.unique_name,
|
||||
self.path)
|
||||
return "<%s: %r -- %r>" % (self.__class__.__name__, self.unique_name, self.path)
|
||||
|
||||
|
||||
def _fl_helper(cls, mod, *args, **kwds):
|
||||
warnings.warn("Import from %s module instead of lockfile package" % mod,
|
||||
DeprecationWarning, stacklevel=2)
|
||||
warnings.warn(
|
||||
"Import from %s module instead of lockfile package" % mod,
|
||||
DeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
# This is a bit funky, but it's only for awhile. The way the unit tests
|
||||
# are constructed this function winds up as an unbound method, so it
|
||||
# actually takes three args, not two. We want to toss out self.
|
||||
@@ -286,8 +307,8 @@ def LinkFileLock(*args, **kwds):
|
||||
lockfile.linklockfile module.
|
||||
"""
|
||||
from . import linklockfile
|
||||
return _fl_helper(linklockfile.LinkLockFile, "lockfile.linklockfile",
|
||||
*args, **kwds)
|
||||
|
||||
return _fl_helper(linklockfile.LinkLockFile, "lockfile.linklockfile", *args, **kwds)
|
||||
|
||||
|
||||
def MkdirFileLock(*args, **kwds):
|
||||
@@ -297,8 +318,10 @@ def MkdirFileLock(*args, **kwds):
|
||||
lockfile.mkdirlockfile module.
|
||||
"""
|
||||
from . import mkdirlockfile
|
||||
return _fl_helper(mkdirlockfile.MkdirLockFile, "lockfile.mkdirlockfile",
|
||||
*args, **kwds)
|
||||
|
||||
return _fl_helper(
|
||||
mkdirlockfile.MkdirLockFile, "lockfile.mkdirlockfile", *args, **kwds
|
||||
)
|
||||
|
||||
|
||||
def SQLiteFileLock(*args, **kwds):
|
||||
@@ -308,8 +331,10 @@ def SQLiteFileLock(*args, **kwds):
|
||||
lockfile.mkdirlockfile module.
|
||||
"""
|
||||
from . import sqlitelockfile
|
||||
return _fl_helper(sqlitelockfile.SQLiteLockFile, "lockfile.sqlitelockfile",
|
||||
*args, **kwds)
|
||||
|
||||
return _fl_helper(
|
||||
sqlitelockfile.SQLiteLockFile, "lockfile.sqlitelockfile", *args, **kwds
|
||||
)
|
||||
|
||||
|
||||
def locked(path, timeout=None):
|
||||
@@ -324,6 +349,7 @@ def locked(path, timeout=None):
|
||||
def myname(...):
|
||||
...
|
||||
"""
|
||||
|
||||
def decor(func):
|
||||
@functools.wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
@@ -333,15 +359,19 @@ def locked(path, timeout=None):
|
||||
return func(*args, **kwargs)
|
||||
finally:
|
||||
lock.release()
|
||||
|
||||
return wrapper
|
||||
|
||||
return decor
|
||||
|
||||
|
||||
if hasattr(os, "link"):
|
||||
from . import linklockfile as _llf
|
||||
|
||||
LockFile = _llf.LinkLockFile
|
||||
else:
|
||||
from . import mkdirlockfile as _mlf
|
||||
|
||||
LockFile = _mlf.MkdirLockFile
|
||||
|
||||
FileLock = LockFile
|
||||
|
||||
+10
-10
@@ -3,8 +3,7 @@ from __future__ import absolute_import
|
||||
import time
|
||||
import os
|
||||
|
||||
from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout,
|
||||
AlreadyLocked)
|
||||
from . import LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout, AlreadyLocked
|
||||
|
||||
|
||||
class LinkLockFile(LockBase):
|
||||
@@ -41,12 +40,11 @@ class LinkLockFile(LockBase):
|
||||
if timeout is not None and time.time() > end_time:
|
||||
os.unlink(self.unique_name)
|
||||
if timeout > 0:
|
||||
raise LockTimeout("Timeout waiting to acquire"
|
||||
" lock for %s" %
|
||||
self.path)
|
||||
raise LockTimeout(
|
||||
"Timeout waiting to acquire" " lock for %s" % self.path
|
||||
)
|
||||
else:
|
||||
raise AlreadyLocked("%s is already locked" %
|
||||
self.path)
|
||||
raise AlreadyLocked("%s is already locked" % self.path)
|
||||
time.sleep(timeout is not None and timeout / 10 or 0.1)
|
||||
else:
|
||||
# Link creation succeeded. We're good to go.
|
||||
@@ -64,9 +62,11 @@ class LinkLockFile(LockBase):
|
||||
return os.path.exists(self.lock_file)
|
||||
|
||||
def i_am_locking(self):
|
||||
return (self.is_locked() and
|
||||
os.path.exists(self.unique_name) and
|
||||
os.stat(self.unique_name).st_nlink == 2)
|
||||
return (
|
||||
self.is_locked()
|
||||
and os.path.exists(self.unique_name)
|
||||
and os.stat(self.unique_name).st_nlink == 2
|
||||
)
|
||||
|
||||
def break_lock(self):
|
||||
if os.path.exists(self.lock_file):
|
||||
|
||||
+10
-13
@@ -5,12 +5,12 @@ import os
|
||||
import sys
|
||||
import errno
|
||||
|
||||
from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout,
|
||||
AlreadyLocked)
|
||||
from . import LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout, AlreadyLocked
|
||||
|
||||
|
||||
class MkdirLockFile(LockBase):
|
||||
"""Lock file by creating a directory."""
|
||||
|
||||
def __init__(self, path, threaded=True, timeout=None):
|
||||
"""
|
||||
>>> lock = MkdirLockFile('somefile')
|
||||
@@ -19,10 +19,9 @@ class MkdirLockFile(LockBase):
|
||||
LockBase.__init__(self, path, threaded, timeout)
|
||||
# Lock file itself is a directory. Place the unique file name into
|
||||
# it.
|
||||
self.unique_name = os.path.join(self.lock_file,
|
||||
"%s.%s%s" % (self.hostname,
|
||||
self.tname,
|
||||
self.pid))
|
||||
self.unique_name = os.path.join(
|
||||
self.lock_file, "%s.%s%s" % (self.hostname, self.tname, self.pid)
|
||||
)
|
||||
|
||||
def acquire(self, timeout=None):
|
||||
timeout = timeout if timeout is not None else self.timeout
|
||||
@@ -47,13 +46,12 @@ class MkdirLockFile(LockBase):
|
||||
return
|
||||
if timeout is not None and time.time() > end_time:
|
||||
if timeout > 0:
|
||||
raise LockTimeout("Timeout waiting to acquire"
|
||||
" lock for %s" %
|
||||
self.path)
|
||||
raise LockTimeout(
|
||||
"Timeout waiting to acquire" " lock for %s" % self.path
|
||||
)
|
||||
else:
|
||||
# Someone else has the lock.
|
||||
raise AlreadyLocked("%s is already locked" %
|
||||
self.path)
|
||||
raise AlreadyLocked("%s is already locked" % self.path)
|
||||
time.sleep(wait)
|
||||
else:
|
||||
# Couldn't create the lock for some other reason
|
||||
@@ -74,8 +72,7 @@ class MkdirLockFile(LockBase):
|
||||
return os.path.exists(self.lock_file)
|
||||
|
||||
def i_am_locking(self):
|
||||
return (self.is_locked() and
|
||||
os.path.exists(self.unique_name))
|
||||
return self.is_locked() and os.path.exists(self.unique_name)
|
||||
|
||||
def break_lock(self):
|
||||
if os.path.exists(self.lock_file):
|
||||
|
||||
+9
-11
@@ -18,10 +18,9 @@ import errno
|
||||
import os
|
||||
import time
|
||||
|
||||
from . import (LockBase, AlreadyLocked, LockFailed, NotLocked, NotMyLock,
|
||||
LockTimeout)
|
||||
from . import LockBase, AlreadyLocked, LockFailed, NotLocked, NotMyLock, LockTimeout
|
||||
|
||||
|
||||
|
||||
class PIDLockFile(LockBase):
|
||||
""" Lockfile implemented as a Unix PID file.
|
||||
|
||||
@@ -80,12 +79,11 @@ class PIDLockFile(LockBase):
|
||||
# The lock creation failed. Maybe sleep a bit.
|
||||
if time.time() > end_time:
|
||||
if timeout is not None and timeout > 0:
|
||||
raise LockTimeout("Timeout waiting to acquire"
|
||||
" lock for %s" %
|
||||
self.path)
|
||||
raise LockTimeout(
|
||||
"Timeout waiting to acquire" " lock for %s" % self.path
|
||||
)
|
||||
else:
|
||||
raise AlreadyLocked("%s is already locked" %
|
||||
self.path)
|
||||
raise AlreadyLocked("%s is already locked" % self.path)
|
||||
time.sleep(timeout is not None and timeout / 10 or 0.1)
|
||||
else:
|
||||
raise LockFailed("failed to create %s" % self.path)
|
||||
@@ -125,7 +123,7 @@ def read_pid_from_pidfile(pidfile_path):
|
||||
"""
|
||||
pid = None
|
||||
try:
|
||||
pidfile = open(pidfile_path, 'r')
|
||||
pidfile = open(pidfile_path, "r")
|
||||
except IOError:
|
||||
pass
|
||||
else:
|
||||
@@ -156,10 +154,10 @@ def write_pid_to_pidfile(pidfile_path):
|
||||
and write it to the named file as a line of text.
|
||||
|
||||
"""
|
||||
open_flags = (os.O_CREAT | os.O_EXCL | os.O_WRONLY)
|
||||
open_flags = os.O_CREAT | os.O_EXCL | os.O_WRONLY
|
||||
open_mode = 0o644
|
||||
pidfile_fd = os.open(pidfile_path, open_flags, open_mode)
|
||||
pidfile = os.fdopen(pidfile_fd, 'w')
|
||||
pidfile = os.fdopen(pidfile_fd, "w")
|
||||
|
||||
# According to the FHS 2.3 section on PID files in /var/run:
|
||||
#
|
||||
|
||||
+46
-40
@@ -27,6 +27,7 @@ class SQLiteLockFile(LockBase):
|
||||
|
||||
if SQLiteLockFile.testdb is None:
|
||||
import tempfile
|
||||
|
||||
_fd, testdb = tempfile.mkstemp()
|
||||
os.close(_fd)
|
||||
os.unlink(testdb)
|
||||
@@ -34,20 +35,24 @@ class SQLiteLockFile(LockBase):
|
||||
SQLiteLockFile.testdb = testdb
|
||||
|
||||
import sqlite3
|
||||
|
||||
self.connection = sqlite3.connect(SQLiteLockFile.testdb)
|
||||
|
||||
c = self.connection.cursor()
|
||||
try:
|
||||
c.execute("create table locks"
|
||||
"("
|
||||
" lock_file varchar(32),"
|
||||
" unique_name varchar(32)"
|
||||
")")
|
||||
c.execute(
|
||||
"create table locks"
|
||||
"("
|
||||
" lock_file varchar(32),"
|
||||
" unique_name varchar(32)"
|
||||
")"
|
||||
)
|
||||
except sqlite3.OperationalError:
|
||||
pass
|
||||
else:
|
||||
self.connection.commit()
|
||||
import atexit
|
||||
|
||||
atexit.register(os.unlink, SQLiteLockFile.testdb)
|
||||
|
||||
def acquire(self, timeout=None):
|
||||
@@ -68,32 +73,35 @@ class SQLiteLockFile(LockBase):
|
||||
while True:
|
||||
if not self.is_locked():
|
||||
# Not locked. Try to lock it.
|
||||
cursor.execute("insert into locks"
|
||||
" (lock_file, unique_name)"
|
||||
" values"
|
||||
" (?, ?)",
|
||||
(self.lock_file, self.unique_name))
|
||||
cursor.execute(
|
||||
"insert into locks"
|
||||
" (lock_file, unique_name)"
|
||||
" values"
|
||||
" (?, ?)",
|
||||
(self.lock_file, self.unique_name),
|
||||
)
|
||||
self.connection.commit()
|
||||
|
||||
# Check to see if we are the only lock holder.
|
||||
cursor.execute("select * from locks"
|
||||
" where unique_name = ?",
|
||||
(self.unique_name,))
|
||||
cursor.execute(
|
||||
"select * from locks" " where unique_name = ?", (self.unique_name,)
|
||||
)
|
||||
rows = cursor.fetchall()
|
||||
if len(rows) > 1:
|
||||
# Nope. Someone else got there. Remove our lock.
|
||||
cursor.execute("delete from locks"
|
||||
" where unique_name = ?",
|
||||
(self.unique_name,))
|
||||
cursor.execute(
|
||||
"delete from locks" " where unique_name = ?",
|
||||
(self.unique_name,),
|
||||
)
|
||||
self.connection.commit()
|
||||
else:
|
||||
# Yup. We're done, so go home.
|
||||
return
|
||||
else:
|
||||
# Check to see if we are the only lock holder.
|
||||
cursor.execute("select * from locks"
|
||||
" where unique_name = ?",
|
||||
(self.unique_name,))
|
||||
cursor.execute(
|
||||
"select * from locks" " where unique_name = ?", (self.unique_name,)
|
||||
)
|
||||
rows = cursor.fetchall()
|
||||
if len(rows) == 1:
|
||||
# We're the locker, so go home.
|
||||
@@ -103,9 +111,9 @@ class SQLiteLockFile(LockBase):
|
||||
if timeout is not None and time.time() > end_time:
|
||||
if timeout > 0:
|
||||
# No more waiting.
|
||||
raise LockTimeout("Timeout waiting to acquire"
|
||||
" lock for %s" %
|
||||
self.path)
|
||||
raise LockTimeout(
|
||||
"Timeout waiting to acquire" " lock for %s" % self.path
|
||||
)
|
||||
else:
|
||||
# Someone else has the lock and we are impatient..
|
||||
raise AlreadyLocked("%s is already locked" % self.path)
|
||||
@@ -117,40 +125,38 @@ class SQLiteLockFile(LockBase):
|
||||
if not self.is_locked():
|
||||
raise NotLocked("%s is not locked" % self.path)
|
||||
if not self.i_am_locking():
|
||||
raise NotMyLock("%s is locked, but not by me (by %s)" %
|
||||
(self.unique_name, self._who_is_locking()))
|
||||
raise NotMyLock(
|
||||
"%s is locked, but not by me (by %s)"
|
||||
% (self.unique_name, self._who_is_locking())
|
||||
)
|
||||
cursor = self.connection.cursor()
|
||||
cursor.execute("delete from locks"
|
||||
" where unique_name = ?",
|
||||
(self.unique_name,))
|
||||
cursor.execute(
|
||||
"delete from locks" " where unique_name = ?", (self.unique_name,)
|
||||
)
|
||||
self.connection.commit()
|
||||
|
||||
def _who_is_locking(self):
|
||||
cursor = self.connection.cursor()
|
||||
cursor.execute("select unique_name from locks"
|
||||
" where lock_file = ?",
|
||||
(self.lock_file,))
|
||||
cursor.execute(
|
||||
"select unique_name from locks" " where lock_file = ?", (self.lock_file,)
|
||||
)
|
||||
return cursor.fetchone()[0]
|
||||
|
||||
def is_locked(self):
|
||||
cursor = self.connection.cursor()
|
||||
cursor.execute("select * from locks"
|
||||
" where lock_file = ?",
|
||||
(self.lock_file,))
|
||||
cursor.execute("select * from locks" " where lock_file = ?", (self.lock_file,))
|
||||
rows = cursor.fetchall()
|
||||
return not not rows
|
||||
|
||||
def i_am_locking(self):
|
||||
cursor = self.connection.cursor()
|
||||
cursor.execute("select * from locks"
|
||||
" where lock_file = ?"
|
||||
" and unique_name = ?",
|
||||
(self.lock_file, self.unique_name))
|
||||
cursor.execute(
|
||||
"select * from locks" " where lock_file = ?" " and unique_name = ?",
|
||||
(self.lock_file, self.unique_name),
|
||||
)
|
||||
return not not cursor.fetchall()
|
||||
|
||||
def break_lock(self):
|
||||
cursor = self.connection.cursor()
|
||||
cursor.execute("delete from locks"
|
||||
" where lock_file = ?",
|
||||
(self.lock_file,))
|
||||
cursor.execute("delete from locks" " where lock_file = ?", (self.lock_file,))
|
||||
self.connection.commit()
|
||||
|
||||
@@ -3,8 +3,7 @@ from __future__ import absolute_import
|
||||
import os
|
||||
import time
|
||||
|
||||
from . import (LockBase, NotLocked, NotMyLock, LockTimeout,
|
||||
AlreadyLocked)
|
||||
from . import LockBase, NotLocked, NotMyLock, LockTimeout, AlreadyLocked
|
||||
|
||||
|
||||
class SymlinkLockFile(LockBase):
|
||||
@@ -40,12 +39,11 @@ class SymlinkLockFile(LockBase):
|
||||
# Otherwise the lock creation failed.
|
||||
if timeout is not None and time.time() > end_time:
|
||||
if timeout > 0:
|
||||
raise LockTimeout("Timeout waiting to acquire"
|
||||
" lock for %s" %
|
||||
self.path)
|
||||
raise LockTimeout(
|
||||
"Timeout waiting to acquire" " lock for %s" % self.path
|
||||
)
|
||||
else:
|
||||
raise AlreadyLocked("%s is already locked" %
|
||||
self.path)
|
||||
raise AlreadyLocked("%s is already locked" % self.path)
|
||||
time.sleep(timeout / 10 if timeout is not None else 0.1)
|
||||
else:
|
||||
# Link creation succeeded. We're good to go.
|
||||
@@ -62,8 +60,10 @@ class SymlinkLockFile(LockBase):
|
||||
return os.path.islink(self.lock_file)
|
||||
|
||||
def i_am_locking(self):
|
||||
return (os.path.islink(self.lock_file)
|
||||
and os.readlink(self.lock_file) == self.unique_name)
|
||||
return (
|
||||
os.path.islink(self.lock_file)
|
||||
and os.readlink(self.lock_file) == self.unique_name
|
||||
)
|
||||
|
||||
def break_lock(self):
|
||||
if os.path.islink(self.lock_file): # exists && link
|
||||
|
||||
Reference in New Issue
Block a user