1

I'm writing an IPython extension with cell magics that call out to another executable via pexpect. It keeps this executable running in the background for the life of the kernel. Is there a hook somewhere so that I can send this subprocess Ctrl-C when a kernel interrupt is raised (eg, the "Interrupt Kernel" menu option in the IPython Notebook)?

acfoltzer
  • 5,588
  • 31
  • 48
  • Are you controlling the subprocess in a cell that's still executing when you want to interrupt it? Or from a background thread? Or have you just created the pexpect object and gone on to do something else. By the 'stop' button, do you mean the interrupt menu option, or the kernel shutdown button on the dashboard? – Thomas K Sep 25 '13 at 00:56
  • @ThomasK I'm not sure what the first part of your comment means, but I think I'm doing the first option. The extension starts up the subprocess when it is loaded by IPython, and then the cell magic implementation sends lines and reads output from it. This happens on the same thread that calls the cell magic. – acfoltzer Sep 25 '13 at 17:37
  • And do you want it to be stopped when the kernel is *shut down*, or merely *interrupted*? These are different things - you can keep using a kernel after interrupting it, but after shutting it down, the kernel process is gone. – Thomas K Sep 25 '13 at 17:59
  • @ThomasK I just want to send `Ctrl-C` to the subprocess when the kernel is **interrupted**. The subprocess is another language's interpreter, which will do the right thing as long as I can get that signal to it. Shutting down the kernel already does the right thing; I just want folks to be able to escape from any infinite loops they might write in their code without having to restart everything :) – acfoltzer Sep 25 '13 at 18:03
  • So is this while your cell magic is running? If so, you should be able to catch `KeyboardInterrupt` in your Python function, and then use `p.sendintr()` to send an interrupt to your child process. – Thomas K Sep 25 '13 at 19:05
  • Ah, that did it! Can you leave that as an answer so I can accept it? It didn't occur to me to catch a KeyboardInterrupt from something the user does in the browser. – acfoltzer Sep 25 '13 at 23:59

1 Answers1

2

Reposting as an answer:

IPython interrupts the kernel by sending a SIGINT, the same signal that's fired when you press Ctrl-C in a terminal. So, so long as you want to catch it while your own code is running, you can just catch KeyboardInterrupt, like this:

p.sendline('some command')
try:
    p.expect(processing_finished_mark)
except KeyboardInterrupt:
    p.sendintr()
Thomas K
  • 39,200
  • 7
  • 84
  • 86