Skip to content

Commit f07809c

Browse files
committed
Use 'raise from' in initialization
1 parent 56e88e9 commit f07809c

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

include/pybind11/detail/common.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,19 @@ extern "C" {
272272
} \
273273
}
274274

275+
#if PY_VERSION_HEX >= 0x03030000
276+
277+
#define PYBIND11_CATCH_INIT_EXCEPTIONS \
278+
catch (pybind11::error_already_set &e) { \
279+
pybind11::raise_from(e, PyExc_ImportError, "initialization failed"); \
280+
return nullptr; \
281+
} catch (const std::exception &e) { \
282+
PyErr_SetString(PyExc_ImportError, e.what()); \
283+
return nullptr; \
284+
} \
285+
286+
#else
287+
275288
#define PYBIND11_CATCH_INIT_EXCEPTIONS \
276289
catch (pybind11::error_already_set &e) { \
277290
PyErr_SetString(PyExc_ImportError, e.what()); \
@@ -281,6 +294,8 @@ extern "C" {
281294
return nullptr; \
282295
} \
283296

297+
#endif
298+
284299
/** \rst
285300
***Deprecated in favor of PYBIND11_MODULE***
286301

tests/test_embed/test_interpreter.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,24 @@ TEST_CASE("Import error handling") {
7373
REQUIRE_NOTHROW(py::module_::import("widget_module"));
7474
REQUIRE_THROWS_WITH(py::module_::import("throw_exception"),
7575
"ImportError: C++ Error");
76+
#if PY_VERSION_HEX >= 0x03030000
77+
REQUIRE_THROWS_WITH(py::module_::import("throw_error_already_set"),
78+
Catch::Contains("ImportError: initialization failed"));
79+
80+
auto locals = py::dict("is_keyerror"_a=false, "message"_a="not set");
81+
py::exec(R"(
82+
try:
83+
import throw_error_already_set
84+
except ImportError as e:
85+
is_keyerror = type(e.__cause__) == KeyError
86+
message = str(e.__cause__)
87+
)", py::globals(), locals);
88+
REQUIRE(locals["is_keyerror"].cast<bool>() == true);
89+
REQUIRE(locals["message"].cast<std::string>() == "'missing'");
90+
#else
7691
REQUIRE_THROWS_WITH(py::module_::import("throw_error_already_set"),
7792
Catch::Contains("ImportError: KeyError"));
93+
#endif
7894
}
7995

8096
TEST_CASE("There can be only one interpreter") {

0 commit comments

Comments
 (0)