Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42473ad7ff | ||
|
|
eeda3385eb | ||
|
|
50baa8db50 | ||
|
|
45cdbdfe4f | ||
|
|
514225621f | ||
|
|
5452efab5b | ||
|
|
5d2afb9582 | ||
|
|
af7d6e8a39 | ||
|
|
cf8a9545bc | ||
|
|
176ef7b9d9 |
10
ChangeLog
10
ChangeLog
@ -1,3 +1,13 @@
|
|||||||
|
|
||||||
|
* 4.3.5 - Aug 19 2019
|
||||||
|
|
||||||
|
- Increase times in unit tests to ensure passing on slow systems
|
||||||
|
|
||||||
|
- Allow instantiating FunctionTimedOut exception without arguments ( will replace function name with "Unknown Function" and timedOutAfter with "Unknown" when absent)
|
||||||
|
|
||||||
|
- Update runTests.py from latest GoodTests distrib, 3.0.5 from 2.1.1
|
||||||
|
|
||||||
|
|
||||||
* 4.3.4 - Aug 19 2019
|
* 4.3.4 - Aug 19 2019
|
||||||
|
|
||||||
- Merge patch by Rafal Florczak to use threading.Thread.is_alive vs now deprecated threading.Thread.isAlive
|
- Merge patch by Rafal Florczak to use threading.Thread.is_alive vs now deprecated threading.Thread.isAlive
|
||||||
|
|||||||
@ -222,7 +222,7 @@ This will force 'Server is shutting down' as the message held by this exception.
|
|||||||
Pydoc
|
Pydoc
|
||||||
=====
|
=====
|
||||||
|
|
||||||
Find the latest pydoc at http://htmlpreview.github.io/?https://github.com/kata198/func_timeout/blob/master/doc/func_timeout.html?vers=4.3.4 .
|
Find the latest pydoc at http://htmlpreview.github.io/?https://github.com/kata198/func_timeout/blob/master/doc/func_timeout.html?vers=4.3.5 .
|
||||||
|
|
||||||
|
|
||||||
Support
|
Support
|
||||||
|
|||||||
@ -246,7 +246,7 @@ This will force 'Server is shutting down' as the message held by this exception.
|
|||||||
Pydoc
|
Pydoc
|
||||||
=====
|
=====
|
||||||
|
|
||||||
Find the latest pydoc at http://htmlpreview.github.io/?https://github.com/kata198/func_timeout/blob/master/doc/func_timeout.html?vers=4.3.4 .
|
Find the latest pydoc at http://htmlpreview.github.io/?https://github.com/kata198/func_timeout/blob/master/doc/func_timeout.html?vers=4.3.5 .
|
||||||
|
|
||||||
|
|
||||||
Support
|
Support
|
||||||
|
|||||||
@ -53,7 +53,19 @@ LICENSE, otherwise it is available at https://gith
|
|||||||
</dl>
|
</dl>
|
||||||
<hr />
|
<hr />
|
||||||
Methods defined here:<br />
|
Methods defined here:<br />
|
||||||
<dl ><dt ><a name="FunctionTimedOut-__init__" ><strong >__init__</strong></a>(self, msg='', timedOutAfter=None, timedOutFunction=None, timedOutArgs=None, timedOutKwargs=None)</dt><dd ><tt >Initialize self. See help(type(self)) for accurate signature.</tt></dd></dl>
|
<dl ><dt ><a name="FunctionTimedOut-__init__" ><strong >__init__</strong></a>(self, msg='', timedOutAfter=None, timedOutFunction=None, timedOutArgs=None, timedOutKwargs=None)</dt><dd ><tt >__init__ - Create this exception type.<br />
|
||||||
|
<br />
|
||||||
|
You should not need to do this outside of testing, it will be created by the func_timeout API<br />
|
||||||
|
<br />
|
||||||
|
@param msg <str> - A predefined message, otherwise we will attempt to generate one from the other arguments.<br />
|
||||||
|
<br />
|
||||||
|
@param timedOutAfter <None/float> - Number of seconds before timing-out. Filled-in by API, None will produce "Unknown"<br />
|
||||||
|
<br />
|
||||||
|
@param timedOutFunction <None/function> - Reference to the function that timed-out. Filled-in by API." None will produce "Unknown Function"<br />
|
||||||
|
<br />
|
||||||
|
@param timedOutArgs <None/tuple/list> - List of fixed-order arguments ( *args ), or None for no args.<br />
|
||||||
|
<br />
|
||||||
|
@param timedOutKwargs <None/dict> - Dict of keyword arg ( **kwargs ) names to values, or None for no kwargs.</tt></dd></dl>
|
||||||
|
|
||||||
<dl ><dt ><a name="FunctionTimedOut-getMsg" ><strong >getMsg</strong></a>(self)</dt><dd ><tt >getMsg - Generate a default message based on parameters to <a href="#FunctionTimedOut" >FunctionTimedOut</a> exception'<br />
|
<dl ><dt ><a name="FunctionTimedOut-getMsg" ><strong >getMsg</strong></a>(self)</dt><dd ><tt >getMsg - Generate a default message based on parameters to <a href="#FunctionTimedOut" >FunctionTimedOut</a> exception'<br />
|
||||||
<br />
|
<br />
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
<table width="100%" cellspacing="0" cellpadding="2" border="0" summary="heading" >
|
<table width="100%" cellspacing="0" cellpadding="2" border="0" summary="heading" >
|
||||||
<tr bgcolor="#7799ee" >
|
<tr bgcolor="#7799ee" >
|
||||||
<td valign="bottom" > <br />
|
<td valign="bottom" > <br />
|
||||||
<font color="#ffffff" face="helvetica, arial" > <br /><big ><big ><strong >func_timeout</strong></big></big> (version 4.3.4)</font></td><td align="right" valign="bottom" ><font color="#ffffff" face="helvetica, arial" ><a href="func_timeout.html" >index</a></font></td></tr></table>
|
<font color="#ffffff" face="helvetica, arial" > <br /><big ><big ><strong >func_timeout</strong></big></big> (version 4.3.5)</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, 2017, 2019 Tim Savannah All Rights Reserved.<br />
|
<p ><tt >Copyright (c) 2016, 2017, 2019 Tim Savannah All Rights Reserved.<br />
|
||||||
<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 />
|
Licensed under the Lesser GNU Public License Version 3, LGPLv3. You should have recieved a copy of this with the source distribution as<br />
|
||||||
@ -71,7 +71,19 @@ LICENSE, otherwise it is available at https://gith
|
|||||||
</dl>
|
</dl>
|
||||||
<hr />
|
<hr />
|
||||||
Methods defined here:<br />
|
Methods defined here:<br />
|
||||||
<dl ><dt ><a name="FunctionTimedOut-__init__" ><strong >__init__</strong></a>(self, msg='', timedOutAfter=None, timedOutFunction=None, timedOutArgs=None, timedOutKwargs=None)</dt><dd ><tt >Initialize self. See help(type(self)) for accurate signature.</tt></dd></dl>
|
<dl ><dt ><a name="FunctionTimedOut-__init__" ><strong >__init__</strong></a>(self, msg='', timedOutAfter=None, timedOutFunction=None, timedOutArgs=None, timedOutKwargs=None)</dt><dd ><tt >__init__ - Create this exception type.<br />
|
||||||
|
<br />
|
||||||
|
You should not need to do this outside of testing, it will be created by the func_timeout API<br />
|
||||||
|
<br />
|
||||||
|
@param msg <str> - A predefined message, otherwise we will attempt to generate one from the other arguments.<br />
|
||||||
|
<br />
|
||||||
|
@param timedOutAfter <None/float> - Number of seconds before timing-out. Filled-in by API, None will produce "Unknown"<br />
|
||||||
|
<br />
|
||||||
|
@param timedOutFunction <None/function> - Reference to the function that timed-out. Filled-in by API." None will produce "Unknown Function"<br />
|
||||||
|
<br />
|
||||||
|
@param timedOutArgs <None/tuple/list> - List of fixed-order arguments ( *args ), or None for no args.<br />
|
||||||
|
<br />
|
||||||
|
@param timedOutKwargs <None/dict> - Dict of keyword arg ( **kwargs ) names to values, or None for no kwargs.</tt></dd></dl>
|
||||||
|
|
||||||
<dl ><dt ><a name="FunctionTimedOut-getMsg" ><strong >getMsg</strong></a>(self)</dt><dd ><tt >getMsg - Generate a default message based on parameters to <a href="#FunctionTimedOut" >FunctionTimedOut</a> exception'<br />
|
<dl ><dt ><a name="FunctionTimedOut-getMsg" ><strong >getMsg</strong></a>(self)</dt><dd ><tt >getMsg - Generate a default message based on parameters to <a href="#FunctionTimedOut" >FunctionTimedOut</a> exception'<br />
|
||||||
<br />
|
<br />
|
||||||
@ -383,5 +395,5 @@ to return cleanly, but in most cases it
|
|||||||
|
|
||||||
<tr ><td bgcolor="#55aa55" ><tt > </tt></td><td > </td>
|
<tr ><td bgcolor="#55aa55" ><tt > </tt></td><td > </td>
|
||||||
<td width="100%" ><strong >__all__</strong> = ('func_timeout', 'func_set_timeout', 'FunctionTimedOut', 'StoppableThread')<br />
|
<td width="100%" ><strong >__all__</strong> = ('func_timeout', 'func_set_timeout', 'FunctionTimedOut', 'StoppableThread')<br />
|
||||||
<strong >__version_tuple__</strong> = (4, 3, 4)</td></tr></table>
|
<strong >__version_tuple__</strong> = (4, 3, 5)</td></tr></table>
|
||||||
</p></p></p></p></body></html>
|
</p></p></p></p></body></html>
|
||||||
@ -6,8 +6,8 @@
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
__version__ = '4.3.4'
|
__version__ = '4.3.5'
|
||||||
__version_tuple__ = (4, 3, 4)
|
__version_tuple__ = (4, 3, 5)
|
||||||
|
|
||||||
__all__ = ('func_timeout', 'func_set_timeout', 'FunctionTimedOut', 'StoppableThread')
|
__all__ = ('func_timeout', 'func_set_timeout', 'FunctionTimedOut', 'StoppableThread')
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
'''
|
'''
|
||||||
Copyright (c) 2016 Tim Savannah All Rights Reserved.
|
Copyright (c) 2016, 2017, 2019 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
|
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
|
LICENSE, otherwise it is available at https://github.com/kata198/func_timeout/LICENSE
|
||||||
@ -25,6 +25,22 @@ class FunctionTimedOut(BaseException):
|
|||||||
|
|
||||||
|
|
||||||
def __init__(self, msg='', timedOutAfter=None, timedOutFunction=None, timedOutArgs=None, timedOutKwargs=None):
|
def __init__(self, msg='', timedOutAfter=None, timedOutFunction=None, timedOutArgs=None, timedOutKwargs=None):
|
||||||
|
'''
|
||||||
|
__init__ - Create this exception type.
|
||||||
|
|
||||||
|
You should not need to do this outside of testing, it will be created by the func_timeout API
|
||||||
|
|
||||||
|
@param msg <str> - A predefined message, otherwise we will attempt to generate one from the other arguments.
|
||||||
|
|
||||||
|
@param timedOutAfter <None/float> - Number of seconds before timing-out. Filled-in by API, None will produce "Unknown"
|
||||||
|
|
||||||
|
@param timedOutFunction <None/function> - Reference to the function that timed-out. Filled-in by API." None will produce "Unknown Function"
|
||||||
|
|
||||||
|
@param timedOutArgs <None/tuple/list> - List of fixed-order arguments ( *args ), or None for no args.
|
||||||
|
|
||||||
|
@param timedOutKwargs <None/dict> - Dict of keyword arg ( **kwargs ) names to values, or None for no kwargs.
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
self.timedOutAfter = timedOutAfter
|
self.timedOutAfter = timedOutAfter
|
||||||
|
|
||||||
@ -46,7 +62,18 @@ class FunctionTimedOut(BaseException):
|
|||||||
|
|
||||||
@return <str> - Message
|
@return <str> - 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)
|
# Try to gather the function name, if available.
|
||||||
|
# If it is not, default to an "unknown" string to allow default instantiation
|
||||||
|
if self.timedOutFunction is not None:
|
||||||
|
timedOutFuncName = self.timedOutFunction.__name__
|
||||||
|
else:
|
||||||
|
timedOutFuncName = 'Unknown Function'
|
||||||
|
if self.timedOutAfter is not None:
|
||||||
|
timedOutAfterStr = "%f" %(self.timedOutAfter, )
|
||||||
|
else:
|
||||||
|
timedOutAfterStr = "Unknown"
|
||||||
|
|
||||||
|
return 'Function %s (args=%s) (kwargs=%s) timed out after %s seconds.\n' %(timedOutFuncName, repr(self.timedOutArgs), repr(self.timedOutKwargs), timedOutAfterStr)
|
||||||
|
|
||||||
def retry(self, timeout=RETRY_SAME_TIMEOUT):
|
def retry(self, timeout=RETRY_SAME_TIMEOUT):
|
||||||
'''
|
'''
|
||||||
|
|||||||
5
setup.py
5
setup.py
@ -30,7 +30,7 @@ if __name__ == '__main__':
|
|||||||
log_description = summary
|
log_description = summary
|
||||||
|
|
||||||
setup(name='func_timeout',
|
setup(name='func_timeout',
|
||||||
version='4.3.4',
|
version='4.3.7',
|
||||||
packages=['func_timeout'],
|
packages=['func_timeout'],
|
||||||
author='Tim Savannah',
|
author='Tim Savannah',
|
||||||
author_email='kata198@gmail.com',
|
author_email='kata198@gmail.com',
|
||||||
@ -50,6 +50,9 @@ if __name__ == '__main__':
|
|||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
'Programming Language :: Python :: 3.7',
|
'Programming Language :: Python :: 3.7',
|
||||||
|
'Programming Language :: Python :: 3.8',
|
||||||
|
'Programming Language :: Python :: 3.9',
|
||||||
|
'Programming Language :: Python :: 3.10',
|
||||||
'Topic :: Software Development :: Libraries :: Python Modules'
|
'Topic :: Software Development :: Libraries :: Python Modules'
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|||||||
@ -25,7 +25,7 @@ class TestBasic(object):
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
def test_funcTimeout(self):
|
def test_funcTimeout(self):
|
||||||
sleepFunction = getSleepLambda(1.25)
|
sleepFunction = getSleepLambda(2.00)
|
||||||
|
|
||||||
expectedResult = 5 + 13
|
expectedResult = 5 + 13
|
||||||
|
|
||||||
@ -36,9 +36,9 @@ class TestBasic(object):
|
|||||||
assert result == expectedResult , 'Did not get return from sleepFunction'
|
assert result == expectedResult , 'Did not get return from sleepFunction'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = func_timeout(1.5, sleepFunction, args=(5, 13))
|
result = func_timeout(2.5, sleepFunction, args=(5, 13))
|
||||||
except FunctionTimedOut as te:
|
except FunctionTimedOut as te:
|
||||||
raise AssertionError('Got unexpected timeout at 1.5 second timeout for 1.25 second function: %s' %(str(te),))
|
raise AssertionError('Got unexpected timeout at 2.5 second timeout for 2.00 second function: %s' %(str(te),))
|
||||||
|
|
||||||
assert result == expectedResult , 'Got wrong return from func_timeout.\nGot: %s\nExpected: %s\n' %(repr(result), repr(expectedResult))
|
assert result == expectedResult , 'Got wrong return from func_timeout.\nGot: %s\nExpected: %s\n' %(repr(result), repr(expectedResult))
|
||||||
|
|
||||||
@ -51,16 +51,16 @@ class TestBasic(object):
|
|||||||
assert gotException , 'Expected to get FunctionTimedOut exception for 1.25 sec function at 1s timeout'
|
assert gotException , 'Expected to get FunctionTimedOut exception for 1.25 sec function at 1s timeout'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = func_timeout(1.5, sleepFunction, args=(5,), kwargs={ 'b' : 13})
|
result = func_timeout(2.5, sleepFunction, args=(5,), kwargs={ 'b' : 13})
|
||||||
except FunctionTimedOut as te:
|
except FunctionTimedOut as te:
|
||||||
raise AssertionError('Got unexpected timeout at 1.5 second timeout for 1.25 second function: %s' %(str(te), ))
|
raise AssertionError('Got unexpected timeout at 2.5 second timeout for 2.00 second function: %s' %(str(te), ))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise AssertionError('Got unknown exception mixing args and kwargs: < %s > %s' %(e.__class__.__name__, str(e)))
|
raise AssertionError('Got unknown exception mixing args and kwargs: < %s > %s' %(e.__class__.__name__, str(e)))
|
||||||
|
|
||||||
assert result == expectedResult , 'Got wrong result when mixing args and kwargs'
|
assert result == expectedResult , 'Got wrong result when mixing args and kwargs'
|
||||||
|
|
||||||
def test_retry(self):
|
def test_retry(self):
|
||||||
sleepFunction = getSleepLambda(.5)
|
sleepFunction = getSleepLambda(1.2)
|
||||||
|
|
||||||
expectedResult = 5 + 19
|
expectedResult = 5 + 19
|
||||||
|
|
||||||
@ -69,14 +69,14 @@ class TestBasic(object):
|
|||||||
|
|
||||||
startTime = time.time()
|
startTime = time.time()
|
||||||
try:
|
try:
|
||||||
result = func_timeout(.3, sleepFunction, args=(5, 19))
|
result = func_timeout(.8, sleepFunction, args=(5, 19))
|
||||||
except FunctionTimedOut as fte:
|
except FunctionTimedOut as fte:
|
||||||
functionTimedOut = fte
|
functionTimedOut = fte
|
||||||
gotException = True
|
gotException = True
|
||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert gotException , 'Expected to get exception'
|
assert gotException , 'Expected to get exception'
|
||||||
assert compareTimes(endTime, startTime, .3, 3, None, .10) == 0 , 'Expected to wait .3 seconds. Was: %f - %f = %f' %(endTime, startTime, round(endTime - startTime, 3))
|
assert compareTimes(endTime, startTime, .8, 3, deltaFixed=.15) == 0 , 'Expected to wait .8 seconds. Was: %f - %f = %f' %(endTime, startTime, round(endTime - startTime, 3))
|
||||||
|
|
||||||
gotException = False
|
gotException = False
|
||||||
startTime = time.time()
|
startTime = time.time()
|
||||||
@ -87,7 +87,7 @@ class TestBasic(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert gotException , 'Expected to get exception on retry.'
|
assert gotException , 'Expected to get exception on retry.'
|
||||||
assert compareTimes(endTime, startTime, .3, 3, None, .10) == 0 , 'Expected retry with no arguments to use same timeout of .3'
|
assert compareTimes(endTime, startTime, .8, 3, deltaFixed=.15) == 0 , 'Expected retry with no arguments to use same timeout of .8'
|
||||||
|
|
||||||
gotException = False
|
gotException = False
|
||||||
startTime = time.time()
|
startTime = time.time()
|
||||||
@ -98,19 +98,19 @@ class TestBasic(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert not gotException , 'Did NOT to get exception with no timeout'
|
assert not gotException , 'Did NOT to get exception with no timeout'
|
||||||
assert compareTimes(endTime, startTime, .5, 3, None, .10) == 0 , 'Expected retry with None as timeout to last full length of function'
|
assert compareTimes(endTime, startTime, 1.2, 3, deltaFixed=.15) == 0 , 'Expected retry with None as timeout to last full length of function'
|
||||||
|
|
||||||
gotException = False
|
gotException = False
|
||||||
startTime = time.time()
|
startTime = time.time()
|
||||||
try:
|
try:
|
||||||
result = functionTimedOut.retry(.4)
|
result = functionTimedOut.retry(.55)
|
||||||
except FunctionTimedOut:
|
except FunctionTimedOut:
|
||||||
gotException = True
|
gotException = True
|
||||||
finally:
|
finally:
|
||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert gotException , 'Expected to time out after .4 seconds when providing .4'
|
assert gotException , 'Expected to time out after .55 seconds when providing .55'
|
||||||
assert compareTimes(endTime, startTime, .4, 3, .05, None) == 0 , 'Expected providing .4 would allow timeout of up to .4 seconds'
|
assert compareTimes(endTime, startTime, .55, 3, deltaFixed=.15) == 0 , 'Expected providing .55 would allow timeout of up to .55 seconds'
|
||||||
|
|
||||||
threadsCleanedUp = False
|
threadsCleanedUp = False
|
||||||
|
|
||||||
@ -122,11 +122,11 @@ class TestBasic(object):
|
|||||||
threadsCleanedUp = True
|
threadsCleanedUp = True
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
assert threadsCleanedUp , 'Expected other threads to get cleaned up after gc collection'
|
assert threadsCleanedUp , 'Expected other threads to get cleaned up after gc collection'
|
||||||
|
|
||||||
def test_exception(self):
|
def test_exception(self):
|
||||||
sleepFunction = getSleepLambda(.5)
|
sleepFunction = getSleepLambda(.85)
|
||||||
|
|
||||||
expectedResult = 5 + 19
|
expectedResult = 5 + 19
|
||||||
|
|
||||||
@ -135,7 +135,7 @@ class TestBasic(object):
|
|||||||
|
|
||||||
startTime = time.time()
|
startTime = time.time()
|
||||||
try:
|
try:
|
||||||
result = func_timeout(.3, sleepFunction, args=(5, 19))
|
result = func_timeout(.5, sleepFunction, args=(5, 19))
|
||||||
except FunctionTimedOut as fte:
|
except FunctionTimedOut as fte:
|
||||||
functionTimedOut = fte
|
functionTimedOut = fte
|
||||||
gotException = True
|
gotException = True
|
||||||
@ -144,14 +144,43 @@ class TestBasic(object):
|
|||||||
assert gotException , 'Expected to get exception'
|
assert gotException , 'Expected to get exception'
|
||||||
|
|
||||||
assert 'timed out after ' in functionTimedOut.msg , 'Expected message to be constructed. Got: %s' %(repr(functionTimedOut.msg), )
|
assert 'timed out after ' in functionTimedOut.msg , 'Expected message to be constructed. Got: %s' %(repr(functionTimedOut.msg), )
|
||||||
assert round(functionTimedOut.timedOutAfter, 1) == .3 , 'Expected timedOutAfter to equal timeout ( .3 ). Got: %s' %(str(round(functionTimedOut.timedOutAfter, 1)), )
|
assert round(functionTimedOut.timedOutAfter, 1) == .5 , 'Expected timedOutAfter to equal timeout ( .5 ). Got: %s' %(str(round(functionTimedOut.timedOutAfter, 1)), )
|
||||||
assert functionTimedOut.timedOutFunction == sleepFunction , 'Expected timedOutFunction to equal sleepFunction'
|
assert functionTimedOut.timedOutFunction == sleepFunction , 'Expected timedOutFunction to equal sleepFunction'
|
||||||
assert functionTimedOut.timedOutArgs == (5, 19) , 'Expected args to equal (5, 19)'
|
assert functionTimedOut.timedOutArgs == (5, 19) , 'Expected args to equal (5, 19)'
|
||||||
assert functionTimedOut.timedOutKwargs == {} , 'Expected timedOutKwargs to equal {}'
|
assert functionTimedOut.timedOutKwargs == {} , 'Expected timedOutKwargs to equal {}'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_instantiateExceptionNoArgs(self):
|
||||||
|
|
||||||
|
gotException = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
exc = FunctionTimedOut()
|
||||||
|
msg = str(exc)
|
||||||
|
msg2 = exc.getMsg()
|
||||||
|
|
||||||
|
except Exception as _e:
|
||||||
|
sys.stderr.write('Got unexpected exception in test_instantiateExceptionNoArgs with no arguments. %s %s\n\n' %(str(type(_e)), str(_e)))
|
||||||
|
gotException = True
|
||||||
|
|
||||||
|
assert gotException is False, 'Expected to be able to create FunctionTimedOut exception without arguments.'
|
||||||
|
|
||||||
|
gotException = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
exc = FunctionTimedOut('test')
|
||||||
|
msg = str(exc)
|
||||||
|
msg2 = str(exc.getMsg())
|
||||||
|
|
||||||
|
except Exception as _e:
|
||||||
|
sys.stderr.write('Got unexpected exception in test_instantiateExceptionNoArgs with fixed message string. %s %s\n\n' %(str(type(_e)), str(_e)))
|
||||||
|
gotException = True
|
||||||
|
|
||||||
|
assert gotException is False , 'Expected to be able to create a FunctionTimedOut exception with a fixed message.'
|
||||||
|
|
||||||
|
# Other forms (providing the function name) are tested elsewhere.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.exit(subprocess.Popen('GoodTests.py -n1 "%s" %s' %(sys.argv[0], ' '.join(['"%s"' %(arg.replace('"', '\\"'), ) for arg in sys.argv[1:]]) ), shell=True).wait())
|
sys.exit(subprocess.Popen('GoodTests.py -n1 "%s" %s' %(sys.argv[0], ' '.join(['"%s"' %(arg.replace('"', '\\"'), ) for arg in sys.argv[1:]]) ), shell=True).wait())
|
||||||
|
|||||||
@ -19,7 +19,7 @@ from func_timeout import func_timeout, FunctionTimedOut, func_set_timeout
|
|||||||
|
|
||||||
from TestUtils import ARG_NO_DEFAULT, getSleepLambda, getSleepLambdaWithArgs, compareTimes
|
from TestUtils import ARG_NO_DEFAULT, getSleepLambda, getSleepLambdaWithArgs, compareTimes
|
||||||
|
|
||||||
SLEEP_TIME = .5
|
SLEEP_TIME = 1.25
|
||||||
|
|
||||||
def doSleep(a, b):
|
def doSleep(a, b):
|
||||||
time.sleep(a)
|
time.sleep(a)
|
||||||
@ -52,7 +52,7 @@ class TestDecorator(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert gotException , 'Expected to get exception at sleep time'
|
assert gotException , 'Expected to get exception at sleep time'
|
||||||
assert compareTimes(endTime, startTime, SLEEP_TIME, None, .1) == 0 , 'Expected to sleep up to sleep time'
|
assert compareTimes(endTime, startTime, SLEEP_TIME, None, deltaFixed=.15) == 0 , 'Expected to sleep up to sleep time'
|
||||||
|
|
||||||
expected = SLEEP_TIME * .8 + 4
|
expected = SLEEP_TIME * .8 + 4
|
||||||
gotException = False
|
gotException = False
|
||||||
@ -64,7 +64,7 @@ class TestDecorator(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert not gotException , 'Expected not to get exception at 80% sleep time'
|
assert not gotException , 'Expected not to get exception at 80% sleep time'
|
||||||
assert compareTimes(endTime, startTime, SLEEP_TIME * .8, None, .1) == 0 , 'Expected to only sleep for 80% of sleep time'
|
assert compareTimes(endTime, startTime, SLEEP_TIME * .8, None, deltaFixed=.15) == 0 , 'Expected to only sleep for 80% of sleep time'
|
||||||
assert result == expected , 'Got wrong result'
|
assert result == expected , 'Got wrong result'
|
||||||
|
|
||||||
def test_funcSetTimeoutOverride(self):
|
def test_funcSetTimeoutOverride(self):
|
||||||
@ -85,7 +85,7 @@ class TestDecorator(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert gotException , 'Expected to get exception at 130% sleep time'
|
assert gotException , 'Expected to get exception at 130% sleep time'
|
||||||
assert compareTimes(endTime, startTime, SLEEP_TIME * 1.2, None, .1) == 0 , 'Expected to sleep up to 120% of sleep time'
|
assert compareTimes(endTime, startTime, SLEEP_TIME * 1.2, None, deltaFixed=.15) == 0 , 'Expected to sleep up to 120% of sleep time'
|
||||||
|
|
||||||
@func_set_timeout(SLEEP_TIME, allowOverride=False)
|
@func_set_timeout(SLEEP_TIME, allowOverride=False)
|
||||||
def doSleepFuncNoOverride(a, b):
|
def doSleepFuncNoOverride(a, b):
|
||||||
@ -113,7 +113,7 @@ class TestDecorator(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert not gotException , 'Expected not to get exception with forced 115% sleep time'
|
assert not gotException , 'Expected not to get exception with forced 115% sleep time'
|
||||||
assert compareTimes(endTime, startTime, SLEEP_TIME, None, .1) == 0 , 'Expected to sleep for SLEEP_TIME'
|
assert compareTimes(endTime, startTime, SLEEP_TIME, None, deltaFixed=.15) == 0 , 'Expected to sleep for SLEEP_TIME'
|
||||||
assert result == expected , 'Got wrong result'
|
assert result == expected , 'Got wrong result'
|
||||||
|
|
||||||
def test_funcSetTimeCalculate(self):
|
def test_funcSetTimeCalculate(self):
|
||||||
@ -145,7 +145,7 @@ class TestDecorator(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert not gotException , 'Expected not to get exception with calculated 120% timeout on sleep time'
|
assert not gotException , 'Expected not to get exception with calculated 120% timeout on sleep time'
|
||||||
assert compareTimes(endTime, startTime, SLEEP_TIME, None, .1) == 0 , 'Expected to sleep for SLEEP_TIME'
|
assert compareTimes(endTime, startTime, SLEEP_TIME, None, deltaFixed=.15) == 0 , 'Expected to sleep for SLEEP_TIME'
|
||||||
assert result == expected , 'Got wrong result'
|
assert result == expected , 'Got wrong result'
|
||||||
|
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ class TestDecorator(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert gotException , 'Expected to get exception with calculated 80% timeout on sleep time'
|
assert gotException , 'Expected to get exception with calculated 80% timeout on sleep time'
|
||||||
assert compareTimes(endTime, startTime, SLEEP_TIME * .8, None, .1) == 0 , 'Expected to sleep for 80% SLEEP_TIME'
|
assert compareTimes(endTime, startTime, SLEEP_TIME * .8, None, deltaFixed=.15) == 0 , 'Expected to sleep for 80% SLEEP_TIME'
|
||||||
|
|
||||||
@func_set_timeout(calculateSleepOverArgs, allowOverride=False)
|
@func_set_timeout(calculateSleepOverArgs, allowOverride=False)
|
||||||
def doSleepFuncOverArgs(a, b):
|
def doSleepFuncOverArgs(a, b):
|
||||||
@ -181,7 +181,7 @@ class TestDecorator(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert not gotException , 'Expected not to get exception with calculated 120% timeout on sleep time using *args'
|
assert not gotException , 'Expected not to get exception with calculated 120% timeout on sleep time using *args'
|
||||||
assert compareTimes(endTime, startTime, SLEEP_TIME, None, .1) == 0 , 'Expected to sleep for SLEEP_TIME using *args'
|
assert compareTimes(endTime, startTime, SLEEP_TIME, None, deltaFixed=.15) == 0 , 'Expected to sleep for SLEEP_TIME using *args'
|
||||||
assert result == expected , 'Got wrong result'
|
assert result == expected , 'Got wrong result'
|
||||||
|
|
||||||
@func_set_timeout(calculateSleepUnderArgs, allowOverride=False)
|
@func_set_timeout(calculateSleepUnderArgs, allowOverride=False)
|
||||||
@ -199,7 +199,7 @@ class TestDecorator(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert gotException , 'Expected to get exception with calculated 80% timeout on sleep time using *args'
|
assert gotException , 'Expected to get exception with calculated 80% timeout on sleep time using *args'
|
||||||
assert compareTimes(endTime, startTime, SLEEP_TIME * .8, None, .1) == 0 , 'Expected to sleep for 80% SLEEP_TIME using *args'
|
assert compareTimes(endTime, startTime, SLEEP_TIME * .8, None, deltaFixed=.15) == 0 , 'Expected to sleep for 80% SLEEP_TIME using *args'
|
||||||
|
|
||||||
|
|
||||||
def test_funcSetTimeCalculateWithOverride(self):
|
def test_funcSetTimeCalculateWithOverride(self):
|
||||||
@ -231,7 +231,7 @@ class TestDecorator(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert not gotException , 'Expected not to get exception with calculated 120% timeout on sleep time'
|
assert not gotException , 'Expected not to get exception with calculated 120% timeout on sleep time'
|
||||||
assert compareTimes(endTime, startTime, SLEEP_TIME, None, .1) == 0 , 'Expected to sleep for SLEEP_TIME'
|
assert compareTimes(endTime, startTime, SLEEP_TIME, None, deltaFixed=.15) == 0 , 'Expected to sleep for SLEEP_TIME'
|
||||||
assert result == expected , 'Got wrong result'
|
assert result == expected , 'Got wrong result'
|
||||||
|
|
||||||
expected = SLEEP_TIME + 4
|
expected = SLEEP_TIME + 4
|
||||||
@ -244,7 +244,7 @@ class TestDecorator(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert not gotException , 'Expected not to get exception with calculated 120% timeout on sleep time but 150% timeout on override'
|
assert not gotException , 'Expected not to get exception with calculated 120% timeout on sleep time but 150% timeout on override'
|
||||||
assert compareTimes(endTime, startTime, SLEEP_TIME, None, .1) == 0 , 'Expected to sleep for SLEEP_TIME with 150% timeout on override'
|
assert compareTimes(endTime, startTime, SLEEP_TIME, None, deltaFixed=.15) == 0 , 'Expected to sleep for SLEEP_TIME with 150% timeout on override'
|
||||||
assert result == expected , 'Got wrong result'
|
assert result == expected , 'Got wrong result'
|
||||||
|
|
||||||
|
|
||||||
@ -258,7 +258,7 @@ class TestDecorator(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert gotException , 'Expected to get exception with calculated 120% timeout on sleep time but 70% timeout on override'
|
assert gotException , 'Expected to get exception with calculated 120% timeout on sleep time but 70% timeout on override'
|
||||||
assert compareTimes(endTime, startTime, SLEEP_TIME * .7, None, .1) == 0 , 'Expected to sleep for 70% SLEEP_TIME with 70% timeout on override'
|
assert compareTimes(endTime, startTime, SLEEP_TIME * .7, None, deltaFixed=.15) == 0 , 'Expected to sleep for 70% SLEEP_TIME with 70% timeout on override'
|
||||||
|
|
||||||
|
|
||||||
@func_set_timeout(calculateSleepUnder, allowOverride=True)
|
@func_set_timeout(calculateSleepUnder, allowOverride=True)
|
||||||
@ -276,7 +276,7 @@ class TestDecorator(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert gotException , 'Expected to get exception with calculated 80% timeout on sleep time'
|
assert gotException , 'Expected to get exception with calculated 80% timeout on sleep time'
|
||||||
assert compareTimes(endTime, startTime, SLEEP_TIME * .8, None, .1) == 0 , 'Expected to sleep for 80% SLEEP_TIME'
|
assert compareTimes(endTime, startTime, SLEEP_TIME * .8, None, deltaFixed=.15) == 0 , 'Expected to sleep for 80% SLEEP_TIME'
|
||||||
|
|
||||||
expected = SLEEP_TIME + 4
|
expected = SLEEP_TIME + 4
|
||||||
gotException = False
|
gotException = False
|
||||||
@ -288,7 +288,7 @@ class TestDecorator(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert not gotException , 'Expected not to get exception with calculated 80% timeout on sleep time but 120% timeout on override'
|
assert not gotException , 'Expected not to get exception with calculated 80% timeout on sleep time but 120% timeout on override'
|
||||||
assert compareTimes(endTime, startTime, SLEEP_TIME , None, .1) == 0 , 'Expected to sleep for SLEEP_TIME with 120% timeout on override'
|
assert compareTimes(endTime, startTime, SLEEP_TIME , None, deltaFixed=.15) == 0 , 'Expected to sleep for SLEEP_TIME with 120% timeout on override'
|
||||||
|
|
||||||
|
|
||||||
def test_setFuncTimeoutetry(self):
|
def test_setFuncTimeoutetry(self):
|
||||||
@ -322,7 +322,7 @@ class TestDecorator(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert gotException , 'Expected to get exception with calculated 80% timeout'
|
assert gotException , 'Expected to get exception with calculated 80% timeout'
|
||||||
assert compareTimes(endTime, startTime, SLEEP_TIME * .8, None, .1) == 0 , 'Expected to sleep for 80% SLEEP_TIME with 80% timeout'
|
assert compareTimes(endTime, startTime, SLEEP_TIME * .8, None, deltaFixed=.15) == 0 , 'Expected to sleep for 80% SLEEP_TIME with 80% timeout'
|
||||||
|
|
||||||
gotException = False
|
gotException = False
|
||||||
startTime = time.time()
|
startTime = time.time()
|
||||||
@ -335,7 +335,7 @@ class TestDecorator(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert gotException , 'Expected to get exception with calculated same 80% timeout on retry'
|
assert gotException , 'Expected to get exception with calculated same 80% timeout on retry'
|
||||||
assert compareTimes(endTime, startTime, SLEEP_TIME * .8, None, .1) == 0 , 'Expected to sleep for 80% SLEEP_TIME with same 80% timeout on retry'
|
assert compareTimes(endTime, startTime, SLEEP_TIME * .8, None, deltaFixed=.15) == 0 , 'Expected to sleep for 80% SLEEP_TIME with same 80% timeout on retry'
|
||||||
|
|
||||||
result = None
|
result = None
|
||||||
gotException = False
|
gotException = False
|
||||||
@ -349,7 +349,7 @@ class TestDecorator(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert not gotException , 'Expected to get exception with calculated 80% timeout on retry ( None ) [ No timeout ]'
|
assert not gotException , 'Expected to get exception with calculated 80% timeout on retry ( None ) [ No timeout ]'
|
||||||
assert compareTimes(endTime, startTime, SLEEP_TIME, None, .1) == 0 , 'Expected to sleep for 100% SLEEP_TIME with 80% timeout overriden on retry ( None ) [ No timeout ]'
|
assert compareTimes(endTime, startTime, SLEEP_TIME, None, deltaFixed=.15) == 0 , 'Expected to sleep for 100% SLEEP_TIME with 80% timeout overriden on retry ( None ) [ No timeout ]'
|
||||||
assert result == expected , 'Got wrong result'
|
assert result == expected , 'Got wrong result'
|
||||||
|
|
||||||
|
|
||||||
@ -365,7 +365,7 @@ class TestDecorator(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert gotException , 'Expected to get exception with calculated 80% timeout overriden by 60% timeout on retry'
|
assert gotException , 'Expected to get exception with calculated 80% timeout overriden by 60% timeout on retry'
|
||||||
assert compareTimes(endTime, startTime, SLEEP_TIME * .6, None, .1) == 0 , 'Expected to sleep for 60% SLEEP_TIME with 80% timeout overriden on retry ( SLEEP_TIME * .6 ) [ 60% timeout ]'
|
assert compareTimes(endTime, startTime, SLEEP_TIME * .6, None, deltaFixed=.15) == 0 , 'Expected to sleep for 60% SLEEP_TIME with 80% timeout overriden on retry ( SLEEP_TIME * .6 ) [ 60% timeout ]'
|
||||||
|
|
||||||
result = None
|
result = None
|
||||||
gotException = False
|
gotException = False
|
||||||
@ -379,7 +379,7 @@ class TestDecorator(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert not gotException , 'Expected to get exception with calculated 80% timeout overriden by 150% timeout on retry'
|
assert not gotException , 'Expected to get exception with calculated 80% timeout overriden by 150% timeout on retry'
|
||||||
assert compareTimes(endTime, startTime, SLEEP_TIME , None, .1) == 0 , 'Expected to sleep for 100% SLEEP_TIME with 80% timeout overriden on retry ( SLEEP_TIME * 1.5 ) [ 150% timeout ]'
|
assert compareTimes(endTime, startTime, SLEEP_TIME , None, deltaFixed=.15) == 0 , 'Expected to sleep for 100% SLEEP_TIME with 80% timeout overriden on retry ( SLEEP_TIME * 1.5 ) [ 150% timeout ]'
|
||||||
assert result == expected
|
assert result == expected
|
||||||
|
|
||||||
threadsCleanedUp = False
|
threadsCleanedUp = False
|
||||||
|
|||||||
@ -35,7 +35,7 @@ class TestBasicSleepWithArgs(object):
|
|||||||
raise AssertionError('Expected to have 1 default arg and 2 standard. Tried 3 args')
|
raise AssertionError('Expected to have 1 default arg and 2 standard. Tried 3 args')
|
||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert compareTimes(endTime, startTime, 2, 2, deltaFixed=.1, deltaPct=None) == 0 , 'Expected getSleepLambdaWithArgs(2) to take 2 seconds.'
|
assert compareTimes(endTime, startTime, 2, 2, deltaFixed=.15, deltaPct=None) == 0 , 'Expected getSleepLambdaWithArgs(2) to take 2 seconds.'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sleepLambda(4, 7, 12)
|
sleepLambda(4, 7, 12)
|
||||||
@ -54,7 +54,7 @@ class TestBasicSleepWithArgs(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert result == expectedResult , 'Got wrong result'
|
assert result == expectedResult , 'Got wrong result'
|
||||||
assert compareTimes(endTime, startTime, 1.75, 2, deltaFixed=.1, deltaPct=None) == 0 , 'Expected getSleepLambdaWithArgs(1.75) to take 1.75 seconds.'
|
assert compareTimes(endTime, startTime, 1.75, 2, deltaFixed=.15, deltaPct=None) == 0 , 'Expected getSleepLambdaWithArgs(1.75) to take 1.75 seconds.'
|
||||||
|
|
||||||
expectedResult = 5 + 13
|
expectedResult = 5 + 13
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ class TestBasicSleepWithArgs(object):
|
|||||||
endTime = time.time()
|
endTime = time.time()
|
||||||
|
|
||||||
assert result == expectedResult , 'Did not get return from sleepFunction'
|
assert result == expectedResult , 'Did not get return from sleepFunction'
|
||||||
assert compareTimes(endTime, startTime, 1.75, 2, deltaFixed=.1, deltaPct=None) == 0 , 'Expected getSleepLambda(1.75) to take 1.75 seconds.'
|
assert compareTimes(endTime, startTime, 1.75, 2, deltaFixed=.15, deltaPct=None) == 0 , 'Expected getSleepLambda(1.75) to take 1.75 seconds.'
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.exit(subprocess.Popen('GoodTests.py -n1 "%s" %s' %(sys.argv[0], ' '.join(['"%s"' %(arg.replace('"', '\\"'), ) for arg in sys.argv[1:]]) ), shell=True).wait())
|
sys.exit(subprocess.Popen('GoodTests.py -n1 "%s" %s' %(sys.argv[0], ' '.join(['"%s"' %(arg.replace('"', '\\"'), ) for arg in sys.argv[1:]]) ), shell=True).wait())
|
||||||
|
|||||||
@ -12,7 +12,62 @@
|
|||||||
# NOTE: Since version 1.2.3, you can also import this (like from a graphical application) and call the "main()" function.
|
# NOTE: Since version 1.2.3, you can also import this (like from a graphical application) and call the "main()" function.
|
||||||
# All of the following globals are the defaults, but can be overridden when calling main() (params have the same name as the globals).
|
# All of the following globals are the defaults, but can be overridden when calling main() (params have the same name as the globals).
|
||||||
|
|
||||||
import imp
|
# Assign a local function, "find_mod" to the interface to search
|
||||||
|
# PYTHONPATH for importable module
|
||||||
|
try:
|
||||||
|
# imp.find_module has been deprecated as of python 3.7, so
|
||||||
|
# prefer some alternate/newer interfaces first.
|
||||||
|
import importlib
|
||||||
|
|
||||||
|
try:
|
||||||
|
# If we have the newest and therefore least-deprecated
|
||||||
|
# way, use it.
|
||||||
|
_findModSpec = importlib.util.find_spec
|
||||||
|
def find_mod(modName):
|
||||||
|
'''
|
||||||
|
find_mod - Find a module by name.
|
||||||
|
|
||||||
|
Similar to import #modName but only finds importable module,
|
||||||
|
does not actually import.
|
||||||
|
|
||||||
|
@raises ImportError on failure
|
||||||
|
'''
|
||||||
|
modSpec = _findModSpec(modName)
|
||||||
|
if not modSpec:
|
||||||
|
# imp.find_module raises import error if cannot find,
|
||||||
|
# but find_spec just returns None
|
||||||
|
# So simulate the ImportError for common interface
|
||||||
|
raise ImportError('No module named %s' %(modName, ))
|
||||||
|
|
||||||
|
return modSpec
|
||||||
|
|
||||||
|
except AttributeError:
|
||||||
|
# We have importlib, but don't have importlib.util.find_spec
|
||||||
|
|
||||||
|
# We could use importlib.import_module which is present in
|
||||||
|
# python 2.7, but that changes behaviour by actually
|
||||||
|
# importing (and thus additionally checking syntax/other).
|
||||||
|
#
|
||||||
|
# So just fall back to the old imp.find_module in this case
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Clean up namespace
|
||||||
|
del importlib
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
# Fall back to imp.find_module implementation below
|
||||||
|
raise ImportError('importlib but no importlib.util')
|
||||||
|
#find_mod = lambda modName : importlib.import_module(modName)
|
||||||
|
|
||||||
|
except:
|
||||||
|
# importlib is not present or has an unknown/dated interface,
|
||||||
|
# so fallback to the deprecated but oldest form
|
||||||
|
import imp
|
||||||
|
|
||||||
|
# Use a lambda to ensure only one arg is passed as that is
|
||||||
|
# our standard interface
|
||||||
|
find_mod = lambda modName : imp.find_module(modName)
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import subprocess
|
import subprocess
|
||||||
@ -32,8 +87,8 @@ ALLOW_SITE_INSTALL = False
|
|||||||
# This is the test directory that should contain all your tests. This should be a directory in your "tests" folder
|
# This is the test directory that should contain all your tests. This should be a directory in your "tests" folder
|
||||||
MY_TEST_DIRECTORY = 'FuncTimeoutTests'
|
MY_TEST_DIRECTORY = 'FuncTimeoutTests'
|
||||||
|
|
||||||
__version__ = '2.1.1'
|
__version__ = '3.0.5'
|
||||||
__version_tuple__ = (2, 1, 1)
|
__version_tuple__ = (3, 0, 5)
|
||||||
|
|
||||||
def findGoodTests():
|
def findGoodTests():
|
||||||
'''
|
'''
|
||||||
@ -65,8 +120,83 @@ def findGoodTests():
|
|||||||
"success" : success
|
"success" : success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def findExecutable(execName):
|
||||||
|
'''
|
||||||
|
findExecutable - Search PATH for an executable
|
||||||
|
|
||||||
|
@return <dict> {
|
||||||
|
'path' <str> -> Path to executable (if found, see "success")
|
||||||
|
'success' <bool> -> True/False if we successfully found requested executable
|
||||||
|
}
|
||||||
|
'''
|
||||||
|
|
||||||
|
pathSplit = os.environ['PATH'].split(':')
|
||||||
|
if '.' not in pathSplit:
|
||||||
|
pathSplit = ['.'] + pathSplit
|
||||||
|
os.environ['PATH'] = ':'.join(pathSplit)
|
||||||
|
|
||||||
|
result = ''
|
||||||
|
success = False
|
||||||
|
for path in pathSplit:
|
||||||
|
if path.endswith(os.sep):
|
||||||
|
path = path[:-1]
|
||||||
|
guess = path + os.sep + execName
|
||||||
|
if os.path.exists(guess):
|
||||||
|
success = True
|
||||||
|
result = guess
|
||||||
|
break
|
||||||
|
|
||||||
|
return {
|
||||||
|
"path" : result,
|
||||||
|
"success" : success
|
||||||
|
}
|
||||||
|
|
||||||
|
def findGoodTests():
|
||||||
|
return findExecutable('GoodTests.py')
|
||||||
|
|
||||||
|
|
||||||
def try_pip_install():
|
def try_pip_install():
|
||||||
pipe = subprocess.Popen('pip install GoodTests', shell=True)
|
'''
|
||||||
|
try to pip install GoodTests.py
|
||||||
|
|
||||||
|
First, try via pip module.
|
||||||
|
|
||||||
|
If that fails, try to locate pip by dirname(current python executable) + os.sep + pip
|
||||||
|
If that does not exist, scan PATH for pip
|
||||||
|
|
||||||
|
If found a valid pip executable, invoke it to install GoodTests
|
||||||
|
otherwise, fail.
|
||||||
|
'''
|
||||||
|
|
||||||
|
didImport = False
|
||||||
|
try:
|
||||||
|
import pip
|
||||||
|
didImport = True
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if didImport is True:
|
||||||
|
print ( "Found pip as module=pip")
|
||||||
|
res = pip.main(['install', 'GoodTests'])
|
||||||
|
if res == 0:
|
||||||
|
return 0
|
||||||
|
sys.stderr.write('Failed to install GoodTests via pip module. Falling back to pip executable...\n\n')
|
||||||
|
|
||||||
|
pipPath = os.path.dirname(sys.executable) + os.sep + 'pip'
|
||||||
|
print ( 'Searching for pip at "%s"' %(pipPath, ) )
|
||||||
|
if not os.path.exists(pipPath):
|
||||||
|
print ( '"%s" does not exist. Scanning PATH to locate a usable pip executable' %(pipPath, ))
|
||||||
|
pipPath = None
|
||||||
|
searchResults = findExecutable('pip')
|
||||||
|
if not searchResults['success']:
|
||||||
|
sys.stderr.write('Failed to find a usable pip executable in PATH.\n')
|
||||||
|
return 1 # Failed to locate a usable pip
|
||||||
|
|
||||||
|
pipPath = searchResults['path']
|
||||||
|
|
||||||
|
print ( 'Found pip executable at "%s"' %(pipPath, ) )
|
||||||
|
print ( "Executing: %s %s 'install' 'GoodTests'" %(sys.executable, pipPath) )
|
||||||
|
pipe = subprocess.Popen([sys.executable, pipPath, 'install', 'GoodTests'], shell=False, env=os.environ)
|
||||||
res = pipe.wait()
|
res = pipe.wait()
|
||||||
|
|
||||||
return res
|
return res
|
||||||
@ -195,7 +325,7 @@ def main(thisDir=None, additionalArgs=[], MY_PACKAGE_MODULE=None, ALLOW_SITE_INS
|
|||||||
elif dirName == '':
|
elif dirName == '':
|
||||||
inCurrentDir = False
|
inCurrentDir = False
|
||||||
try:
|
try:
|
||||||
imp.find_module(MY_PACKAGE_MODULE)
|
find_mod(MY_PACKAGE_MODULE)
|
||||||
inCurrentDir = True
|
inCurrentDir = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
# COMPAT WITH PREVIOUS runTests.py: Try plain module in parent directory
|
# COMPAT WITH PREVIOUS runTests.py: Try plain module in parent directory
|
||||||
@ -203,7 +333,7 @@ def main(thisDir=None, additionalArgs=[], MY_PACKAGE_MODULE=None, ALLOW_SITE_INS
|
|||||||
oldSysPath = sys.path[:]
|
oldSysPath = sys.path[:]
|
||||||
sys.path = [os.path.realpath(os.getcwd() + os.sep + '..' + os.sep)]
|
sys.path = [os.path.realpath(os.getcwd() + os.sep + '..' + os.sep)]
|
||||||
try:
|
try:
|
||||||
imp.find_module(MY_PACKAGE_MODULE)
|
find_mod(MY_PACKAGE_MODULE)
|
||||||
foundIt = True
|
foundIt = True
|
||||||
sys.path = oldSysPath
|
sys.path = oldSysPath
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
@ -234,8 +364,15 @@ def main(thisDir=None, additionalArgs=[], MY_PACKAGE_MODULE=None, ALLOW_SITE_INS
|
|||||||
if baseName.endswith(('.py', '.pyc', '.pyo')):
|
if baseName.endswith(('.py', '.pyc', '.pyo')):
|
||||||
MY_PACKAGE_MODULE = baseName[ : baseName.rindex('.')]
|
MY_PACKAGE_MODULE = baseName[ : baseName.rindex('.')]
|
||||||
|
|
||||||
if e.name != MY_PACKAGE_MODULE:
|
try:
|
||||||
sys.stderr.write('Error while importing %s: %s\n Likely this is another dependency that needs to be installed\nPerhaps run "pip install %s" or install the providing package.\n\n' %(e.name, str(e), e.name))
|
eName = e.name
|
||||||
|
except AttributeError as noNameE:
|
||||||
|
# Some platforms python2 does not have this attribute
|
||||||
|
# so pull it from the message
|
||||||
|
eName = e.message.split()[-1]
|
||||||
|
|
||||||
|
if eName != MY_PACKAGE_MODULE:
|
||||||
|
sys.stderr.write('Error while importing %s: %s\n Likely this is another dependency that needs to be installed\nPerhaps run "pip install %s" or install the providing package.\n\n' %(eName, str(e), eName))
|
||||||
return 1
|
return 1
|
||||||
sys.stderr.write('Could not import %s. Either install it or otherwise add to PYTHONPATH\n%s\n' %(MY_PACKAGE_MODULE, str(e)))
|
sys.stderr.write('Could not import %s. Either install it or otherwise add to PYTHONPATH\n%s\n' %(MY_PACKAGE_MODULE, str(e)))
|
||||||
return 1
|
return 1
|
||||||
@ -253,8 +390,7 @@ def main(thisDir=None, additionalArgs=[], MY_PACKAGE_MODULE=None, ALLOW_SITE_INS
|
|||||||
|
|
||||||
|
|
||||||
didTerminate = False
|
didTerminate = False
|
||||||
|
pipe = subprocess.Popen([sys.executable, goodTestsInfo['path']] + additionalArgs + [MY_TEST_DIRECTORY], env=os.environ, shell=False)
|
||||||
pipe = subprocess.Popen([goodTestsInfo['path']] + additionalArgs + [MY_TEST_DIRECTORY], env=os.environ, shell=False)
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
pipe.wait()
|
pipe.wait()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user