I have a Python library written in Rust with PyO3, and it involves some expensive calculations (up to 10 minutes for a single function call). How can I abort the execution when calling from Python ?
Ctrl+C seems to only be handled after the end of the execution, so is essentially useless.
Minimal reproducible example:
# Cargo.toml
[package]
name = "wait"
version = "0.0.0"
authors = []
edition = "2018"
[lib]
name = "wait"
crate-type = ["cdylib"]
[dependencies.pyo3]
version = "0.10.1"
features = ["extension-module"]
// src/lib.rs
use pyo3::wrap_pyfunction;
#[pyfunction]
pub fn sleep() {
std::thread::sleep(std::time::Duration::from_millis(10000));
}
#[pymodule]
fn wait(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(sleep))
}
$ rustup override set nightly
$ cargo build --release
$ cp target/release/libwait.so wait.so
$ python3
>>> import wait
>>> wait.sleep()
Immediately after having entered wait.sleep()
I type Ctrl + C
, and the characters ^C
are printed to the screen, but only 10 seconds later do I finally get
>>> wait.sleep()
^CTraceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyboardInterrupt
>>>
The KeyboardInterrupt
was detected, but was left unhandled until the end of the call to the Rust function. Is there a way to bypass that ?
The behavior is the same when the Python code is put in a file and executed from outside the REPL.