Set error if it's not set in error_already_set()

This commit is contained in:
Ivan Smirnov 2016-09-07 21:10:16 +01:00
parent 392f16ccb8
commit 67b54894b2
3 changed files with 39 additions and 4 deletions

View File

@ -106,10 +106,15 @@ PYBIND11_NOINLINE inline handle get_type_handle(const std::type_info &tp) {
} }
PYBIND11_NOINLINE inline std::string error_string() { PYBIND11_NOINLINE inline std::string error_string() {
PyObject *type, *value, *traceback; if (!PyErr_Occurred()) {
PyErr_Fetch(&type, &value, &traceback); PyErr_SetString(PyExc_RuntimeError, "Unknown internal error occurred");
return "Unknown internal error occurred";
}
std::string errorString; PyObject *type, *value, *traceback;
PyErr_Fetch(&type, &value, &traceback);
std::string errorString;
if (type) { if (type) {
errorString += handle(type).attr("__name__").cast<std::string>(); errorString += handle(type).attr("__name__").cast<std::string>();
errorString += ": "; errorString += ": ";

View File

@ -104,5 +104,23 @@ test_initializer custom_exceptions([](py::module &m) {
m.def("throws3", &throws3); m.def("throws3", &throws3);
m.def("throws4", &throws4); m.def("throws4", &throws4);
m.def("throws_logic_error", &throws_logic_error); m.def("throws_logic_error", &throws_logic_error);
});
m.def("throw_already_set", [](bool err) {
if (err)
PyErr_SetString(PyExc_ValueError, "foo");
try {
throw py::error_already_set();
} catch (const std::runtime_error& e) {
if ((err && e.what() != std::string("ValueError: foo")) ||
(!err && e.what() != std::string("Unknown internal error occurred")))
{
PyErr_Clear();
throw std::runtime_error("error message mismatch");
}
}
PyErr_Clear();
if (err)
PyErr_SetString(PyExc_ValueError, "foo");
throw py::error_already_set();
});
});

View File

@ -1,6 +1,18 @@
import pytest import pytest
def test_error_already_set(msg):
from pybind11_tests import throw_already_set
with pytest.raises(RuntimeError) as excinfo:
throw_already_set(False)
assert msg(excinfo.value) == "Unknown internal error occurred"
with pytest.raises(ValueError) as excinfo:
throw_already_set(True)
assert msg(excinfo.value) == "foo"
def test_custom(msg): def test_custom(msg):
from pybind11_tests import (MyException, throws1, throws2, throws3, throws4, from pybind11_tests import (MyException, throws1, throws2, throws3, throws4,
throws_logic_error) throws_logic_error)