import signal
from functools import wraps
__all__ = ['timeout', 'TimeoutError']
class TimeoutError(Exception): pass
# IMPORTANT: this is not thread-safe
def timeout(seconds, error_message='Function call timed out'):
def _handle_timeout(signum, frame):
raise TimeoutError(error_message)
def decorated(func):
@wraps(func)
def wrapper(*args, **kwargs):
signal.signal(signal.SIGALRM, _handle_timeout)
signal.alarm(seconds)
try:
result = func(*args, **kwargs)
finally:
signal.alarm(0)
return result
return wrapper
return decorated
if __name__ == '__main__':
# sample usage
import time
@timeout(4)
def wait(delay):
time.sleep(delay)
print('done: ' + str(delay))
wait(0) # pass
try:
wait(5) # fail
except TimeoutError as e:
print(e)