from functools import wraps import errno import os import signal class TimeoutError(Exception): """Generic Timeout Error.""" def timeout(seconds=10, error_message=os.strerror(errno.ETIME)): """Timeout decorator to wrap around another callable. https://stackoverflow.com/questions/2281850/timeout-function-if-it-takes-too-long-to-finish """ def decorator(func): def _handle_timeout(signum, frame): raise TimeoutError(error_message) 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 wraps(func)(wrapper) return decorator