Python从哪里获得其回溯信息?

2024-09-28 05:16:08 发布

您现在位置:Python中文网/ 问答频道 /正文

考虑以下verysimple.py

if '__main__' == __name__:
    prnt('Line1')

现在,如果我用> python verysimple.py执行它,我当然会受到以下的欢迎:

    Traceback (most recent call last):
        File "verysimple.py", line 2, in <module>
          prnt('Line1')
    NameError: name 'prnt' is not defined`

我想知道Python在中从何处提取回溯信息(尤其是错误的命令)。你知道吗

我已经试着在PyEval_FrameEx里面找到我的路,但是想不出来。。。你知道吗


Tags: nameinpymostifmainlinecall
1条回答
网友
1楼 · 发布于 2024-09-28 05:16:08

你在正确的轨道上。解析代码树时,它只需多次遍历PyEval_FrameEx。 最后,它将调用format_exc_check_arg()来格式化错误,这对我来说发生在pythonversion3.3.2源代码的ceval.c的第2100行。 format_exc_check_arg()推导出攻击性的“object”(prnt),并调用errors.c中的PyErr_Format,以正确格式化异常字符串(异常类型及其对应的字符串NAME_ERROR_MSG,已经从此行2100传递给format_exc_check_arg()。你知道吗

我只是使用以下代码进行测试:

prnt('Line1')

然后通过我周围的python3.3的debug build运行它。你知道吗

PyEval_FrameEx中的周围代码是

    TARGET(LOAD_NAME)
        w = GETITEM(names, oparg);
        if ((v = f->f_locals) == NULL) {
            PyErr_Format(PyExc_SystemError,
                         "no locals when loading %R", w);
            why = WHY_EXCEPTION;
            break;
        }
        if (PyDict_CheckExact(v)) {
            x = PyDict_GetItem(v, w);
            Py_XINCREF(x);
        }
        else {
            x = PyObject_GetItem(v, w);
            if (x == NULL && PyErr_Occurred()) {
                if (!PyErr_ExceptionMatches(
                                PyExc_KeyError))
                    break;
                PyErr_Clear();
            }
        }
        if (x == NULL) {
            x = PyDict_GetItem(f->f_globals, w);
            Py_XINCREF(x);
            if (x == NULL) {
                if (PyDict_CheckExact(f->f_builtins)) {
                    x = PyDict_GetItem(f->f_builtins, w);
                    if (x == NULL) {
// below is the line where the PyExc_NameError will be properly formatted.
                        format_exc_check_arg(
                                    PyExc_NameError,
                                    NAME_ERROR_MSG, w);
                        break;
                    }
                    Py_INCREF(x);
                }
                else {
                    x = PyObject_GetItem(f->f_builtins, w);
                    if (x == NULL) {
                        if (PyErr_ExceptionMatches(PyExc_KeyError))
                            format_exc_check_arg(
                                        PyExc_NameError,
                                        NAME_ERROR_MSG, w);
                        break;
                    }
                }
            }
        }
        PUSH(x);
        DISPATCH();

请注意,上面的两行PyDict_GetItem(...)将是试图在内置语句和函数中查找prnt的行(我从应用wf->builtins中推断出来,w本身是从上述代码中的第二条语句中获得的。 由于字典查找将失败,x == NULLNameError被设置并格式化。你知道吗

希望这能帮助你更进一步。你知道吗

相关问题 更多 >

    热门问题