I am writing embedded python interpretor, there is a function PyErr_Print()
(https://docs.python.org/3/c-api/exceptions.html) which writes to standard error text explaining why C function I called failed.
This doesn't seem to work on windows as it never writes anything to terminal, is there a way to redirect it somewhere, or store as a string so that I can see it?
Here is a solution using boost::python:
#include <ostream>
#include <boost/python.hpp>
std::ostream& operator<<(std::ostream& os, boost::python::error_already_set& e) {
using namespace boost::python;
// acquire the Global Interpreter Lock
PyObject * extype, * value, * traceback;
PyErr_Fetch(&extype, &value, &traceback);
if (!extype) return os;
object o_extype(handle<>(borrowed(extype)));
object o_value(handle<>(borrowed(value)));
object o_traceback(handle<>(borrowed(traceback)));
object mod_traceback = import("traceback");
object lines = mod_traceback.attr("format_exception")(
o_extype, o_value, o_traceback);
for (int i = 0; i < len(lines); ++i)
os << extract<std::string>(lines[i])();
// PyErr_Fetch clears the error state, uncomment
// the following line to restore the error state:
// PyErr_Restore(extype, value, traceback);
// release the GIL
return os;
}
Use like this:
#include <iostream>
#include <boost/python.hpp>
try {
// some code that raises
catch (boost::python::error_already_set& e) {
std::cout << e << std::endl; // or stream to somewhere else
}