I'm calling a function in Python which I know may stall and force me to restart the script.
How do I call the function or what do I wrap it in so that if it takes longer than 5 seconds the script cancels it and does something else?
I'm calling a function in Python which I know may stall and force me to restart the script.
How do I call the function or what do I wrap it in so that if it takes longer than 5 seconds the script cancels it and does something else?
Great, easy to use and reliable PyPi project timeout-decorator (https://pypi.org/project/timeout-decorator/)
installation:
Usage:
timeout-decorator
don't work on windows system as , windows didn't supportsignal
well.If you use timeout-decorator in windows system you will get the following
Some suggested to use
use_signals=False
but didn't worked for me.Author @bitranox created the following package:
Code Sample:
Gives the following exception:
The
stopit
package, found on pypi, seems to handle timeouts well.I like the
@stopit.threading_timeoutable
decorator, which adds atimeout
parameter to the decorated function, which does what you expect, it stops the function.Check it out on pypi: https://pypi.python.org/pypi/stopit
I posted a gist that solves this question/problem with a decorator and a
threading.Timer
. Here it is with a breakdown.Imports and setups for compatibility
It was tested with Python 2 and 3. It should also work under Unix/Linux and Windows.
First the imports. These attempt to keep the code consistent regardless of the Python version:
Use version independent code:
Now we have imported our functionality from the standard library.
exit_after
decoratorNext we need a function to terminate the
main()
from the child thread:And here is the decorator itself:
Usage
And here's the usage that directly answers your question about exiting after 5 seconds!:
Demo:
The second function call will not finish, instead the process should exit with a traceback!
KeyboardInterrupt
does not always stop a sleeping threadNote that sleep will not always be interrupted by a keyboard interrupt, on Python 2 on Windows, e.g.:
nor is it likely to interrupt code running in extensions unless it explicitly checks for
PyErr_CheckSignals()
, see Cython, Python and KeyboardInterrupt ignoredI would avoid sleeping a thread more than a second, in any case - that's an eon in processor time.
To catch it and do something else, you can catch the KeyboardInterrupt.
Here is a slight improvement to the given thread-based solution.
The code below supports exceptions:
Invoking it with a 5 second timeout:
I have a different proposal which is a pure function (with the same API as the threading suggestion) and seems to work fine (based on suggestions on this thread)