-
I've this #include <iostream>
#include <pybind11/embed.h>
namespace py = pybind11;
void test() {
py::scoped_interpreter guard;
try {
py::exec(R"(
import numpy
print("module loaded")
)");
} catch (py::error_already_set &e) {
std::cerr << e.what() << "\n";
}
}
int main() {
// py::scoped_interpreter guard; // If the `guard` is in the `main` scope, there is no issue.
test();
test(); // this call fails to import numpy
return 0;
} All the
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
This issue comes from Py_FinalizeEx. Basically, initialising and finalising python interpreter multiple times from a process can lead to undefined behaviour.
My solution at this point is to use a single #include <pybind11/embed.h>
namespace py = pybind11;
void test(const char *code) {
// Clear references to modules and variables from `__main__`
PyDict_Clear(PyModule_GetDict(PyImport_AddModule("__main__")));
py::exec(R"(
import numpy
print("module loaded")
)");
py::exec(code);
}
int main() {
py::scoped_interpreter guard;
test("x=1; print('First time', x)");
// I want this to fail with `NameError: name 'x' is not defined`
test("print('Second time', x)");
return 0;
} |
Beta Was this translation helpful? Give feedback.
This issue comes from Py_FinalizeEx. Basically, initialising and finalising python interpreter multiple times from a process can lead to undefined behaviour.
My solution at this point is to use a single
scoped_interpreter
and usePyDict_Clear
to clean variables from it. Not at all thread safe.