Drop python2 support, add py38 and py39

This commit is contained in:
ikkamens 2021-01-17 13:02:41 +01:00
parent 50baa8db50
commit 3c0829399c
11 changed files with 55 additions and 73 deletions

View File

@ -1,4 +1,3 @@
# vim: set ts=4 sw=4 expandtab : # vim: set ts=4 sw=4 expandtab :
''' '''
@ -9,27 +8,25 @@
''' '''
import copy import copy
import inspect
import threading
import time
import types import types
import sys import sys
from .exceptions import FunctionTimedOut from .exceptions import FunctionTimedOut
from .StoppableThread import StoppableThread from .StoppableThread import StoppableThread
try:
from .py3_raise import raise_exception
except SyntaxError:
from .py2_raise import raise_exception
except ImportError:
from .py2_raise import raise_exception
from functools import wraps from functools import wraps
__all__ = ('func_timeout', 'func_set_timeout') __all__ = ('func_timeout', 'func_set_timeout')
# PEP 409 - Raise with the chained exception context disabled
# This, in effect, prevents the "funcwrap" wrapper ( chained
# in context to an exception raised here, due to scope )
# Only available in python3.3+
def raise_exception(exception):
raise exception[0] from None
def func_timeout(timeout, func, args=(), kwargs=None): def func_timeout(timeout, func, args=(), kwargs=None):
''' '''
func_timeout - Runs the given function for up to #timeout# seconds. func_timeout - Runs the given function for up to #timeout# seconds.
@ -175,7 +172,7 @@ def func_set_timeout(timeout, allowOverride=False):
try: try:
timeout = float(timeout) timeout = float(timeout)
except: except:
raise ValueError('timeout argument must be a float/int for number of seconds, or a function/lambda which gets passed the function arguments and returns a calculated timeout (as float or int). Passed type: < %s > is not of any of these, and cannot be converted to a float.' %( timeout.__class__.__name__, )) raise ValueError(f'timeout argument must be a float/int for number of seconds, or a function/lambda which gets passed the function arguments and returns a calculated timeout (as float or int). Passed type: < {timeout.__class__.__name__} > is not of any of these, and cannot be converted to a float.')
if not allowOverride and not isTimeoutAFunction: if not allowOverride and not isTimeoutAFunction:

View File

@ -69,11 +69,11 @@ class FunctionTimedOut(BaseException):
else: else:
timedOutFuncName = 'Unknown Function' timedOutFuncName = 'Unknown Function'
if self.timedOutAfter is not None: if self.timedOutAfter is not None:
timedOutAfterStr = "%f" %(self.timedOutAfter, ) timedOutAfterStr = f"{self.timedOutAfter:f}"
else: else:
timedOutAfterStr = "Unknown" timedOutAfterStr = "Unknown"
return 'Function %s (args=%s) (kwargs=%s) timed out after %s seconds.\n' %(timedOutFuncName, repr(self.timedOutArgs), repr(self.timedOutKwargs), timedOutAfterStr) return f'Function {timedOutFuncName} (args={repr(self.timedOutArgs)}) (kwargs={repr(self.timedOutKwargs)}) timed out after {timedOutAfterStr} seconds.\n'
def retry(self, timeout=RETRY_SAME_TIMEOUT): def retry(self, timeout=RETRY_SAME_TIMEOUT):
''' '''

View File

@ -1,5 +0,0 @@
# Python2 allows specifying an alternate traceback.
def raise_exception(exception):
raise exception[0] , None , exception[0].__traceback__

View File

@ -1,7 +0,0 @@
# PEP 409 - Raise with the chained exception context disabled
# This, in effect, prevents the "funcwrap" wrapper ( chained
# in context to an exception raised here, due to scope )
# Only available in python3.3+
def raise_exception(exception):
raise exception[0] from None

View File

