# Distinguish between alarm() and manual interrupt

I have a long computation that needs to be repeated many times with different input. I want to limit each repetition to, say, a minute. Using alarm means that if I try to manually interrupt the whole thing, it will just assume that one repetition timed out. Is there a solution that doesn't involve restarting the worksheet?

while True:
alarm(60)
try:
do_long_computation(random())
except KeyboardInterrupt:
continue
alarm(0)

edit retag close merge delete

Sort by » oldest newest most voted

Updated: modern Sage raises an AlarmInterrupt instead of a KeyboardInterrupt, so you can catch it explicitly instead. That's a much cleaner solution than having to dig around inside a KeyboardInterrupt message.

Also, it's probably a better idea to use cancel_alarm() than alarm(0), which was apparently never officially supported.

Sure. While I would have made it a little more explicit, the KeyboardInterrupt generated by alarm does contain information that a typical KeyboardInterrupt doesn't, in the .args and .message attributes. For example, control-C in the following

try:
sleep(5)
except KeyboardInterrupt as KI:
print 'args=',KI.args
print 'message=', KI.message


produces

^Cargs= ()
message=


but adding alarm(2) before executing it produces:

args= ('computation timed out because alarm was set for 2 seconds',)
message= computation timed out because alarm was set for 2 seconds


So one way to take advantage of this would be through something like this:

while True:
alarm(3)
try:
print 'sleeping..'
sleep(5)
except KeyboardInterrupt as KI:
if KI.message.startswith("computation timed out"):
print 'timed out!'
continue
else:
# not a timeout, so break
print 'manual exit!'
alarm(0)
break
alarm(0)


which gives

sleeping..
timed out!
sleeping..
timed out!
sleeping..
timed out!
sleeping..
^Cmanual exit!


I tend to wrap this stuff up in decorators, but in this case mine is nested three deep so it's probably overkill for the problem, because it makes it look more complicated than it really is.

more