Select to view content in your preferred language

KeyboardInterrupt doesn't work when arcgisscripting module is loaded

1799
3
09-24-2010 10:58 AM
LoganPugh
Frequent Contributor
The KeyboardInterrupt exception -- thrown when Ctrl-C, or Ctrl-Break on some machines, are pressed in a Python console window -- is commonly used to gracefully break out of long-process loops, allowing your script to perform cleanup, logging etc, before exiting.

Under my ArcGIS 9.3.1 SP2/Windows XP SP3 environment, there is an issue with catching the KeyboardInterrupt exception if the arcgisscripting module is loaded. Instead of hitting the KeyboardInterrupt catch statement, the script aborts abruptly, spitting out the following message:

forrtl: error (200): program aborting due to control-C event


If the arcgisscripting module is not loaded (removed from the import statement), the KeyboardInterrupt exception is thrown and processed properly.

From what I've read this is due to the use of Fortran in the arcgisscripting module which somehow overrides Python's interrupt processing.

Here's an example script you can use to test and reproduce the issue. Save it as a Python script, run it from the Windows command prompt and press Ctrl-C (Ctrl-Break on some machines) to test whether the KeyboardInterrupt exception is processed. Simply toggle the commenting for the "import arcgisscripting" line.

#import arcgisscripting
import time

try:
    while(True):
        time.sleep(1)
except KeyboardInterrupt:
    print "KeyboardInterrupt detected!"


Anyone know of a workaround to this problem? Thanks in advance for any insights you may have.
0 Kudos
3 Replies
KimOllivier
Honored Contributor
There is a soft interrupt.

Click on the Pythonwin icon in the tray at the bottom of the screen and you will get an option "break into running code" that will do a soft interrupt, very useful if you have got into a loop by forgetting the row = cur.next().
0 Kudos
LoganPugh
Frequent Contributor
Yeah that is handy for debugging, not so much for production though. I received a response on GIS Stack Exchange that sounds promising, have not tested yet:

You can try reinstalling a custom handler for SIGINT using the signal module after importing arcgisscripting.
import arcgisscripting
import signal

def ctrlc(sig, frame):
    raise KeyboardInterrupt("CTRL-C!")

signal.signal(signal.SIGINT, ctrlc)
http://gis.stackexchange.com/questions/2190/keyboardinterrupt-doesnt-work-when-arcgisscripting-modul...

edit: It unfortunately doesn't seem to work, the forrtl error still occurs instead of my KeyboardInterrupt exception. Also, the help file on the signal module says that SIGINT is already translated to KeyboardInterrupt by default. So unfortunately it looks like arcgisscripting is still overriding it.
0 Kudos
LoganPugh
Frequent Contributor
I figured out a Windows-only workaround for this. It uses the msvcrt module, which is a Windows-only wrapper for the Visual C++ runtime, to read which keyboard character code was last received. It doesn't override the Ctrl-C, so I specified it should look for Ctrl-Alt-Q. When you press Ctrl-Alt-Q in my test script it will raise the KeyboardInterrupt exception. If you hit Ctrl-C it will still abruptly kill the script, however.

There are likely other ways to do this on *nix but I only needed this for Windows.
import arcgisscripting
import msvcrt
import time

def kbfunc():
   x = msvcrt.kbhit()
   if x:
      ret = ord(msvcrt.getch())
   else:
      ret = 0
   return ret

if __name__ == '__main__':
    try:
        while(True):
            time.sleep(1)

            # Check to see if Ctrl-Alt-Q is pressed
            x = kbfunc()
            if x == 16: # Ctrl-Alt-Q
                raise KeyboardInterrupt

    except KeyboardInterrupt:
        print "KeyboardInterrupt detected!"
0 Kudos