pybind / pybind11

Seamless operability between C++11 and Python
https://pybind11.readthedocs.io/
Other
15.57k stars 2.09k forks source link

Catching specific exception types via error_already_set #700

Open llchan opened 7 years ago

llchan commented 7 years ago

If I want to perform the C++ equivalent of this python code:

try:
    val = d['key']
except KeyError:
    return

I can do it like this, but it's rather verbose:

py::object val;
try {
  val = d["key"];
} catch (py::error_already_set& exc) {
  exc.restore();
  if (PyErr_ExceptionMatches(PyExc_KeyError)) {
    PyErr_Clear();
    return;
  } else {
    throw py::error_already_set();
  }
}

Is there a more idiomatic way to do this? If not, could we modify the type hierarchy and/or the error_already_set mechanism to allow for something closer to this?

py::object val;
try {
  val = d["key"];
} catch (const py::key_error& exc) {
  return;
}
llchan commented 7 years ago

@romanvm @dean0x7d thanks for adding the helper func. Can we also mention this in the docs?

dean0x7d commented 7 years ago

@llchan It's mentioned in the API reference for error_already_set.

llchan commented 7 years ago

I see, looks good, but I was thinking we could also add something in the tutorial-ish section here: http://pybind11.readthedocs.io/en/master/advanced/exceptions.html

dean0x7d commented 7 years ago

Ah, right, it does seem like that section is overwhelmingly about C++ -> Python exception translation, but not the other way around. If you have something in mind for it, would you be willing to submit a PR?