I'm using the code solution mentioned here.
I'm new to decorators, and don't understand why this solution doesn't work if I want to write something like the following:
@timeout(10)
def main_func():
nested_func()
while True:
continue
@timeout(5)
def nested_func():
print "finished doing nothing"
=> Result of this will be no timeout at all. We will be stuck on endless loop.
However if I remove @timeout
annotation from nested_func
I get a timeout error.
For some reason we can't use decorator on function and on a nested function in the same time, any idea why and how can I correct it to work, assume that containing function timeout always must be bigger than the nested timeout.
This is a limitation of the
signal
module's timing functions, which the decorator you linked uses. Here's the relevant piece of the documentation (with emphasis added by me):So, what you're seeing is that when your
nested_func
is called, it's timer cancels the outer function's timer.You can update the decorator to pay attention to the return value of the
alarm
call (which will be the time before the previous alarm (if any) was due). It's a bit complicated to get the details right, since the inner timer needs to track how long its function ran for, so it can modify the time remaining on the previous timer. Here's an untested version of the decorator that I think gets it mostly right (but I'm not entirely sure it works correctly for all exception cases):as Blckknght pointed out, You cant use signals for nested decorators - but You can use multiprocerssing to archive that.
You might use this decorator, it supports nested decorators : https://github.com/bitranox/wrapt_timeout_decorator
and as ABADGER1999 points out in his blog https://anonbadger.wordpress.com/2018/12/15/python-signal-handlers-and-exceptions/ using signals and the TimeoutException is probably not the best idea - because it can be catched in the decorated function.
Of course You can use Your own Exception, derived from the Base Exception Class, but the code might still not work as expected - see the next example - You may try it out in jupyter: https://mybinder.org/v2/gh/bitranox/wrapt_timeout_decorator/master?filepath=jupyter_test_wrapt_timeout_decorator.ipynb
There's a better version of timeout decorator that's currently on Python's PyPI library. It supports both UNIX and non-UNIX based operating system. The part where SIGNALS are mentioned - that specifically for UNIX.
Assuming you aren't using UNIX. Below is a code snippet from the decorator that shows you a list of parameters that you can use as required.
For implementation on NON-UNIX base operating system. This is what I would do:
If you notice, I'm doing use_signals=False. That's all, you should be good to go.