Chapter 3: Using decorators

Example - Timeout

face Josiah Wang

Here is another practical example application of decorators.

Here, I have created a @timeout decorator that you can wrap around any function to raise a TimeoutError if the function does not finish executing after a given number of seconds.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import signal

def timeout(seconds):
    def process_timeout(func):
        def handle_timeout(signum, frame):
            raise TimeoutError("The function timed out")

        def wrapper(*args, **kwargs):
            signal.signal(signal.SIGALRM, handle_timeout)
            signal.alarm(seconds)

            try:
                func(*args, **kwargs)
            finally:
                signal.alarm(0) # No need to time out!

        return wrapper

    return process_timeout


@timeout(seconds=2)
def infinite():
    print("Running infinite...")
    while True:
        pass


# Wait 2 seconds. It should time out.
infinite()