diff --git a/func_timeout/dafunc.py b/func_timeout/dafunc.py index f69786e..fff9cfa 100644 --- a/func_timeout/dafunc.py +++ b/func_timeout/dafunc.py @@ -81,7 +81,7 @@ def func_timeout(timeout, func, args=(), kwargs=None): stopException = FunctionTimedOut thread._stopThread(stopException) thread.join(.1) - raise FunctionTimedOut('Function %s (args=%s) (kwargs=%s) timed out after %f seconds.\n' %(func.__name__, str(args), str(kwargs), timeout)) + raise FunctionTimedOut('', timeout, func, args, kwargs) if exception: raise exception[0] diff --git a/func_timeout/exceptions.py b/func_timeout/exceptions.py index 62e2c3a..613bbec 100644 --- a/func_timeout/exceptions.py +++ b/func_timeout/exceptions.py @@ -5,9 +5,64 @@ LICENSE, otherwise it is available at https://github.com/kata198/func_timeout/LICENSE ''' +__all__ = ('FunctionTimedOut', 'RETRY_SAME_TIMEOUT') + +RETRY_SAME_TIMEOUT = '__rst' class FunctionTimedOut(BaseException): ''' FunctionTimedOut - Exception raised when a function times out + + @property timedOutAfter - Number of seconds before timeout was triggered + + @property timedOutFunction - Function called which timed out + @property timedOutArgs - Ordered args to function + @property timedOutKwargs - Keyword args to function + + @method retry - R ''' - pass + + + def __init__(self, msg='', timedOutAfter=None, timedOutFunction=None, timedOutArgs=None, timedOutKwargs=None): + + self.timedOutAfter = timedOutAfter + + self.timedOutFunction = timedOutFunction + self.timedOutArgs = timedOutArgs + self.timedOutKwargs = timedOutKwargs + + if not msg: + msg = self.getMsg() + + BaseException.__init__(self, msg) + + + def getMsg(self): + ''' + getMsg - Generate a default message based on parameters to FunctionTimedOut exception' + + @return - Message + ''' + return 'Function %s (args=%s) (kwargs=%s) timed out after %f seconds.\n' %(self.timedOutFunction.__name__, repr(self.timedOutArgs), repr(self.timedOutKwargs), self.timedOutAfter) + + def retry(self, timeout=RETRY_SAME_TIMEOUT): + ''' + retry - Retry the timed-out function with same arguments. + + @param timeout Default RETRY_SAME_TIMEOUT + + If RETRY_SAME_TIMEOUT : Will retry the function same args, sane timeout + If a float/int : Will retry the function same args with provided timeout + If None : Will retry function same args no timeout + + @return - Returnval from function + ''' + if timeout is None: + return self.timedOutFunction(*(self.timedOutArgs), **self.timedOutKwargs) + + from .dafunc import func_timeout + + if timeout == RETRY_SAME_TIMEOUT: + timeout = self.timedOutAfter + + return func_timeout(timeout, self.timedOutFunction, args=self.timedOutArgs, kwargs=self.timedOutKwargs) diff --git a/testit.py b/testit.py index 297f198..bbfaf8a 100755 --- a/testit.py +++ b/testit.py @@ -15,8 +15,15 @@ if __name__ == '__main__': print ( "\tGot Return: %s\n" %(str(func_timeout(4, doit, args=(6,))),) ) print ( "\nShould time out (exception):" ) + myException = None try: print ("\tGot Return: %s\n" %(str(func_timeout(1, doit, kwargs={'howmany' : 16})),)) except FunctionTimedOut as e: sys.stderr.write('\tGot Exception: %s\n' %(str(e),)) + myException = e pass + + if myException is not None: + print ( "\nGot: %s\n" %( str(myException.retry(2.5)), ) ) + else: + sys.stderr.write('Did not get exception before?\n')