From c364beb1354983a48885b15f0e2dd8cc892a9046 Mon Sep 17 00:00:00 2001 From: David Aguilar Date: Sat, 25 Feb 2012 13:09:10 -0800 Subject: [PATCH] decorators: Move interruptable() to cola.decorators Signed-off-by: David Aguilar --- cola/core.py | 29 ++++------------------------- cola/decorators.py | 52 +++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 47 insertions(+), 34 deletions(-) diff --git a/cola/core.py b/cola/core.py index 6cad6e54..6baa1edd 100644 --- a/cola/core.py +++ b/cola/core.py @@ -1,13 +1,10 @@ """This module provides core functions for handling unicode and UNIX quirks -OSX and others are known to interrupt system calls +The @interruptable functions retry when system calls are interrupted, +e.g. when python raises an IOError or OSError with errno == EINTR. - http://en.wikipedia.org/wiki/PCLSRing - http://en.wikipedia.org/wiki/Unix_philosophy#Worse_is_better - -The @interruptable functions handle this situation """ -import errno +from cola.decorators import interruptable # Some files are not in UTF-8; some other aren't in any codification. # Remember that GIT doesn't care about encodings (saves binary data) @@ -30,31 +27,13 @@ def decode(enc): # this shouldn't ever happen... FIXME return unicode(enc) + def encode(unenc): """encode(unencoded_string) returns a string encoded in utf-8 """ return unenc.encode('utf-8', 'replace') -def interruptable(fn): - def interruptable_decorator(*args): - while True: - try: - result = fn(*args) - except IOError, e: - if e.errno == errno.EINTR: - continue - raise e - except OSError, e: - if e.errno == errno.EINTR: - continue - raise e - else: - break - return result - return interruptable_decorator - - @interruptable def read(fh): """Read from a filehandle and retry when interrupted""" diff --git a/cola/decorators.py b/cola/decorators.py index 0587a964..7e44d5d0 100644 --- a/cola/decorators.py +++ b/cola/decorators.py @@ -1,22 +1,28 @@ -__all__ = ('decorator', 'deprecated', 'memoize') +__all__ = ('decorated', 'deprecator', 'memoize', 'interruptable') + +import errno def decorator(caller, func=None): """ + Create a new decorator + decorator(caller) converts a caller function into a decorator; decorator(caller, func) decorates a function using a caller. + """ - if func is None: # returns a decorator + if func is None: + # return a decorator def _decorator(f, *args, **opts): def _caller(*args, **opts): return caller(f, *args, **opts) return _caller return _decorator - - else: # returns a decorated function - def _decorator(*args, **opts): + else: + # return a decorated function + def _decorated(*args, **opts): return caller(func, *args, **opts) - return _decorator + return _decorated @decorator @@ -47,7 +53,35 @@ def _memoize(func, *args, **opts): key = args cache = func.cache # attribute added by memoize try: - return cache[key] + result = cache[key] except KeyError: - cache[key] = result = func(*args, **opts) - return result + result = cache[key] = func(*args, **opts) + return result + + +@decorator +def interruptable(func, *args, **opts): + """Handle interruptable system calls + + OSX and others are known to interrupt system calls + + http://en.wikipedia.org/wiki/PCLSRing + http://en.wikipedia.org/wiki/Unix_philosophy#Worse_is_better + + The @interruptable decorator handles this situation + + """ + while True: + try: + result = func(*args, **opts) + except IOError, e: + if e.errno == errno.EINTR: + continue + raise e + except OSError, e: + if e.errno == errno.EINTR: + continue + raise e + else: + break + return result -- 2.11.4.GIT