[BUG]: Issue with Re-registering Exceptions in Multiple Interpreter Lifecycles
nowtilous opened this issue · comments
Required prerequisites
- Make sure you've read the documentation. Your issue may be addressed there.
- Search the issue tracker and Discussions to verify that this hasn't already been reported. +1 or comment there if it has.
- Consider asking first in the Gitter chat room or in a Discussion.
What version (or hash if on master) of pybind11 are you using?
latest
Problem description
When registering an exception in a PYBIND11_MODULE scope (with pybind11::register_exception), pybind invokes allows this action only once per exception type.
This is due to the usage of gil_safe_call_once_and_store in register_exception_impl.
The issue is, that some programs require to initialize + deinitialize the interpreter multiple times within the program's life time.
So, everytime a module is created, the register_exception occurs, however, after the first time it is invoked, it will never be invoked again for the same exception class due to the usage of gil_safe_call_once_and_store (which calls std::call_once).
A simple solution for this is to not use the call_once in gil_safe_call_once_and_store, and simply registering the exception
whenever a registration is invoked, regardless of it being already invoked previously.
This is pretty simple, makes me wonder if this was intended.
Reproducible example code
// a definition of MyException...
PYBIND11_EMBEDDED_MODULE(sample, m) {
py::register_exception<MyException>(m, "MyException")
}
int main() {
py::initialize_interpreter();
py::exec("from sample import MyException");
py::finalize_interpreter(); // Here, the exception registration will be destroyed
py::initialize_interpreter();
// The following will fail due to ImportError of MyException!
py::exec("from sample import MyException");
py::finalize_interpreter();
return 0;
}
Is this a regression? Put the last known working version here if it is.
Not a regression