summaryrefslogtreecommitdiff
path: root/decorator
diff options
context:
space:
mode:
authormichele.simionato <devnull@localhost>2009-04-21 09:53:51 +0000
committermichele.simionato <devnull@localhost>2009-04-21 09:53:51 +0000
commitc692f6dda66eb896a5edd78a097eb5cca9e5017e (patch)
treed6075f45582387f3d2a84970bc36b0069ebbf28d /decorator
parent590505a9d2d2184d88755465f3365c965a8b4a77 (diff)
downloadmicheles-c692f6dda66eb896a5edd78a097eb5cca9e5017e.tar.gz
Improved the TailRecursive decorator by using George Sakkis's version
Diffstat (limited to 'decorator')
-rw-r--r--decorator/documentation.py35
1 files changed, 17 insertions, 18 deletions
diff --git a/decorator/documentation.py b/decorator/documentation.py
index 97552da..e5cc32c 100644
--- a/decorator/documentation.py
+++ b/decorator/documentation.py
@@ -983,37 +983,36 @@ class Action(object):
@Restricted(Admin)
def delete(self):
pass
-
+
class TailRecursive(object):
"""
tail_recursive decorator based on Kay Schluehr's recipe
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496691
+ with improvements by me and George Sakkis.
"""
- CONTINUE = object() # sentinel
def __init__(self, func):
self.func = func
self.firstcall = True
+ self.CONTINUE = object() # sentinel
def __call__(self, *args, **kwd):
- try:
- if self.firstcall: # start looping
- self.firstcall = False
- while True:
- result = self.func(*args, **kwd)
- if result is self.CONTINUE: # update arguments
+ CONTINUE = self.CONTINUE
+ if self.firstcall:
+ func = self.func
+ self.firstcall = False
+ try:
+ while True:
+ result = func(*args, **kwd)
+ if result is CONTINUE: # update arguments
args, kwd = self.argskwd
else: # last call
- break
- else: # return the arguments of the tail call
- self.argskwd = args, kwd
- return self.CONTINUE
- except: # reset and re-raise
- self.firstcall = True
- raise
- else: # reset and exit
- self.firstcall = True
- return result
+ return result
+ finally:
+ self.firstcall = True
+ else: # return the arguments of the tail call
+ self.argskwd = args, kwd
+ return CONTINUE
def tail_recursive(func):
return decorator_apply(TailRecursive, func)