@ -26,11 +26,11 @@ if __name__ == '__main__':
with open('README.rst', 'rt') as f: with open('README.rst', 'rt') as f:
long_description = f.read() long_description = f.read()
except Exception as e: except Exception as e:
sys.stderr.write('Error reading from README.rst: %s\n' %(str(e),)) sys.stderr.write(f'Error reading from README.rst: {str(e)}\n')
log_description = summary log_description = summary
setup(name='func_timeout', setup(name='func_timeout',
version='4.3.5', version='4.4.0',
packages=['func_timeout'], packages=['func_timeout'],
author='Tim Savannah', author='Tim Savannah',
author_email='kata198@gmail.com', author_email='kata198@gmail.com',
@ -44,12 +44,10 @@ if __name__ == '__main__':
classifiers=['Development Status :: 5 - Production/Stable', classifiers=['Development Status :: 5 - Production/Stable',
'Programming Language :: Python', 'Programming Language :: Python',
'License :: OSI Approved :: GNU Lesser General Public License v2 (LGPLv2)', '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',
'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',
'Topic :: Software Development :: Libraries :: Python Modules' 'Topic :: Software Development :: Libraries :: Python Modules'
] ]
) )

View File

@ -17,19 +17,19 @@ def doit(howmany):
if __name__ == '__main__': if __name__ == '__main__':
print ( "Should get return value of 23:" ) print ( "Should get return value of 23:" )
print ( "\tGot Return: %s\n" %(str(func_timeout(4, doit, args=(6,))),) ) print ( f"\tGot Return: {str(func_timeout(4, doit, args=(6,)))}\n" )
print ( "\nShould time out (exception):" ) print ( "\nShould time out (exception):" )
myException = None myException = None
try: try:
print ("\tGot Return: %s\n" %(str(func_timeout(1, doit, kwargs={'howmany' : 16})),)) print (f"\tGot Return: {str(func_timeout(1, doit, kwargs={'howmany': 16}))}\n")
except FunctionTimedOut as e: except FunctionTimedOut as e:
sys.stderr.write('\tGot Exception: %s\n' %(str(e),)) sys.stderr.write(f'\tGot Exception: {str(e)}\n')
myException = e myException = e
pass pass
print ( "\nRetrying with longer timeout, should get 16+17=33:" ) print ( "\nRetrying with longer timeout, should get 16+17=33:" )
if myException is not None: if myException is not None:
print ( "\nGot: %s\n" %( str(myException.retry(2.5)), ) ) print ( f"\nGot: {str(myException.retry(2.5))}\n" )
else: else:
sys.stderr.write('Did not get exception before?\n') sys.stderr.write('Did not get exception before?\n')

View File

@ -1,4 +1,3 @@
# vim: set ts=4 sw=4 expandtab : # vim: set ts=4 sw=4 expandtab :
''' '''
@ -93,7 +92,7 @@ def getSleepLambda(sleepTime):
return eval('''lambda a, b : int(bool(time.sleep(%f))) + a + b''' %(_sleepTime,)) return eval(f'''lambda a, b : int(bool(time.sleep({_sleepTime:f}))) + a + b''')
def getSleepLambdaWithArgs(sleepTime, args): def getSleepLambdaWithArgs(sleepTime, args):
@ -145,7 +144,7 @@ def getSleepLambdaWithArgs(sleepTime, args):
# print ( 'Function is: %s' %('''lambda %s : int(bool(time.sleep(%f))) + %s''' %(argStr, sleepTime, sumStr, ) ) ) # print ( 'Function is: %s' %('''lambda %s : int(bool(time.sleep(%f))) + %s''' %(argStr, sleepTime, sumStr, ) ) )
return eval('''lambda %s : int(bool(time.sleep(%f))) + %s''' % (argStr, sleepTime, sumStr, ) ) return eval(f'''lambda {argStr} : int(bool(time.sleep({sleepTime:f}))) + {sumStr}''' )
def compareTimes(timeEnd, timeStart, cmpTime, roundTo=None, deltaFixed=.05, deltaPct=None): def compareTimes(timeEnd, timeStart, cmpTime, roundTo=None, deltaFixed=.05, deltaPct=None):

View File

