diff --git a/ChangeLog b/ChangeLog index 8b5930c..82afe7a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +* 2.0.0 - Mar 18 2016 +- Change implementation to not leave lingering threads after a timeout occurs + * 1.0.1 - Mar 15 2016 - Remove debugging print - Note that it has been explicitly tested on 2.7, 3.4, and 3.5 in README. diff --git a/func_timeout/__init__.py b/func_timeout/__init__.py index 1a80394..61ca80c 100644 --- a/func_timeout/__init__.py +++ b/func_timeout/__init__.py @@ -5,73 +5,11 @@ LICENSE, otherwise it is available at https://github.com/kata198/func_timeout/LICENSE ''' -import threading -import time -__version__ = '1.0.1' -__version_tuple__ = (1, 0, 1) +__version__ = '2.0.0' +__version_tuple__ = (2, 0, 0) __all__ = ('func_timeout', 'FunctionTimedOut') -def func_timeout(timeout, func, args=(), kwargs=None): - ''' - func_timeout - Runs the given function for up to #timeout# seconds. - - Raises any exceptions #func# would raise, returns what #func# would return (unless timeout is exceeded), in which case it raises FunctionTimedOut - - @param timeout - Maximum number of seconds to run #func# before terminating - @param func - The function to call - @param args - Any ordered arguments to pass to the function - @param kwargs - Keyword arguments to pass to the function. - - @raises - FunctionTimedOut if #timeout# is exceeded, otherwise anything #func# could raise will be raised - - @return - The return value that #func# gives - ''' - - if not kwargs: - kwargs = {} - if not args: - args = () - - ret = [] - exception = [] - - def funcwrap(args2, kwargs2): - try: - ret.append( func(*args2, **kwargs2) ) - except Exception as e: - exception.append(e) - - thread = threading.Thread(target=funcwrap, args=(args, kwargs)) - - thread.start() - thread.join(timeout) - - if thread.isAlive(): - doRaiseCantStop = False - thread.isDaemon = True - try: - if hasattr(thread, '_tstate_lock'): - # 3.5 - thread._tstate_lock.release() - elif hasattr(thread, '_Thread__stop'): - # 2.7 - thread._Thread__stop() - else: - doRaiseCantStop = True - except: - pass - if doRaiseCantStop is True: - raise NotImplementedError('function timeouts not supported on this system.\n') - - if exception: - raise exception[0] - - if ret: - return ret[0] - - raise FunctionTimedOut('Function %s (args=%s) (kwargs=%s) timed out after %f seconds.\n' %(func.__name__, str(args), str(kwargs), timeout)) - -class FunctionTimedOut(Exception): - pass +from .exceptions import FunctionTimedOut +from .dafunc import func_timeout diff --git a/setup.py b/setup.py index 0f4dba4..2d01454 100755 --- a/setup.py +++ b/setup.py @@ -30,7 +30,7 @@ if __name__ == '__main__': log_description = summary setup(name='func_timeout', - version='1.0.1', + version='2.0.0', packages=['func_timeout'], author='Tim Savannah', author_email='kata198@gmail.com',