所以我有一个C程序,它使用嵌入式CPython解释器来执行Python代码。问题是如果Python代码有错误,解释器提供的行号信息就没用了,因为每次调用PyEval_EvalCodeEx
都会开始计算1行。所以,我想给出每当我执行代码时,Python解释器就行号而言是一个上下文。
有办法做到这一点吗?查看PyEval_EvalCodeEx
的定义,它最终是Python C-API公开的代码执行的最低级函数,我没有看到任何传递行号信息的机会。
文档只是阅读:
PyObject* PyEval_EvalCodeEx(PyObject *co, PyObject *globals, PyObject *locals, PyObject **args, int argcount, PyObject **kws, int kwcount, PyObject **defs, int defcount, PyObject *closure)
在给定特定环境的情况下,评估预编译的代码对象 评价。这个环境包括全球和世界的词典 局部变量,参数数组,关键字和默认值,以及a 关闭细胞元组。
这是不可能做到的?
答案 0 :(得分:1)
如果你看一下PyEval_EvalCodeEx()
的实现,你可能会看到第一个参数被转换为PyCodeObject *
,就在函数体的开头:
/* File: ceval.c */
PyObject *
PyEval_EvalCodeEx(PyObject *_co, ...)
{
PyCodeObject* co = (PyCodeObject*)_co;
...
}
如果您查看PyCodeObject
,就会有一个名为co_firstlineno
的成员:
/* File: code.h */
typedef struct {
PyObject_HEAD
...
PyObject *co_filename; /* unicode (where it was loaded from) */
PyObject *co_name; /* unicode (name, for reference) */
int co_firstlineno; /* first source line number */
PyObject *co_lnotab; /* string (encoding addr<->lineno mapping) See
Objects/lnotab_notes.txt for details. */
...
} PyCodeObject;
所以我想在调用co_firstfileno
函数之前修改PyEval_EvalCodeEx()
字段可能就足够了,如下所示:
((PyCodeObject *)co)->co_firstlineno = 42;
PyEval_EvalCodeEx(co, ...);
这应该足够了,据我所知,你甚至不需要修改co_lnotab
,因为它包含来自co_firstlineno
的偏移,而不是绝对位置。