Hello community, here is the log from the commit of package python-fasteners for openSUSE:Factory checked in at 2016-01-01 19:48:21 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-fasteners (Old) and /work/SRC/openSUSE:Factory/.python-fasteners.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "python-fasteners" Changes: -------- --- /work/SRC/openSUSE:Factory/python-fasteners/python-fasteners.changes 2015-10-06 13:27:46.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python-fasteners.new/python-fasteners.changes 2016-01-01 19:50:23.000000000 +0100 @@ -1,0 +2,10 @@ +Thu Dec 17 13:42:09 UTC 2015 - tbechtold@suse.com + +- update to 0.14.1: + * Allow providing a custom exception logger + to 'locked' decorator + * Allow providing a custom logger to process + lock class + * Fix issue #12 + +------------------------------------------------------------------- Old: ---- fasteners-0.13.0.tar.gz New: ---- fasteners-0.14.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-fasteners.spec ++++++ --- /var/tmp/diff_new_pack.STFASc/_old 2016-01-01 19:50:24.000000000 +0100 +++ /var/tmp/diff_new_pack.STFASc/_new 2016-01-01 19:50:24.000000000 +0100 @@ -17,7 +17,7 @@ Name: python-fasteners -Version: 0.13.0 +Version: 0.14.1 Release: 0 Summary: A python package that provides useful locks License: Apache-2.0 ++++++ fasteners-0.13.0.tar.gz -> fasteners-0.14.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fasteners-0.13.0/ChangeLog new/fasteners-0.14.1/ChangeLog --- old/fasteners-0.13.0/ChangeLog 2015-08-22 16:27:55.000000000 +0200 +++ new/fasteners-0.14.1/ChangeLog 2015-11-13 07:40:18.000000000 +0100 @@ -1,3 +1,9 @@ +0.14: + - Allow providing a custom exception logger + to 'locked' decorator + - Allow providing a custom logger to process + lock class + - Fix issue #12 0.13: - Fix 'ensure_tree' check on freebsd 0.12: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fasteners-0.13.0/PKG-INFO new/fasteners-0.14.1/PKG-INFO --- old/fasteners-0.13.0/PKG-INFO 2015-08-22 16:29:46.000000000 +0200 +++ new/fasteners-0.14.1/PKG-INFO 2015-11-13 07:47:25.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: fasteners -Version: 0.13.0 +Version: 0.14.1 Summary: A python package that provides useful locks. Home-page: https://github.com/harlowja/fasteners Author: Joshua Harlow diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fasteners-0.13.0/fasteners/_utils.py new/fasteners-0.14.1/fasteners/_utils.py --- old/fasteners-0.13.0/fasteners/_utils.py 2015-08-08 10:15:25.000000000 +0200 +++ new/fasteners-0.14.1/fasteners/_utils.py 2015-11-13 07:39:16.000000000 +0100 @@ -27,6 +27,14 @@ LOG = logging.getLogger(__name__) +def pick_first_not_none(*values): + """Returns first of values that is *not* None (or None if all are/were).""" + for val in values: + if val is not None: + return val + return None + + class LockStack(object): """Simple lock stack to get and release many locks. @@ -35,8 +43,9 @@ invalid if that is attempted. """ - def __init__(self): + def __init__(self, logger=None): self._stack = [] + self._logger = pick_first_not_none(logger, LOG) def acquire_lock(self, lock): gotten = lock.acquire() @@ -55,8 +64,8 @@ try: lock.release() except Exception: - LOG.exception("Failed releasing lock %s from lock" - " stack with %s locks", am_left, tot_am) + self._logger.exception("Failed releasing lock %s from lock" + " stack with %s locks", am_left, tot_am) am_left -= 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fasteners-0.13.0/fasteners/lock.py new/fasteners-0.14.1/fasteners/lock.py --- old/fasteners-0.13.0/fasteners/lock.py 2015-08-08 10:15:25.000000000 +0200 +++ new/fasteners-0.14.1/fasteners/lock.py 2015-11-13 07:39:16.000000000 +0100 @@ -137,7 +137,7 @@ current_thread_functor=None): self._writer = None self._pending_writers = collections.deque() - self._readers = collections.deque() + self._readers = {} self._cond = condition_cls() if current_thread_functor is None: current_thread_functor = self._fetch_current_thread_functor() @@ -191,7 +191,10 @@ # No active writer, or we are the writer; # we are good to become a reader. if self._writer is None or self._writer == me: - self._readers.append(me) + try: + self._readers[me] = self._readers[me] + 1 + except KeyError: + self._readers[me] = 1 break # An active writer; guess we have to wait. self._cond.wait() @@ -203,7 +206,14 @@ # still have to remove that other read lock; this allows for # basic reentrancy to be possible. with self._cond: - self._readers.remove(me) + try: + me_instances = self._readers[me] + if me_instances > 1: + self._readers[me] = me_instances - 1 + else: + self._readers.pop(me) + except KeyError: + pass self._cond.notify_all() @contextlib.contextmanager @@ -270,16 +280,21 @@ attribute named '_lock' is looked for (this attribute is expected to be the lock/list of locks object/s) in the instance object this decorator is attached to. + + NOTE(harlowja): a custom logger (which will be used if lock release + failures happen) can be provided by passing a logger instance for keyword + argument ``logger``. """ def decorator(f): attr_name = kwargs.get('lock', '_lock') + logger = kwargs.get('logger') @six.wraps(f) def wrapper(self, *args, **kwargs): attr_value = getattr(self, attr_name) if isinstance(attr_value, (tuple, list)): - with _utils.LockStack() as stack: + with _utils.LockStack(logger=logger) as stack: for i, lock in enumerate(attr_value): if not stack.acquire_lock(lock): raise threading.ThreadError("Unable to acquire" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fasteners-0.13.0/fasteners/process_lock.py new/fasteners-0.14.1/fasteners/process_lock.py --- old/fasteners-0.13.0/fasteners/process_lock.py 2015-08-22 15:34:02.000000000 +0200 +++ new/fasteners-0.14.1/fasteners/process_lock.py 2015-11-13 07:39:16.000000000 +0100 @@ -82,11 +82,12 @@ acquire the lock (and repeat). """ - def __init__(self, path, sleep_func=time.sleep): + def __init__(self, path, sleep_func=time.sleep, logger=None): self.lockfile = None self.path = path self.acquired = False self.sleep_func = sleep_func + self.logger = _utils.pick_first_not_none(logger, LOG) def _try_acquire(self, blocking, watch): try: @@ -110,10 +111,11 @@ def _do_open(self): basedir = os.path.dirname(self.path) - made_basedir = _ensure_tree(basedir) - if made_basedir: - LOG.log(_utils.BLATHER, - 'Created lock base path `%s`', basedir) + if basedir: + made_basedir = _ensure_tree(basedir) + if made_basedir: + self.logger.log(_utils.BLATHER, + 'Created lock base path `%s`', basedir) # Open in append mode so we don't overwrite any potential contents of # the target file. This eliminates the possibility of an attacker # creating a symlink to an important file in our lock path. @@ -157,10 +159,10 @@ return False else: self.acquired = True - LOG.log(_utils.BLATHER, - "Acquired file lock `%s` after waiting %0.3fs [%s" - " attempts were required]", self.path, watch.elapsed(), - r.attempts) + self.logger.log(_utils.BLATHER, + "Acquired file lock `%s` after waiting %0.3fs [%s" + " attempts were required]", self.path, + watch.elapsed(), r.attempts) return True def _do_close(self): @@ -180,19 +182,19 @@ try: self.unlock() except IOError: - LOG.exception("Could not unlock the acquired lock opened" - " on `%s`", self.path) + self.logger.exception("Could not unlock the acquired lock opened" + " on `%s`", self.path) else: self.acquired = False try: self._do_close() except IOError: - LOG.exception("Could not close the file handle" - " opened on `%s`", self.path) + self.logger.exception("Could not close the file handle" + " opened on `%s`", self.path) else: - LOG.log(_utils.BLATHER, - "Unlocked and closed file lock open on" - " `%s`", self.path) + self.logger.log(_utils.BLATHER, + "Unlocked and closed file lock open on" + " `%s`", self.path) def __exit__(self, exc_type, exc_val, exc_tb): self.release() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fasteners-0.13.0/fasteners/version.py new/fasteners-0.14.1/fasteners/version.py --- old/fasteners-0.13.0/fasteners/version.py 2015-08-08 10:15:25.000000000 +0200 +++ new/fasteners-0.14.1/fasteners/version.py 2015-11-13 07:46:02.000000000 +0100 @@ -17,7 +17,7 @@ # License for the specific language governing permissions and limitations # under the License. -_VERSION = "0.12" +_VERSION = "0.14.1" def version_string(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fasteners-0.13.0/fasteners.egg-info/PKG-INFO new/fasteners-0.14.1/fasteners.egg-info/PKG-INFO --- old/fasteners-0.13.0/fasteners.egg-info/PKG-INFO 2015-08-22 16:29:45.000000000 +0200 +++ new/fasteners-0.14.1/fasteners.egg-info/PKG-INFO 2015-11-13 07:47:25.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: fasteners -Version: 0.13.0 +Version: 0.14.1 Summary: A python package that provides useful locks. Home-page: https://github.com/harlowja/fasteners Author: Joshua Harlow diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fasteners-0.13.0/fasteners.egg-info/SOURCES.txt new/fasteners-0.14.1/fasteners.egg-info/SOURCES.txt --- old/fasteners-0.13.0/fasteners.egg-info/SOURCES.txt 2015-08-22 16:29:45.000000000 +0200 +++ new/fasteners-0.14.1/fasteners.egg-info/SOURCES.txt 2015-11-13 07:47:25.000000000 +0100 @@ -13,7 +13,6 @@ fasteners.egg-info/PKG-INFO fasteners.egg-info/SOURCES.txt fasteners.egg-info/dependency_links.txt -fasteners.egg-info/pbr.json fasteners.egg-info/requires.txt fasteners.egg-info/top_level.txt fasteners/tests/__init__.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fasteners-0.13.0/fasteners.egg-info/pbr.json new/fasteners-0.14.1/fasteners.egg-info/pbr.json --- old/fasteners-0.13.0/fasteners.egg-info/pbr.json 2015-08-22 16:29:45.000000000 +0200 +++ new/fasteners-0.14.1/fasteners.egg-info/pbr.json 1970-01-01 01:00:00.000000000 +0100 @@ -1 +0,0 @@ -{"is_release": false, "git_version": "c055890"} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fasteners-0.13.0/fasteners.egg-info/requires.txt new/fasteners-0.14.1/fasteners.egg-info/requires.txt --- old/fasteners-0.13.0/fasteners.egg-info/requires.txt 2015-08-22 16:29:45.000000000 +0200 +++ new/fasteners-0.14.1/fasteners.egg-info/requires.txt 2015-11-13 07:47:25.000000000 +0100 @@ -1,2 +1,2 @@ six -monotonic>=0.1 \ No newline at end of file +monotonic>=0.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/fasteners-0.13.0/setup.py new/fasteners-0.14.1/setup.py --- old/fasteners-0.13.0/setup.py 2015-08-22 16:28:14.000000000 +0200 +++ new/fasteners-0.14.1/setup.py 2015-11-13 07:46:46.000000000 +0100 @@ -31,7 +31,7 @@ setup( name='fasteners', - version='0.13.0', + version='0.14.1', description='A python package that provides useful locks.', author="Joshua Harlow", author_email='harlowja@yahoo-inc.com',