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)?
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()
Related
I know how to do something similar with Thonny: I could paste my code into the editor, and press the green "Run" button. This would run the program and give me output. But it would require copy pasting my file into Thonny (I want to code in Vim or run pre-existing examples) and pressing GUI buttons which I don't want to do.
Another related approach would be to copy the program as main.py to the pico, e.g. with rshell: How can you make a micropython program on a raspberry pi pico autorun? But this requires plugging and unplugging the USB, and then reconnecting to the UART every time to see the output.
Is it possible to send file contents to a GNU Screen session? would likely also solve or almost solve my problem, but:
I don't want to start a named server and then run another command, it's messy, I just want to run!
I would need to think about how to send Ctrl+D to soft restart. Should not be hard, but lazy to learn
The first way I got it to work was with https://github.com/scientifichackers/ampy That tool is just designed for the job, and does it perfectly with the run command:
python3 -m pip install --user adafruit-ampy
ampy --port /dev/ttyACM0 run blink.py
Outcome:
stops execution of current program
starts execution of blink.py
shows UART output on my shell
I can then quit ampty with Ctrl + C to get back to my shell, and the program continues to run.
Tested on adafruit-ampy==1.1.0, Ubuntu 22.04 host, Raspberry Pi Pico W, MicroPython rp2-pico-w-20221014-unstable-v1.19.1-544-g89b320737.uf2.
When I type emacs & in X11, a new window doesn't open. Instead I just get the PID of the process. This illustrates what I mean.
bash-3.2$ emacs &
[1] 38624
Why is this happening and how can I get emacs to open in a separate window?
You can't start terminal Emacs as a background job -- it needs to interact with the terminal. Whenever a background job attempts to write to the tty, it is immediately stopped.
I would expect that your next input into the terminal would have resulted in a message similar to this?
[1]+ Stopped emacs
(which would have been useful).
You could then foreground the job with fg.
Running emacs & only makes any sense with GUI Emacs.
In Emacs, sometimes I start a shell with ansi-term, and then from this shell I run IPython (another shell) that enters a long loop printing a long, long output.
When this happens, I often want to sendSIGINT to stop the script that IPython is running, but sometimes this takes way too long for IPython to capture Ctrl+C Ctrl+C (there are times when IPython never seems to listen to it). Interestingly, this does not seem to happen when I run it from a regular terminal.
Why is this the case? Is it an Emacs or IPython problem?
Below is the code written in a script say test_atexit.py
def exit_function():
print "I am in exit function"
import atexit
atexit.register(exit_function)
print "I am in main function"
When i run the function using python2.4 then exit_function is being called
$python2.4 test_atexit.py
I am in main function
I am in exit function
When i run the same using ipython then exit_function is not being called
$ ipython
In [1]: %run test_atexit.py
I am in main function
In [2]:
why exit_function is not called when running script using Ipython and how can i make ipython to call exit_function
atexit functions are called when the Python interpreter exits, not when your script finishes. When you %run something in IPython, the interpreter is still running until you quit IPython. When you do that, you should see the output from your exit_function().
Possibly what you want is a try/finally, which ensures that the finally code is run after the try block, even if an exception occurs:
try:
print("Doing things...")
raise Exception("Something went wrong!")
finally:
print("But this will still happen.")
If you really need to make atexit functions run, then you can call atexit._run_exitfuncs. However, this is undocumented, and it may do unexpected things, because anything can register atexit functions - IPython itself registers half a dozen, so you're likely to break things if you do it in IPython.
(Also, Python 2.4? For the sanity of developers everywhere, if it's possible to upgrade, do so ;-) )
I'm using the Scala REPL to interactively test some hash functions I'm building. I'm constantly switching between the product code (Eclipse), the browser and the Scala interpreter, doing copy/paste of values and results. In the mix I'm often doing CTRL-C on the interpreter, exiting the session and loosing all my functions.
Is there any way to let the Scala REPL either ignore CTRL-C or, even better, perform "paste" with it? I'm working on Linux.
I only know how to prevent REPL from exiting. Remapping of CTRL+C to perform copy command could be done in the same way (if there is some command that ables to change keymap w/out restarting terminal -- I don't know is there one). Anyways, to block ^C wrap your REPL invocation in .sh script like this:
#!/bin/bash
#switch off sensitivity to ^C
trap '' 2
# here goes REPL invoke
scala
#get back sensitivity to ^C
trap 2
trap command
defines and activates handlers to be run when the shell receives
signals
or other conditions.
2 is a SIGINT value (that's the signal which is triggered when you press CTRL+C)
The repl already intercepts ctrl-C, but apparently it doesn't work on linux. It does work on osx. If someone who uses linux opens a ticket with sufficient detail to indicate why not, I can fix it.
As an alternative to the native Scala REPL, you can use Ammonite, which does handle Ctrl+C:
# while(true) ()
... hangs ...
^Ctrl-C
Interrupted!
#
The traditional Scala REPL doesn't handle runaway code, and gives you no option but to kill the process, losing all your work.
Ammonite-REPL lets you interrupt the thread, stop the runaway-command and keep going.