Initial Release
This commit is contained in:
parent
37a15a64c3
commit
9104d8ca62
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
*.pyc
|
||||
*.pyo
|
||||
*~
|
||||
build/
|
||||
dist/
|
||||
*.egg-info/
|
||||
7
MANIFEST.in
Normal file
7
MANIFEST.in
Normal file
@ -0,0 +1,7 @@
|
||||
include setup.py
|
||||
include LICENSE
|
||||
include README.md
|
||||
include README.rst
|
||||
include MANIFEST.in
|
||||
recursive-include func_timeout *.py
|
||||
recursive-include doc *.html
|
||||
57
README.md
57
README.md
@ -1,2 +1,55 @@
|
||||
# func_timeout
|
||||
Python module to support running any existing function with a given timeout
|
||||
# func\_timeout
|
||||
Python module to support running any existing function with a given timeout.
|
||||
|
||||
|
||||
Package Includes
|
||||
----------------
|
||||
|
||||
**func\_timeout**
|
||||
|
||||
This is the function wherein you pass the timeout, the function you want to call, and any arguments, and it runs it for up to #timeout# seconds, and will return/raise anything the passed function would otherwise return or raise.
|
||||
|
||||
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 <float> - Maximum number of seconds to run #func# before terminating
|
||||
@param func <function> - The function to call
|
||||
@param args <tuple> - Any ordered arguments to pass to the function
|
||||
@param kwargs <dict/None> - 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
|
||||
'''
|
||||
|
||||
**FunctionTimedOut**
|
||||
|
||||
Exception raised if the function times out
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
So, for esxample, if you have a function "doit('arg1', 'arg2')" that you want to limit to running for 5 seconds, with func\_timeout you can call it like this:
|
||||
|
||||
|
||||
from func_timeout import func_timeout, FunctionTimedOut
|
||||
|
||||
...
|
||||
|
||||
try:
|
||||
|
||||
doitReturnValue = func_timeout(5, doit, args=('arg1', 'arg2'))
|
||||
|
||||
except FunctionTimedOut:
|
||||
print ( "doit('arg1', 'arg2') could not complete within 5 seconds and was terminated.\n")
|
||||
except Exception as e:
|
||||
# Handle any exceptions that doit might raise here
|
||||
|
||||
|
||||
Support
|
||||
-------
|
||||
|
||||
I've tested func\_timeout with python 2.7 and python 3.5.
|
||||
|
||||
74
README.rst
Normal file
74
README.rst
Normal file
@ -0,0 +1,74 @@
|
||||
func_timeout
|
||||
=============
|
||||
Python module to support running any existing function with a given timeout.
|
||||
|
||||
|
||||
Package Includes
|
||||
----------------
|
||||
|
||||
**func_timeout**
|
||||
|
||||
This is the function wherein you pass the timeout, the function you want to call, and any arguments, and it runs it for up to #timeout# seconds, and will return/raise anything the passed function would otherwise return or raise.
|
||||
|
||||
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 <float> - Maximum number of seconds to run #func# before terminating
|
||||
|
||||
@param func <function> - The function to call
|
||||
|
||||
@param args <tuple> - Any ordered arguments to pass to the function
|
||||
|
||||
@param kwargs <dict/None> - 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
|
||||
|
||||
'''
|
||||
|
||||
**FunctionTimedOut**
|
||||
|
||||
Exception raised if the function times out
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
So, for esxample, if you have a function "doit('arg1', 'arg2')" that you want to limit to running for 5 seconds, with func_timeout you can call it like this:
|
||||
|
||||
|
||||
from func_timeout import func_timeout, FunctionTimedOut
|
||||
|
||||
|
||||
...
|
||||
|
||||
|
||||
try:
|
||||
|
||||
|
||||
doitReturnValue = func_timeout(5, doit, args=('arg1', 'arg2'))
|
||||
|
||||
|
||||
except FunctionTimedOut:
|
||||
|
||||
print ( "doit('arg1', 'arg2') could not complete within 5 seconds and was terminated.\n")
|
||||
|
||||
except Exception as e:
|
||||
|
||||
# Handle any exceptions that doit might raise here
|
||||
|
||||
|
||||
|
||||
Support
|
||||
-------
|
||||
|
||||
I've tested func_timeout with python 2.7 and python 3.5.
|
||||
116
doc/func_timeout.html
Normal file
116
doc/func_timeout.html
Normal file
@ -0,0 +1,116 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html><head><title>Python: package func_timeout</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
</head><body bgcolor="#f0f0f8">
|
||||
|
||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
|
||||
<tr bgcolor="#7799ee">
|
||||
<td valign=bottom> <br>
|
||||
<font color="#ffffff" face="helvetica, arial"> <br><big><big><strong>func_timeout</strong></big></big> (version 1.0.0)</font></td
|
||||
><td align=right valign=bottom
|
||||
><font color="#ffffff" face="helvetica, arial"><a href="func_timeout.html">index</a></font></td></tr></table>
|
||||
<p><tt>Copyright (c) 2016 Tim Savannah All Rights Reserved.<br>
|
||||
<br>
|
||||
Licensed under the Lesser GNU Public License Version 3, LGPLv3. You should have recieved a copy of this with the source distribution as<br>
|
||||
LICENSE, otherwise it is available at https://github.com/kata198/func_timeout/LICENSE</tt></p>
|
||||
<p>
|
||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
|
||||
<tr bgcolor="#aa55cc">
|
||||
<td colspan=3 valign=bottom> <br>
|
||||
<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
|
||||
|
||||
<tr><td bgcolor="#aa55cc"><tt> </tt></td><td> </td>
|
||||
<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
|
||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
|
||||
<tr bgcolor="#ee77aa">
|
||||
<td colspan=3 valign=bottom> <br>
|
||||
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
|
||||
|
||||
<tr><td bgcolor="#ee77aa"><tt> </tt></td><td> </td>
|
||||
<td width="100%"><dl>
|
||||
<dt><font face="helvetica, arial"><a href="builtins.html#Exception">builtins.Exception</a>(<a href="builtins.html#BaseException">builtins.BaseException</a>)
|
||||
</font></dt><dd>
|
||||
<dl>
|
||||
<dt><font face="helvetica, arial"><a href="func_timeout.html#FunctionTimedOut">FunctionTimedOut</a>
|
||||
</font></dt></dl>
|
||||
</dd>
|
||||
</dl>
|
||||
<p>
|
||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
|
||||
<tr bgcolor="#ffc8d8">
|
||||
<td colspan=3 valign=bottom> <br>
|
||||
<font color="#000000" face="helvetica, arial"><a name="FunctionTimedOut">class <strong>FunctionTimedOut</strong></a>(<a href="builtins.html#Exception">builtins.Exception</a>)</font></td></tr>
|
||||
|
||||
<tr bgcolor="#ffc8d8"><td rowspan=2><tt> </tt></td>
|
||||
<td colspan=2><tt>Common base class for all non-exit exceptions.<br> </tt></td></tr>
|
||||
<tr><td> </td>
|
||||
<td width="100%"><dl><dt>Method resolution order:</dt>
|
||||
<dd><a href="func_timeout.html#FunctionTimedOut">FunctionTimedOut</a></dd>
|
||||
<dd><a href="builtins.html#Exception">builtins.Exception</a></dd>
|
||||
<dd><a href="builtins.html#BaseException">builtins.BaseException</a></dd>
|
||||
<dd><a href="builtins.html#object">builtins.object</a></dd>
|
||||
</dl>
|
||||
<hr>
|
||||
Data descriptors defined here:<br>
|
||||
<dl><dt><strong>__weakref__</strong></dt>
|
||||
<dd><tt>list of weak references to the object (if defined)</tt></dd>
|
||||
</dl>
|
||||
<hr>
|
||||
Methods inherited from <a href="builtins.html#Exception">builtins.Exception</a>:<br>
|
||||
<dl><dt><a name="FunctionTimedOut-__init__"><strong>__init__</strong></a>(self, /, *args, **kwargs)</dt><dd><tt>Initialize self. See help(type(self)) for accurate signature.</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="FunctionTimedOut-__new__"><strong>__new__</strong></a>(*args, **kwargs)<font color="#909090"><font face="helvetica, arial"> from <a href="builtins.html#type">builtins.type</a></font></font></dt><dd><tt>Create and return a new object. See help(type) for accurate signature.</tt></dd></dl>
|
||||
|
||||
<hr>
|
||||
Methods inherited from <a href="builtins.html#BaseException">builtins.BaseException</a>:<br>
|
||||
<dl><dt><a name="FunctionTimedOut-__delattr__"><strong>__delattr__</strong></a>(self, name, /)</dt><dd><tt>Implement delattr(self, name).</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="FunctionTimedOut-__getattribute__"><strong>__getattribute__</strong></a>(self, name, /)</dt><dd><tt>Return getattr(self, name).</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="FunctionTimedOut-__reduce__"><strong>__reduce__</strong></a>(...)</dt><dd><tt>helper for pickle</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="FunctionTimedOut-__repr__"><strong>__repr__</strong></a>(self, /)</dt><dd><tt>Return repr(self).</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="FunctionTimedOut-__setattr__"><strong>__setattr__</strong></a>(self, name, value, /)</dt><dd><tt>Implement setattr(self, name, value).</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="FunctionTimedOut-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
|
||||
|
||||
<dl><dt><a name="FunctionTimedOut-__str__"><strong>__str__</strong></a>(self, /)</dt><dd><tt>Return str(self).</tt></dd></dl>
|
||||
|
||||
<dl><dt><a name="FunctionTimedOut-with_traceback"><strong>with_traceback</strong></a>(...)</dt><dd><tt><a href="builtins.html#Exception">Exception</a>.<a href="#FunctionTimedOut-with_traceback">with_traceback</a>(tb) --<br>
|
||||
set self.<strong>__traceback__</strong> to tb and return self.</tt></dd></dl>
|
||||
|
||||
<hr>
|
||||
Data descriptors inherited from <a href="builtins.html#BaseException">builtins.BaseException</a>:<br>
|
||||
<dl><dt><strong>__cause__</strong></dt>
|
||||
<dd><tt>exception cause</tt></dd>
|
||||
</dl>
|
||||
<dl><dt><strong>__context__</strong></dt>
|
||||
<dd><tt>exception context</tt></dd>
|
||||
</dl>
|
||||
<dl><dt><strong>__dict__</strong></dt>
|
||||
</dl>
|
||||
<dl><dt><strong>__suppress_context__</strong></dt>
|
||||
</dl>
|
||||
<dl><dt><strong>__traceback__</strong></dt>
|
||||
</dl>
|
||||
<dl><dt><strong>args</strong></dt>
|
||||
</dl>
|
||||
</td></tr></table></td></tr></table><p>
|
||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
|
||||
<tr bgcolor="#eeaa77">
|
||||
<td colspan=3 valign=bottom> <br>
|
||||
<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
|
||||
|
||||
<tr><td bgcolor="#eeaa77"><tt> </tt></td><td> </td>
|
||||
<td width="100%"><dl><dt><a name="-func_timeout"><strong>func_timeout</strong></a>(timeout, func, args=(), kwargs=None)</dt></dl>
|
||||
</td></tr></table><p>
|
||||
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
|
||||
<tr bgcolor="#55aa55">
|
||||
<td colspan=3 valign=bottom> <br>
|
||||
<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
|
||||
|
||||
<tr><td bgcolor="#55aa55"><tt> </tt></td><td> </td>
|
||||
<td width="100%"><strong>__all__</strong> = ('func_timeout', 'FunctionTimedOut')<br>
|
||||
<strong>__version_tuple__</strong> = (1, 0, 0)</td></tr></table>
|
||||
</body></html>
|
||||
79
func_timeout/__init__.py
Normal file
79
func_timeout/__init__.py
Normal file
@ -0,0 +1,79 @@
|
||||
'''
|
||||
Copyright (c) 2016 Tim Savannah All Rights Reserved.
|
||||
|
||||
Licensed under the Lesser GNU Public License Version 3, LGPLv3. You should have recieved a copy of this with the source distribution as
|
||||
LICENSE, otherwise it is available at https://github.com/kata198/func_timeout/LICENSE
|
||||
'''
|
||||
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
|
||||
__version__ = '1.0.0'
|
||||
__version_tuple__ = (1, 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 <float> - Maximum number of seconds to run #func# before terminating
|
||||
@param func <function> - The function to call
|
||||
@param args <tuple> - Any ordered arguments to pass to the function
|
||||
@param kwargs <dict/None> - 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):
|
||||
sys.stdout.write('Args2: %s\nkwargs2: %s\n' %(str(args2), str(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
|
||||
56
setup.py
Executable file
56
setup.py
Executable file
@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python
|
||||
'''
|
||||
Copyright (c) 2016 Tim Savannah All Rights Reserved.
|
||||
This software is licensed under the terms of the Lesser GNU General Public License Version 2.1 (LGPLv2.1)
|
||||
|
||||
You should have received a copy of this with the source distribution as LICENSE,
|
||||
otherwise the most up to date license can be found at
|
||||
https://github.com/kata198/func_timeout/LICENSE
|
||||
|
||||
'''
|
||||
|
||||
import os
|
||||
import sys
|
||||
from setuptools import setup
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
dirName = os.path.dirname(__file__)
|
||||
if dirName and os.getcwd() != dirName:
|
||||
os.chdir(dirName)
|
||||
|
||||
summary = 'Python module which allows you to specify timeouts when calling any existing function'
|
||||
|
||||
try:
|
||||
with open('README.rst', 'rt') as f:
|
||||
long_description = f.read()
|
||||
except Exception as e:
|
||||
sys.stderr.write('Error reading from README.rst: %s\n' %(str(e),))
|
||||
log_description = summary
|
||||
|
||||
setup(name='func_timeout',
|
||||
version='1.0.0',
|
||||
packages=['func_timeout']
|
||||
author='Tim Savannah',
|
||||
author_email='kata198@gmail.com',
|
||||
maintainer='Tim Savannah',
|
||||
url='https://github.com/kata198/func_timeout',
|
||||
maintainer_email='kata198@gmail.com',
|
||||
description=summary,
|
||||
long_description=long_description,
|
||||
license='LGPLv2',
|
||||
keywords=['function', 'timeout', 'call', 'terminate', 'runtime', 'max', 'seconds', 'after', 'execution']
|
||||
classifiers=['Development Status :: 5 - Production/Stable'
|
||||
'Programming Language :: Python',
|
||||
'License :: OSI Approved :: GNU Lesser General Public License v2 (LGPLv2)'
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Topic :: Software Development :: Libraries :: Python Modules'
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user