@ -38,9 +38,9 @@ class TestBasic(object):
try: try:
result = func_timeout(2.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 2.5 second timeout for 2.00 second function: %s' %(str(te),)) raise AssertionError(f'Got unexpected timeout at 2.5 second timeout for 2.00 second function: {str(te)}')
assert result == expectedResult , 'Got wrong return from func_timeout.\nGot: %s\nExpected: %s\n' %(repr(result), repr(expectedResult)) assert result == expectedResult , f'Got wrong return from func_timeout.\nGot: {repr(result)}\nExpected: {repr(expectedResult)}\n'
gotException = False gotException = False
try: try:
@ -53,9 +53,9 @@ class TestBasic(object):
try: try:
result = func_timeout(2.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 2.5 second timeout for 2.00 second function: %s' %(str(te), )) raise AssertionError(f'Got unexpected timeout at 2.5 second timeout for 2.00 second function: {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(f'Got unknown exception mixing args and kwargs: < {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'
@ -76,7 +76,7 @@ class TestBasic(object):
endTime = time.time() endTime = time.time()
assert gotException , 'Expected to get exception' assert gotException , 'Expected to get exception'
assert compareTimes(endTime, startTime, .8, 3, deltaFixed=.15) == 0 , 'Expected to wait .8 seconds. Was: %f - %f = %f' %(endTime, startTime, round(endTime - startTime, 3)) assert compareTimes(endTime, startTime, .8, 3, deltaFixed=.15) == 0 , f'Expected to wait .8 seconds. Was: {endTime:f} - {startTime:f} = {round(endTime - startTime, 3):f}'
gotException = False gotException = False
startTime = time.time() startTime = time.time()
@ -143,8 +143,8 @@ 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 , f'Expected message to be constructed. Got: {repr(functionTimedOut.msg)}'
assert round(functionTimedOut.timedOutAfter, 1) == .5 , 'Expected timedOutAfter to equal timeout ( .5 ). Got: %s' %(str(round(functionTimedOut.timedOutAfter, 1)), ) assert round(functionTimedOut.timedOutAfter, 1) == .5 , f'Expected timedOutAfter to equal timeout ( .5 ). Got: {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 {}'
@ -160,7 +160,7 @@ class TestBasic(object):
msg2 = exc.getMsg() msg2 = exc.getMsg()
except Exception as _e: 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))) sys.stderr.write(f'Got unexpected exception in test_instantiateExceptionNoArgs with no arguments. {str(type(_e))} {str(_e)}\n\n')
gotException = True gotException = True
assert gotException is False, 'Expected to be able to create FunctionTimedOut exception without arguments.' assert gotException is False, 'Expected to be able to create FunctionTimedOut exception without arguments.'
@ -173,7 +173,7 @@ class TestBasic(object):
msg2 = str(exc.getMsg()) msg2 = str(exc.getMsg())
except Exception as _e: 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))) sys.stderr.write(f'Got unexpected exception in test_instantiateExceptionNoArgs with fixed message string. {str(type(_e))} {str(_e)}\n\n')
gotException = True gotException = True
assert gotException is False , 'Expected to be able to create a FunctionTimedOut exception with a fixed message.' assert gotException is False , 'Expected to be able to create a FunctionTimedOut exception with a fixed message.'

View File

@ -331,7 +331,7 @@ class TestDecorator(object):
except FunctionTimedOut as fte2: except FunctionTimedOut as fte2:
gotException = True gotException = True
except Exception as e: except Exception as e:
raise AssertionError('Got exception trying to retry with same timeout: < %s > : %s' %(e.__name__, str(e))) raise AssertionError(f'Got exception trying to retry with same timeout: < {e.__name__} > : {str(e)}')
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'
@ -345,7 +345,7 @@ class TestDecorator(object):
except FunctionTimedOut as fte2: except FunctionTimedOut as fte2:
gotException = True gotException = True
except Exception as e: except Exception as e:
raise AssertionError('Got exception trying to retry with same timeout: < %s > : %s' %(e.__name__, str(e))) raise AssertionError(f'Got exception trying to retry with same timeout: < {e.__name__} > : {str(e)}')
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 ]'
@ -361,7 +361,7 @@ class TestDecorator(object):
except FunctionTimedOut as fte2: except FunctionTimedOut as fte2:
gotException = True gotException = True
except Exception as e: except Exception as e:
raise AssertionError('Got exception trying to retry with same timeout: < %s > : %s' %(e.__name__, str(e))) raise AssertionError(f'Got exception trying to retry with same timeout: < {e.__name__} > : {str(e)}')
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'
@ -375,7 +375,7 @@ class TestDecorator(object):
except FunctionTimedOut as fte2: except FunctionTimedOut as fte2:
gotException = True gotException = True
except Exception as e: except Exception as e:
raise AssertionError('Got exception trying to retry with same timeout: < %s > : %s' %(e.__name__, str(e))) raise AssertionError(f'Got exception trying to retry with same timeout: < {e.__name__} > : {str(e)}')
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'

