Commit bf2b0314 by Wenzel Jakob

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.
parent 4c206e8c
......@@ -218,6 +218,8 @@ extern "C" {
#define PYBIND11_STRINGIFY(x) #x
#define PYBIND11_TOSTRING(x) PYBIND11_STRINGIFY(x)
#define PYBIND11_CONCAT(first, second) first##second
#define PYBIND11_ENSURE_INTERNALS_READY \
pybind11::detail::get_internals();
#define PYBIND11_CHECK_PYTHON_VERSION \
{ \
......@@ -264,6 +266,7 @@ extern "C" {
static PyObject *pybind11_init(); \
PYBIND11_PLUGIN_IMPL(name) { \
PYBIND11_CHECK_PYTHON_VERSION \
PYBIND11_ENSURE_INTERNALS_READY \
try { \
return pybind11_init(); \
} PYBIND11_CATCH_INIT_EXCEPTIONS \
......@@ -291,6 +294,7 @@ extern "C" {
static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &); \
PYBIND11_PLUGIN_IMPL(name) { \
PYBIND11_CHECK_PYTHON_VERSION \
PYBIND11_ENSURE_INTERNALS_READY \
auto m = pybind11::module(PYBIND11_TOSTRING(name)); \
try { \
PYBIND11_CONCAT(pybind11_init_, name)(m); \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment