Использование format_ex c из Python 3.8.1 C API возвращает NoneType - PullRequest
0 голосов
/ 30 января 2020

Я пытаюсь получить распечатку исключения + трассировки в расширении C.

Я хочу сделать то же самое, что и

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

, но в C API, чтобы я мог передать полученную строку на сторону C.

Моя попытка заключается в следующем:

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);
}

Однако строка всегда возвращается со значением NoneType: None, что аналогично вызову `traceback.format_ex c 'вне условия исключения. Как я могу получить отформатированную трассировку для исключения, которое привело к результату, равному 0?

Я также попытался

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

, который действительно получает правильные значения, (значение - строка division by zero), но тогда я не могу понять, как получить полную распечатку трассировки.

1 Ответ

0 голосов
/ 03 февраля 2020

В итоге я получил результат, который был после, со следующим:

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);

Но я до сих пор не знаю, почему вызов PyErr_Fetch возвращает мне информацию о текущем исключении, а вызов PyObject_CallMethod(Python3Traceback, "format_exc"...) дает None.

...