Pythonic use of timeout decorator with variable timeout

Viewed 348

I have a routine that needs to call a number of other functions, and apply a timeout to those functions. I am using the timeout_decorator package. Assume I have a global variable "timeout" with default 120 (seconds). I need to be able to override this on a case by case basis via a command-line argument.

It appears to me that simple use of the decorator does not provide the override option. E.g.

@timeout_decorator.timeout(timeout)
def my_function_not_allowed_to_run_too_long(stuff):
    etc...

will have the default value of timeout, which can't be overridden as the decorator is evaluated prior to processing the command line.

I implemented the following:

class CallFuncWithTimeout(object):
    def __init__(self, func):
        self.func = func

    @timeout_decorator.timeout(timeout)
    def doit(self, *args, **kwargs):
        res = self.func(*args, **kwargs)
        return res

which can be called as follows:

my_func = CallFuncWithTimeout(my_function_not_allowed_to_run_too_long)
try:
    res = my_func.doit(stuff)
except timeout_decorator.timeout_decorator.TimeoutError:
    # handle timeout...

It appears to work; I assume because the class is not instantiated until after the command line has been processed and thus the "timeout" variable in the class reflects the command line value.

My question: is this the cleanest way to get this functionality? Am I missing something easier?

1 Answers

@timeout_decorator adds a timeout argument to the decorated function. Pass a timeout argument while calling the function: my_function_not_allowed_to_run_too_long(timeout=<variable_timeout>) to override the default one.

Related