Skip to content

Add FAQ entry for dealing with long functions interruption - #2000

Merged
wjakob merged 4 commits into
pybind:masterfrom
CharlesB2:check_signals_doc
Nov 25, 2019
Merged

Add FAQ entry for dealing with long functions interruption#2000
wjakob merged 4 commits into
pybind:masterfrom
CharlesB2:check_signals_doc

Conversation

@CharlesB2

Copy link
Copy Markdown
Contributor

I've spent some time figuring out how to correctly interrupt a long-running function when a SIGINT occurs, so I thought this entry could be useful.

@CharlesB2CharlesB2 changed the title Add FAQ entry, for dealing with long functions interruptionAdd FAQ entry for dealing with long functions interruptionNov 21, 2019
@bjodah

Copy link
Copy Markdown
Contributor

I've dabbled with interrupts so I appreciate this. What would be an example of interruption_error()? Is there any such default exception in C++ stdlib? Or do one need to create one and specify it's translation to Python's KeyboardInterrupt using pybind11?

@CharlesB2

Copy link
Copy Markdown
ContributorAuthor

Sorry I didn't include it, it's a user-defined exception since C++ stdexcept has no equivalent:

class interruption_error: public exception {
public:
const char* what() const noexcept{
return "Interruption signal caught."; }
};

@wjakobwjakob left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor wording request.

Comment threaddocs/faq.rst Outdated
@wjakob
wjakob merged commit 0f1d3bf into pybind:masterNov 25, 2019
@wjakob

Copy link
Copy Markdown
Member

Thanks!

@eacousineau

Copy link
Copy Markdown
Contributor

Nice! From tinkering with this, I think this could possibly be simplified; will PR a small change.

Reading the docs, it looks like the exception would have already been raised if this function returns non-zero:
https://docs.python.org/3.6/c-api/exceptions.html?highlight=pyerr_checksignals#c.PyErr_CheckSignals
https://docs.python.org/2.7/c-api/exceptions.html?highlight=pyerr_checksignals#c.PyErr_CheckSignals

So rather than create a redundant KeyboardInterrupt, it looks like you can just throw py::error_already_set. The following seems to work for me:

 m.def("stuff", []() -> void {
while (true) {
if (PyErr_CheckSignals() != 0) {
throwpy::error_already_set();
}
usingnamespacestd::chrono_literals;std::this_thread::sleep_for(50ms);
}
});
try:
m.stuff()
assertFalseexceptKeyboardInterrupt:
print("[ Done ]")

Full code here: https://github.com/eacousineau/repro/blob/f791b817ae88743cff66f7214f40a487ae99d843/python/pybind11/custom_tests/test_tmp.cc

@eacousineau

Copy link
Copy Markdown
Contributor

Posted: #2007

@CharlesB2
CharlesB2 deleted the check_signals_doc branch November 25, 2019 15:13
@CharlesB2

Copy link
Copy Markdown
ContributorAuthor

Great, much simpler with py:error_already_set!

@rwgkrwgk mentioned this pull request Feb 10, 2023
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@CharlesB2@bjodah@wjakob@eacousineau