【问题标题】:Using format_exc from Python 3.8.1 C API returns NoneType使用 Python 3.8.1 C API 中的 format_exc 返回 NoneType
【发布时间】:2020-01-30 19:19:02
【问题描述】:

我正在尝试在 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,这与在 except 子句之外调用 `traceback.format_exc' 相同。如何获取导致结果为 0 的异常的格式化回溯?

我也试过

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

确实得到了正确的值,(值是字符串division by zero),但是我不知道如何获得完整的回溯打印输出。

【问题讨论】:

    标签: python-3.x exception python-c-api


    【解决方案1】:

    我最终得到了我想要的结果:

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-01
      • 1970-01-01
      • 2021-05-13
      • 2019-05-10
      • 1970-01-01
      • 2017-08-25
      • 2021-11-10
      • 1970-01-01
      相关资源
      最近更新 更多