When signal
is imported, I want to tell it not to override the default signal handler (SIG_DFL).
There are a couple of ways around this, and neither of them is objectively bad. But it would be nice if there was an even better alternative.
Consider the following snippet:
(0) Py_InitializeEx(0);
(1)
(2) char* exp =
(3) "input('press ctrl-c or enter’);"
(4) "import signal;"
(5) "signal.signal(signal.SIGINT, signal.SIG_DFL);" // this is one workaround
(6) "input('press ctrl-c');";
(7) PyRun_SimpleString(exp);
(8)
(9) Py_FinalizeEx();
Line (0): I have initialized embedded Python, skipping signal handler registration.
Line (3): Press ctrl-c to show the program exits without also raising KeyboardInterrupt
, otherwise press enter to continue execution.
Line (5): I must manually reset the signal handler to SIG_DFL
if I don’t want to see KeyboardInterrupt
raised.
Line (6): Press ctrl-c to show the program exit without also raising KeyboardInterrupt
.
After removing line (5), line (6) will then raise KeyboardInterrupt
.
Alternatively, I can insert a new line at (0):
signal(SIGINT, <my signal handler>); // this is another workaround
Now, the signal
library will respect my custom handler.
Of course, if I’m intentionally initializing with Py_InitializeEx(0)
, I shouldn’t need to import signal
. And I don’t, but I may want to import asyncio
, which imports signal
.
Ok, now why would I would I care about this particular scenario? I admit I don’t have a mainstream use case.
But I’m working on a Rust wrapper around a Python library. I use another library to help me with inter-op between Rust and Python async.
Part of what this library does (before running any of the Rust code) is it initializes a Python interpreter via Py_InitializeEx(0)
and also imports asyncio
.
Any Rust developers using this library would then learn that, unless they register any signal handlers, SIGINT will end up raising KeyboardInterrupt
.
Solvable, but it’s unexpected behavior (or at least it was for me) until one learns what is happening underneath the hood.
If this is something that won’t be solved at the CPython level (due to infeasibility or if the costs outweigh the benefits), then I plan on moving forward with one of the workarounds.