#include "Py.h" #ifdef flagBOOSTPY using namespace boost::python; #endif NAMESPACE_UPP #ifdef flagBOOSTPY // Parses the value of the active python exception // NOTE SHOULD NOT BE CALLED IF NO EXCEPTION std::string parse_py_exception() { PyObject *type_ptr = NULL, *value_ptr = NULL, *traceback_ptr = NULL; // Fetch the exception info from the Python C API PyErr_Fetch(&type_ptr, &value_ptr, &traceback_ptr); // Fallback error std::string ret("Unfetchable Python error"); // If the fetch got a type pointer, parse the type into the exception string if(type_ptr != NULL){ handle<> h_type(type_ptr); str type_pstr(h_type); // Extract the string from the boost::python object extract e_type_pstr(type_pstr); // If a valid string extraction is available, use it // otherwise use fallback if(e_type_pstr.check()) ret = e_type_pstr(); else ret = "Unknown exception type"; } // Do the same for the exception value (the stringification of the exception) if(value_ptr != NULL){ handle<> h_val(value_ptr); str a(h_val); extract returned(a); if(returned.check()) ret += ": " + returned(); else ret += std::string(": Unparseable Python error: "); } // Parse lines from the traceback using the Python traceback module if(traceback_ptr != NULL){ handle<> h_tb(traceback_ptr); // Load the traceback module and the format_tb function object tb(import("traceback")); object fmt_tb(tb.attr("format_tb")); // Call format_tb to get a list of traceback strings object tb_list(fmt_tb(h_tb)); // Join the traceback strings into a single string object tb_str(str("\n").join(tb_list)); // Extract the string, check the extraction, and fallback in necessary extract returned(tb_str); if(returned.check()) ret += ": " + returned(); else ret += std::string(": Unparseable Python traceback"); } return ret; } #endif END_UPP_NAMESPACE