Skip to content

Add FAQ entry for dealing with long functions interruption #2000

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 25, 2019

Conversation

CharlesB2
Copy link
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.

@CharlesB2 CharlesB2 changed the title Add FAQ entry, for dealing with long functions interruption Add FAQ entry for dealing with long functions interruption Nov 21, 2019
@bjodah
Copy link
Contributor

bjodah commented Nov 21, 2019

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
Contributor Author

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."; 
    }
};

Copy link
Member

@wjakob wjakob left a comment

Choose a reason for hiding this comment

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

Minor wording request.

@wjakob wjakob merged commit 0f1d3bf into pybind:master Nov 25, 2019
@wjakob
Copy link
Member

wjakob commented Nov 25, 2019

Thanks!

@eacousineau
Copy link
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) {
        throw py::error_already_set();
      }
      using namespace std::chrono_literals;
      std::this_thread::sleep_for(50ms);
    }
  });
try:
  m.stuff()
  assert False
except KeyboardInterrupt:
  print("[ Done ]")

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

@eacousineau
Copy link
Contributor

Posted: #2007

@CharlesB2 CharlesB2 deleted the check_signals_doc branch November 25, 2019 15:13
@CharlesB2
Copy link
Contributor Author

Great, much simpler with py:error_already_set!

Sign up for free to 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