gpt4 book ai didi

Python C++ API : How to retrieve lineno attribute of NameError

转载 作者:行者123 更新时间:2023-11-30 19:32:40 25 4
gpt4 key购买 nike

我正在使用 C/C++ 的 python API,我想检索发生名称错误时的行号。

我按照以下问题中的说明进行操作:

How to retrieve filename and lineno attribute of SyntaxError

我写了以下代码:

PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL;
PyObject *comp = NULL, *eval = NULL;
char code[] = {"A=undef_var"};

comp = Py_CompileString(code, "", Py_file_input);
if (comp) {
eval = PyEval_EvalCode(comp, PyEval_GetBuiltins(), NULL);
}
if (!comp || !eval) {
PyErr_PrintEx(1); // inside this function the PyErr_Fetch(ptype, pvalue, ptraceback) is called

// retrieve the information gained from PyErr_Fetch() called inside PyErr_PrintEx(1)
pvalue = PySys_GetObject("last_value");
ptype = PySys_GetObject("last_type");
ptraceback = PySys_GetObject("last_traceback");
PyErr_NormalizeException(ptype, pvalue, ptraceback);

PyObject* line_no = PyObject_GetAttrString(pvalue,"lineno");
if (line_no) {
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);
}
}

上面的代码返回正确的行号,以防 python 代码包含一个 SyntaxError (例如,对于像“A=”这样的简单 python 代码),但如果出现 NameError,则行号未正确设置为 pvalue 对象(例如,对于 python 代码:“A=undefined_var”)。

有什么想法可以解决这个问题吗?

最佳答案

在 @Antti Haapala 的帮助下并考虑发布到此 question 的解决方案我得出以下解决方案:

PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL;
PyObject *compile_obj = NULL, *eval_obj = NULL;
PyObject *line_no = NULL, *line_no_str = NULL, *line_no_unicode = NULL;
char *actual_line_no = NULL;
char code[] = { "A=undef_var" };
int line_num = 0;

compile_obj = Py_CompileString(code, "", Py_file_input);
if (compile_obj) {
eval_obj = PyImport_ExecCodeModule((char *)"", compile_obj);
}
if (!compile_obj || !eval_obj) {
PyErr_PrintEx(1); // inside this function the PyErr_Fetch(ptype, pvalue, ptraceback) is called
// retrieve the information gained from PyErr_Fetch() called inside PyErr_PrintEx(1)
pvalue = PySys_GetObject("last_value");
ptype = PySys_GetObject("last_type");
ptraceback = PySys_GetObject("last_traceback");
if (ptype) {
PyErr_NormalizeException(&ptype, &pvalue, &ptraceback);
}
if (compile_obj) { // NameError
if (ptraceback) {
PyTracebackObject *tb_o = (PyTracebackObject *)ptraceback;
line_num = tb_o->tb_lineno;
}
} else { //Syntax Error
line_no = PyObject_GetAttrString(pvalue, "lineno");
if (line_no) {
line_no_str = PyObject_Str(line_no);
if (line_no_str) line_no_unicode = PyUnicode_AsEncodedString(line_no_str, "utf-8", "Error");
if (line_no_unicode) actual_line_no = PyBytes_AsString(line_no_unicode);
if (actual_line_no) line_num = atoi(actual_line_no);

Py_XDECREF(line_no);
Py_XDECREF(line_no_str);
Py_XDECREF(line_no_unicode);
}
}
}
Py_XDECREF(compile_obj);
Py_XDECREF(eval_obj);

return line_num;

关于Python C++ API : How to retrieve lineno attribute of NameError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46825656/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com