timeout-decorator icon indicating copy to clipboard operation
timeout-decorator copied to clipboard

Context managers?

Open selwin opened this issue 10 years ago • 2 comments

Thanks for this useful library. Do you plan on adding context managers into this library?

selwin avatar Apr 25 '15 02:04 selwin

That would be an interesting feature. Feel free to make a pull request for that.

pnpnpn avatar May 03 '15 20:05 pnpnpn

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__.

todofixthis avatar Apr 28 '16 14:04 todofixthis