CPython -打印回溯

ubof19bj  于 2023-06-04  发布在  Python
关注(0)|答案(1)|浏览(172)

如何在CPython中将回溯对象转换为它的字符串表示?我试过了,但输出不是很有用。

PyObject *type, *value, *traceback;
    PyErr_Fetch(&type, &value, &traceback);

    PyObject* strTrace = PyObject_Repr(traceback);
    pyStrTrace = PyUnicode_AsEncodedString(strTrace, "utf-8", "strict");
    Py_XDECREF(strTrace);
    const char* sTrace = PyBytes_AS_STRING(pyStrTrace);

sTrace的内容:

<traceback object at 0x000002594A5CC598>
dnph8jn4

dnph8jn41#

一条评论建议导入traceback python模块,这肯定会工作得很好,但我更喜欢C++的解决方案,所以我想出了这个片段。希望有人会觉得有用。
首先包括Python的<frameobject.h>

if (PyTraceBack_Check(traceback))
{
    PyTracebackObject* traceRoot = (PyTracebackObject*)traceback;
    PyTracebackObject* pTrace = traceRoot;
    
    while (pTrace != NULL)
    {
        PyFrameObject* frame = pTrace->tb_frame;
        PyCodeObject* code = frame->f_code;

        int lineNr = PyFrame_GetLineNumber(frame);
        const char *sCodeName = PyUnicode_AsUTF8(code->co_name);
        const char *sFileName = PyUnicode_AsUTF8(code->co_filename);

        printf("at %s (%s:%d); ", sCodeName, sFileName, lineNr);
        pTrace = pTrace->tb_next;
    }        
}

从Python 3.11开始,frame->f_code不再可用(PyFrameObject被私有化)。更新日志中建议使用PyFrame_GetCode(frame)
同样,这也消除了包含<frameobject.h>的需要
为了向后兼容,你可以自己实现这个函数:

#if PY_VERSION_HEX < 0x030900B1
#include <frameobject.h>
static inline PyCodeObject* PyFrame_GetCode(PyFrameObject *frame)
{
    Py_INCREF(frame->f_code);
    return frame->f_code;
}
#endif

相关问题