Skip to content

Commit bf2b031

Browse files
committed
Handle cases where binding code immediately throws py::error_already_set
When binding code immediately throws an exception of type py::error_already_set (e.g. via py::module::import that fails), the catch block sets an import error as expected. Unfortunately, following this, the deconstructor of py::error_already_set decides to call py::detail::get_internals() and set up various internal data structures of pybind11, which fails given that the error flag is active. The call stack of this looks as follows: Py_init_mymodule() -> __cxa_decrement_exception_refcount -> error_already_set::~error_already_set() -> gil_scoped_acquire::gil_scoped_acquire() -> detail::get_internals() -> ... -> pybind11::detail::simple_collector() -> uh oh.. The solution is simple: we call detail::get_internals() once before running any binding code to make sure that the internal data structures are ready.
1 parent 4c206e8 commit bf2b031

File tree

1 file changed

+4
-0
lines changed

1 file changed

+4
-0
lines changed

include/pybind11/detail/common.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ extern "C" {
218218
#define PYBIND11_STRINGIFY(x) #x
219219
#define PYBIND11_TOSTRING(x) PYBIND11_STRINGIFY(x)
220220
#define PYBIND11_CONCAT(first, second) first##second
221+
#define PYBIND11_ENSURE_INTERNALS_READY \
222+
pybind11::detail::get_internals();
221223

222224
#define PYBIND11_CHECK_PYTHON_VERSION \
223225
{ \
@@ -264,6 +266,7 @@ extern "C" {
264266
static PyObject *pybind11_init(); \
265267
PYBIND11_PLUGIN_IMPL(name) { \
266268
PYBIND11_CHECK_PYTHON_VERSION \
269+
PYBIND11_ENSURE_INTERNALS_READY \
267270
try { \
268271
return pybind11_init(); \
269272
} PYBIND11_CATCH_INIT_EXCEPTIONS \
@@ -291,6 +294,7 @@ extern "C" {
291294
static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &); \
292295
PYBIND11_PLUGIN_IMPL(name) { \
293296
PYBIND11_CHECK_PYTHON_VERSION \
297+
PYBIND11_ENSURE_INTERNALS_READY \
294298
auto m = pybind11::module(PYBIND11_TOSTRING(name)); \
295299
try { \
296300
PYBIND11_CONCAT(pybind11_init_, name)(m); \

0 commit comments

Comments
 (0)