Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using format_exc from Python 3.8.1 C API returns NoneType

I'm trying to retreive an exception + traceback printout in a C extension.

I want to do the same thing as

try:
    print(0/0) # Throw a divide by zero
except:
    traceback_string = traceback.format_exc()

but in the C API so I can pass the resulting string over to the C side.

My attempt is as follows:

PyObject *result, *output;
PyObject *Python3Traceback;
char *string;

Python3Traceback = PyImport_ImportModule("traceback");

result = PyRun_String("0/0", Py_eval_input, globals, globals);
if (result == 0) {
    output = PyObject_CallMethod(Python3Traceback, "format_exc", "()");
    string = PyUnicode_AsUTF8AndSize(output, &length);
}

However string always comes back with the value NoneType: None, which is the same as calling `traceback.format_exc' outside an except clause. How can I get at the formatted traceback for the exception that caused result to be 0 ?

I've also tried

PyObject *type, *value, *traceback;
PyErr_Fetch(&type, &value, &traceback);
output = PyObject_ASCII(value);
string = PyUnicode_AsUTF8AndSize(output, &length);

Which does get the right values, (value is the string division by zero), but then I can't work out how to get the full traceback printout.

like image 713
RFairey Avatar asked Aug 09 '26 19:08

RFairey


1 Answers

I got the result I was after in the end with the following:

PyErr_Fetch(&type, &value, &traceback);
PyErr_NormalizeException(&type, &value, &traceback);
if (traceback2 != NULL) {
    PyException_SetTraceback(value, traceback);
}
output = PyObject_CallMethod(Python3Traceback, "format_exception", "(OOO)", type, value, traceback);
concat = PyObject_CallMethod(Py_BuildValue("s", ""), "join", "(O)", output);
string = PyUnicode_AsUTF8AndSize(concat, &length);

But I still don't know why calling PyErr_Fetch gets me the current exception information, while calling PyObject_CallMethod(Python3Traceback, "format_exc"...) gives None.

like image 129
RFairey Avatar answered Aug 11 '26 08:08

RFairey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!