You have a few options here. First and foremost, you could simply use Ctrl-C itself, but I assume you’ve looked into that and decided it won’t do.
There are other keystrokes that send signals to a process. On a typical Unix system, you have Ctrl-\ sending SIGQUIT, Ctrl-Z sending SIGTSTP, and sometimes others. Any of these signals - including SIGINT for Ctrl-C - can be caught in Python using the
Python signal handlers are called when the bytecode interpreter gets around to them, but then they’re executed at the next point in the code. Here’s a (somewhat silly) example:
>>> import signal
>>> def where_am_i(*a): raise Exception("Look! I'm an exception!")
>>> signal.signal(signal.SIGTSTP, where_am_i)
>>> def f(): return input("Type something: ")
>>> def g(): return f().upper()
>>> def h(): print(g())
Type something: blah blah blahTraceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in h
File "<stdin>", line 1, in g
File "<stdin>", line 1, in f
File "<stdin>", line 1, in where_am_i
Exception: Look! I'm an exception!
At the prompt, I typed “blah blah blah” and then hit Ctrl-Z, instantly causing the given exception. (If this had been in a script instead of the REPL, the line numbers would have been more interesting.)
If you’re prepared to use either Ctrl-\ or Ctrl-Z as your shortcut, you could use this technique directly (assuming you’re on some sort of Unix - not sure about Windows). For a more custom keyboard signal, you could probably set it up so that, when the keystroke is pressed, the process is sent SIGUSR1; you can then catch SIGUSR1 the exact same way that I catch SIGTSTP above.
In any case, the upshot is that an exception gets raised. At that point, you can define “end the current task” by means of exception handling and stack unwinding, which shouldn’t be too hard (it might be as simple as “try: handle_task() except TaskAbortedException: pass” in some core loop somewhere). At very least, that’s a starting point to go exploring