View File

@ -38,9 +38,9 @@ class TestBasic(object):
try: try:
result = func_timeout(1.5, sleepFunction, args=(5, 13)) result = func_timeout(1.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(f'Got unexpected timeout at 1.5 second timeout for 1.25 second function: {str(te)}')
assert result == expectedResult , 'Got wrong return from func_timeout.\nGot: %s\nExpected: %s\n' %(repr(result), repr(expectedResult)) assert result == expectedResult , f'Got wrong return from func_timeout.\nGot: {repr(result)}\nExpected: {repr(expectedResult)}\n'
gotException = False gotException = False
try: try:
@ -53,9 +53,9 @@ class TestBasic(object):
try: try:
result = func_timeout(1.5, sleepFunction, args=(5,), kwargs={ 'b' : 13}) result = func_timeout(1.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(f'Got unexpected timeout at 1.5 second timeout for 1.25 second function: {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(f'Got unknown exception mixing args and kwargs: < {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'
@ -76,7 +76,7 @@ class TestBasic(object):
endTime = time.time() endTime = time.time()
assert gotException , 'Expected to get exception' assert gotException , 'Expected to get exception'
assert compareTimes(endTime, startTime, .3, 3, .15, None) == 0 , 'Expected to wait .3 seconds. Was: %f - %f = %f' %(endTime, startTime, round(endTime - startTime, 3)) assert compareTimes(endTime, startTime, .3, 3, .15, None) == 0 , f'Expected to wait .3 seconds. Was: {endTime:f} - {startTime:f} = {round(endTime - startTime, 3):f}'
gotException = False gotException = False
startTime = time.time() startTime = time.time()
@ -143,8 +143,8 @@ 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 , f'Expected message to be constructed. Got: {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) == .3 , f'Expected timedOutAfter to equal timeout ( .3 ). Got: {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 {}'

View File

@ -37,7 +37,7 @@ try:
# imp.find_module raises import error if cannot find, # imp.find_module raises import error if cannot find,
# but find_spec just returns None # but find_spec just returns None
# So simulate the ImportError for common interface # So simulate the ImportError for common interface
raise ImportError('No module named %s' %(modName, )) raise ImportError(f'No module named {modName}')
return modSpec return modSpec
@ -183,9 +183,9 @@ def try_pip_install():
sys.stderr.write('Failed to install GoodTests via pip module. Falling back to pip executable...\n\n') 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' pipPath = os.path.dirname(sys.executable) + os.sep + 'pip'
print ( 'Searching for pip at "%s"' %(pipPath, ) ) print ( f'Searching for pip at "{pipPath}"' )
if not os.path.exists(pipPath): if not os.path.exists(pipPath):
print ( '"%s" does not exist. Scanning PATH to locate a usable pip executable' %(pipPath, )) print ( f'"{pipPath}" does not exist. Scanning PATH to locate a usable pip executable')
pipPath = None pipPath = None
searchResults = findExecutable('pip') searchResults = findExecutable('pip')
if not searchResults['success']: if not searchResults['success']:
@ -194,8 +194,8 @@ def try_pip_install():
pipPath = searchResults['path'] pipPath = searchResults['path']
print ( 'Found pip executable at "%s"' %(pipPath, ) ) print ( f'Found pip executable at "{pipPath}"' )
print ( "Executing: %s %s 'install' 'GoodTests'" %(sys.executable, pipPath) ) print ( f"Executing: {sys.executable} {pipPath} 'install' 'GoodTests'" )
pipe = subprocess.Popen([sys.executable, pipPath, 'install', 'GoodTests'], shell=False, env=os.environ) pipe = subprocess.Popen([sys.executable, pipPath, 'install', 'GoodTests'], shell=False, env=os.environ)
res = pipe.wait() res = pipe.wait()
@ -240,7 +240,7 @@ def download_goodTests(GOODTESTS_URL=None):
if str != bytes: if str != bytes:
contents = contents.decode('ascii') contents = contents.decode('ascii')
except Exception as e: except Exception as e:
sys.stderr.write('Failed to download GoodTests.py from "%s"\n%s\n' %(GOODTESTS_URL, str(e))) sys.stderr.write(f'Failed to download GoodTests.py from "{GOODTESTS_URL}"\n{str(e)}\n')
sys.stderr.write('\nTrying pip.\n') sys.stderr.write('\nTrying pip.\n')
res = try_pip_install() res = try_pip_install()
if res != 0: if res != 0:
@ -250,7 +250,7 @@ def download_goodTests(GOODTESTS_URL=None):
with open('GoodTests.py', 'w') as f: with open('GoodTests.py', 'w') as f:
f.write(contents) f.write(contents)
except Exception as e: except Exception as e:
sys.stderr.write('Failed to write to GoodTests.py\n%s\n' %(str(e,))) sys.stderr.write(f'Failed to write to GoodTests.py\n{str(e)}\n')
return 1 return 1
try: try:
os.chmod('GoodTests.py', 0o775) os.chmod('GoodTests.py', 0o775)
@ -311,7 +311,7 @@ def main(thisDir=None, additionalArgs=[], MY_PACKAGE_MODULE=None, ALLOW_SITE_INS
return downloadRet return downloadRet
goodTestsInfo = findGoodTests() goodTestsInfo = findGoodTests()
if goodTestsInfo['success'] is False: if goodTestsInfo['success'] is False:
sys.stderr.write('Could not download or find GoodTests.py. Try to download it yourself using "pip install GoodTests", or wget %s\n' %( GOODTESTS_URL,)) sys.stderr.write(f'Could not download or find GoodTests.py. Try to download it yourself using "pip install GoodTests", or wget {GOODTESTS_URL}\n')
return 1 return 1
baseName = os.path.basename(MY_PACKAGE_MODULE) baseName = os.path.basename(MY_PACKAGE_MODULE)
@ -339,13 +339,13 @@ def main(thisDir=None, additionalArgs=[], MY_PACKAGE_MODULE=None, ALLOW_SITE_INS
except ImportError as e: except ImportError as e:
sys.path = oldSysPath sys.path = oldSysPath
if not ALLOW_SITE_INSTALL: if not ALLOW_SITE_INSTALL:
sys.stderr.write('Cannot find "%s" locally.\n' %(MY_PACKAGE_MODULE,)) sys.stderr.write(f'Cannot find "{MY_PACKAGE_MODULE}" locally.\n')
return 2 return 2
else: else:
try: try:
__import__(baseName) __import__(baseName)
except: except:
sys.stderr.write('Cannot find "%s" locally or in global python path.\n' %(MY_PACKAGE_MODULE,)) sys.stderr.write(f'Cannot find "{MY_PACKAGE_MODULE}" locally or in global python path.\n')
return 2 return 2
if foundIt is True: if foundIt is True:
@ -372,16 +372,16 @@ def main(thisDir=None, additionalArgs=[], MY_PACKAGE_MODULE=None, ALLOW_SITE_INS
eName = e.message.split()[-1] eName = e.message.split()[-1]
if eName != MY_PACKAGE_MODULE: 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)) sys.stderr.write(f'Error while importing {eName}: {str(e)}\n Likely this is another dependency that needs to be installed\nPerhaps run "pip install {eName}" or install the providing package.\n\n')
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(f'Could not import {MY_PACKAGE_MODULE}. Either install it or otherwise add to PYTHONPATH\n{str(e)}\n')
return 1 return 1
if not os.path.isdir(MY_TEST_DIRECTORY): if not os.path.isdir(MY_TEST_DIRECTORY):
if not os.path.exists(MY_TEST_DIRECTORY): if not os.path.exists(MY_TEST_DIRECTORY):
sys.stderr.write('Cannot find test directory: %s\n' %(MY_TEST_DIRECTORY,)) sys.stderr.write(f'Cannot find test directory: {MY_TEST_DIRECTORY}\n')
else: else:
sys.stderr.write('Provided test directory, "%s" is not a directory.\n' %(MY_TEST_DIRECTORY,)) sys.stderr.write(f'Provided test directory, "{MY_TEST_DIRECTORY}" is not a directory.\n')
return 3 return 3
sys.stdout.write('Starting test..\n') sys.stdout.write('Starting test..\n')