Same as
https://ask.sagemath.org/question/65840/bugged-interaction-with-signal-handler-sagemath-95-linux/
This is a minimal reproducible example of a bug using a typical interrupt handler so that files being written to are not corrupted. Running the script as `python filename.py` works as intended, but the issue occurs on running this script as `sage filename.sage` or as `python filename.py` with any Sage import statement similar to `from sage.all import matrix`.
As commented, the first `time.sleep(3)` can be interrupted correctly, the second `time.sleep(4)` correctly raises the `KeyboardInterrupt()` on exiting the scope of `with DelayedKeyboardInterrupt()`, but the final `time.sleep(5)` call cannot be interrupted, but the hardcoded `KeyboardInterrupt()` at the end still works. Printing `signal.getsignal(signal.SIGINT)` shows that `DelayedKeyboardInterrupt()` correctly restores the handler.
I realise that `cysignals` is preferred with Sage, but am unable to figure out how to use it for the project without major changes.
import signal
import time
class DelayedKeyboardInterrupt:
def __enter__(self):
self.sigint_handler = signal.signal(signal.SIGINT, self.handler)
self.signal_received = False
def handler(self, sig, frame):
self.signal_received = True
print("Delaying exit for file I/O.")
def __exit__(self, type, value, traceback):
signal.signal(signal.SIGINT, self.sigint_handler)
if self.signal_received:
raise KeyboardInterrupt("delayed")
print("sleeping unprotected for 3 sec")
time.sleep(3) # Ctrl+C here raises KeyboardInterrupt instantly
with DelayedKeyboardInterrupt():
print("sleeping protected for 4 sec")
time.sleep(4) # Ctrl+C here raises KeyboardInterrupt("delayed") after end of 4 sec
print("sleeping 'unprotected' for 5 sec")
time.sleep(5) # Ctrl+C here does not raise any KeyboardInterrupt
raise KeyboardInterrupt("hardcoded") # this raises correctly
Ubuntu 22.04.1 LTS 64-bit, with Sage 9.5 installed as a apt package