Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is KeyboardInterrupt raised in Python?

All the docs tell us is,

Raised when the user hits the interrupt key (normally Control-C or Delete). During execution, a check for interrupts is made regularly.

But from the point of the code, when can I see this exception? Does it occur during statement execution? Only between statements? Can it happen in the middle of an expression?

For example:

file_ = open('foo')
# <-- can a KeyboardInterrupt be raised here, after the successful
# completion of open but prior to the try? -->
try:
    # try some things with file_
finally:
    # cleanup

Will this code leak during a well-timed KeyboardInterrupt? Or is it raised during the execution of some statements or expressions?

like image 929
Thanatos Avatar asked Feb 23 '16 07:02

Thanatos


2 Answers

According to a note in the unrelated PEP 343:

Even if you write bug-free code, a KeyboardInterrupt exception can still cause it to exit between any two virtual machine opcodes.

So it can occur essentially anywhere. It can indeed occur during evaluation of a single expression. (This shouldn't be surprising, since an expression can include function calls, and pretty much anything can happen inside a function call.)

like image 183
BrenBarn Avatar answered Oct 25 '22 18:10

BrenBarn


Yes, a KeyboardInterrupt can occur in the place you marked.

To deal with this, you should use a with block:

with open('foo') as file_:
    # do some things
    raise KeyboardInterrupt

# file resource is closed no matter what, even if a KeyboardInterrupt is raised

However, the exception could occur even between the open() call and the assignment to file_. It's probably not worth worrying about this, because usually a ctrl-c will mean your program is about to end, so the "leaked" file handle will be cleaned up by the OS. But if you know that it is important, you can use a signal handler to catch the signal that raises KeyboardInterrupt (SIGINT).

like image 22
BingsF Avatar answered Oct 25 '22 17:10

BingsF