2

I am building a Python package which is mostly implemented in Rust, with bindings provided by Pyo3.

Some of the Rust calls can take a long time, and I would like to be able to interrupt the process with Ctrl-c while these calls are happening. The previous question Keyboard Interrupt from Python does not abort Rust function (PyO3) gives two possible solutions. One requires that hooks are added throughout the code for the expensive operations to handle the interrupt. This I would very much like to avoid. The other uses the ctrl crate to set up a keyboard interrupt handler which exits the program. The issue with this approach is that while it does stop the program, it also freezes the terminal with the following error

Keyboard interrupt received, exiting...
C:\arrow\cpp\src\arrow\filesystem\s3fs.cc:2598:  arrow::fs::FinalizeS3 was not called even though S3 was initialized.  This could lead to a segmentation fault at exit

This also happens when interrupting while pure Python code is running.

I guess what I ideally want is for the Rust code to handle the interrupt as it usually does and then for Python to throw a KeyboardInterrupt exception as usual. Is there maybe some way to get the Rust code to act as though it has gotten a SIGINT signal? Is there some other way to exit while running Rust code without freezing the terminal?


The function which sets up the keyboard interrupt looks like this

#[pyfunction]
fn setup_keyboard_interrupt() {
    ctrlc::set_handler(move || {
        println!("Keyboard interrupt received, exiting...");
        std::process::exit(2);
    })
    .expect("Error setting Ctrl-C handler");
}

And I call it in __init__.py

I have tested this in Windows Powershell and WSL and get roughly the same results.


Is there some way to allow users to interrupt the program with Ctrl-c without having to think about it in all Rust code and without it freezing the terminal?

AlbertGarde
  • 369
  • 1
  • 13
  • Maybe use [`crossbeam-channel`](https://docs.rs/crossbeam-channel/latest/crossbeam_channel/) to allow communication between Python and Rust, enabling Python to send a signal/Interrupt to the Rust program? – Jishan Shaikh May 19 '23 at 13:36
  • The problem is not detecting in Rust code that an interrupt has occurred. This is solved with the hook set with the `ctrlc` crate. The issue is what to do once an interrupt has been detected. – AlbertGarde May 19 '23 at 15:58

0 Answers0