mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 13:15:12 +00:00
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.
This commit is contained in:
parent
4c206e8c79
commit
bf2b031449
@ -218,6 +218,8 @@ extern "C" {
|
|||||||
#define PYBIND11_STRINGIFY(x) #x
|
#define PYBIND11_STRINGIFY(x) #x
|
||||||
#define PYBIND11_TOSTRING(x) PYBIND11_STRINGIFY(x)
|
#define PYBIND11_TOSTRING(x) PYBIND11_STRINGIFY(x)
|
||||||
#define PYBIND11_CONCAT(first, second) first##second
|
#define PYBIND11_CONCAT(first, second) first##second
|
||||||
|
#define PYBIND11_ENSURE_INTERNALS_READY \
|
||||||
|
pybind11::detail::get_internals();
|
||||||
|
|
||||||
#define PYBIND11_CHECK_PYTHON_VERSION \
|
#define PYBIND11_CHECK_PYTHON_VERSION \
|
||||||
{ \
|
{ \
|
||||||
@ -264,6 +266,7 @@ extern "C" {
|
|||||||
static PyObject *pybind11_init(); \
|
static PyObject *pybind11_init(); \
|
||||||
PYBIND11_PLUGIN_IMPL(name) { \
|
PYBIND11_PLUGIN_IMPL(name) { \
|
||||||
PYBIND11_CHECK_PYTHON_VERSION \
|
PYBIND11_CHECK_PYTHON_VERSION \
|
||||||
|
PYBIND11_ENSURE_INTERNALS_READY \
|
||||||
try { \
|
try { \
|
||||||
return pybind11_init(); \
|
return pybind11_init(); \
|
||||||
} PYBIND11_CATCH_INIT_EXCEPTIONS \
|
} PYBIND11_CATCH_INIT_EXCEPTIONS \
|
||||||
@ -291,6 +294,7 @@ extern "C" {
|
|||||||
static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &); \
|
static void PYBIND11_CONCAT(pybind11_init_, name)(pybind11::module &); \
|
||||||
PYBIND11_PLUGIN_IMPL(name) { \
|
PYBIND11_PLUGIN_IMPL(name) { \
|
||||||
PYBIND11_CHECK_PYTHON_VERSION \
|
PYBIND11_CHECK_PYTHON_VERSION \
|
||||||
|
PYBIND11_ENSURE_INTERNALS_READY \
|
||||||
auto m = pybind11::module(PYBIND11_TOSTRING(name)); \
|
auto m = pybind11::module(PYBIND11_TOSTRING(name)); \
|
||||||
try { \
|
try { \
|
||||||
PYBIND11_CONCAT(pybind11_init_, name)(m); \
|
PYBIND11_CONCAT(pybind11_init_, name)(m); \
|
||||||
|
Loading…
Reference in New Issue
Block a user