mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 22:02:49 -06:00
65 lines
2 KiB
C++
65 lines
2 KiB
C++
#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<std::string> 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<std::string> 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<std::string> returned(tb_str);
|
|
if(returned.check())
|
|
ret += ": " + returned();
|
|
else
|
|
ret += std::string(": Unparseable Python traceback");
|
|
}
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
END_UPP_NAMESPACE
|
|
|