如何检索 SyntaxError 的文件名和 lineno 属性 [英] How to retrieve filename and lineno attribute of SyntaxError

查看:62
本文介绍了如何检索 SyntaxError 的文件名和 lineno 属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的应用程序中嵌入了 python 解释器.我使用它使用 PyRun_String() API 运行 python 脚本.如果遇到错误/异常,我可以使用 PyErr_Fetch() 获取错误信息.这给了我异常类型、异常值和异常回溯.然后我从回溯中找到起源错误的行号.但是,在语法错误的情况下,我不会得到任何类型的回溯.有谁知道如何在没有回溯的情况下检索行号..?有没有办法使用异常类型或异常值来检索它..?

I have embedded python interpreter in my application. I use it to run python scripts using PyRun_String() API. I can fetch error information using PyErr_Fetch() if an error/exception encounters. This gives me exception type, exception value and exception traceback. I then find line number of the originated error from traceback. However, i dont get any kind of traceback in case of Syntax Error. Do anybody know how to retrieve line number without traceback..? Is there any way to retreive it using exception type or exception value..?

Python 文档指出:

Python documentation stated that:

此类的实例具有属性文件名、行号、偏移量和文本,以便于访问详细信息.异常实例的 str() 只返回消息.

Instances of this class have attributes filename, lineno, offset and text for easier access to the details. str() of the exception instance returns only the message.

如何在嵌入式python..中检索SyntaxError的文件名和lineno属性?

How do I retrieve filename and lineno attribute of SyntaxError in embedded python..?

任何帮助将不胜感激.提前致谢.

Any help will be appreciated. Thanks in advance.

感谢您的建议布雷特.但是我已经使用 PyObject_GetAttr() 尝试过了.

Thanks for your suggestion Brett. But I already tried it by using PyObject_GetAttr().

请参阅下面我用于测试目的的示例代码.

Please see below sample code that I used for testing purpose.

int main(int argc, char** argv)
{
    Py_Initialize();

    // Get a reference to the main module.
    PyObject* main_module =
        PyImport_AddModule("__main__");

    // Get the main module's dictionary
    // and make a copy of it.
    PyObject* main_dict =
        PyModule_GetDict(main_module);

    const char *script_source = "def main():\n\tprint('Hello'\n\nmain()";

    PyObject *res = PyRun_String(script_source,Py_file_input,main_dict,main_dict);
    if(res == NULL)
    {
        PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL;
        PyErr_Fetch(&ptype,&pvalue,&ptraceback);

        PyObject* py_filename = PyUnicode_FromString("filename");
        PyObject* file_name = PyObject_GetAttr(ptype,py_filename);

        PyObject* py_lineno = PyUnicode_FromString("lineno");
        PyObject* line_no = PyObject_GetAttr(ptype,py_lineno);
    }
}

我故意在 script_source 中插入了一个语法错误.

I have intentionally inserted a syntax error in script_source.

我无法从 file_name 和 line_no 对象中检索实际文件名和行号.

I am unable to retrieve actual file name and line number from file_name and line_no objects.

我尝试调试 file_name 和 line_no 对象,内容如下所示.语法错误对象的成员文件名"和语法错误对象的成员行号"

I tried to debug file_name and line_no objects and the content's looks like below. "member filename of Syntax Error Objects" and "member lineno of Syntax Error Objects"

这些对象不可调用,所以我不能在这些对象上使用 PyObject_Call() 变体.

These objects are not callable so I can't use PyObject_Call() variant's over these.

有什么办法可以让我从这些对象的..中获得实际的文件名和行号吗?

Is there any way so that I can get actual file name and line number from these object's..?

在这个文件名中将是我使用的 PyRun_String().

In this file name will be as I am using PyRun_String().

推荐答案

我通过以下方式解决了它.我在 PyErr_Fetch() 之后使用了 PyErr_NormalizeException() 并且代码现在工作正常.

I resolved it in following way. I used PyErr_NormalizeException() after PyErr_Fetch() and code is working fine now.

int main(int argc, char** argv)
{
    Py_Initialize();

    // Get a reference to the main module.
    PyObject* main_module =
        PyImport_AddModule("__main__");

    // Get the main module's dictionary
    // and make a copy of it.
    PyObject* main_dict =
        PyModule_GetDict(main_module);

    const char *script_source = "def main():\n\tprint('Hello'\n\nmain()";

    PyObject *res = PyRun_String(script_source,Py_file_input,main_dict,main_dict);
    if(res == NULL)
    {
        PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL;
        PyErr_Fetch(&ptype,&pvalue,&ptraceback);
        PyErr_NormalizeException(&ptype,&pvalue,&ptraceback);

        char *msg;
        char *file;
        int line;
        int offset;
        char *text;

        int res = PyArg_ParseTuple(pvalue,"s(siis)",&msg,&file,&line,&offset,&text);

        PyObject* file_name = PyObject_GetAttrString(pvalue,"filename");
        PyObject* file_name_str = PyObject_Str(file_name);
        PyObject* file_name_unicode = PyUnicode_AsEncodedString(file_name_str,"utf-8", "Error");
        char *actual_file_name = PyBytes_AsString(file_name_unicode);

        PyObject* line_no = PyObject_GetAttrString(pvalue,"lineno");
        PyObject* line_no_str = PyObject_Str(line_no);
        PyObject* line_no_unicode = PyUnicode_AsEncodedString(line_no_str,"utf-8", "Error");
        char *actual_line_no = PyBytes_AsString(line_no_unicode);

        printf("done");
    }
}

这篇关于如何检索 SyntaxError 的文件名和 lineno 属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