timeout-decorator
timeout-decorator copied to clipboard
Context managers?
Thanks for this useful library. Do you plan on adding context managers into this library?
That would be an interesting feature. Feel free to make a pull request for that.
You can implement signal-based timeout using contextlib2.ContextDecorator. Something like this:
class signal_timeout(ContextDecorator):
"""
Enforces timeout via signals. Can be applied as a context manager or decorator.
"""
class NotInstalled(object): pass
def __init__(self, seconds):
"""
:type seconds: int|float
:param seconds: Number of seconds before timeout occurs.
"""
self.seconds = seconds
self._prev_signal_handler = self.NotInstalled
def __enter__(self):
if self.seconds > 0:
self._prev_signal_handler = \
signal.signal(signal.SIGALRM, self._handle_timeout)
signal.setitimer(signal.ITIMER_REAL, self.seconds)
def __exit__(self, exc_type, exc_val, exc_tb):
if self._prev_signal_handler is not self.NotInstalled:
signal.setitimer(signal.ITIMER_REAL, 0)
signal.signal(signal.SIGALRM, self._prev_signal_handler)
self._prev_signal_handler = self.NotInstalled
@staticmethod
def _handle_timeout(signal_no, stack_trace):
raise TimeoutError()
Multiprocessing will likely require some black magic to convert the context block into a function so that it can be passed to multiprocessing.Process.__init__.