python - 将行号传递给嵌入式 Python 解释器

标签 python c python-3.x python-c-api cpython

所以我有一个 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)

Evaluate a precompiled code object, given a particular environment for its evaluation. This environment consists of dictionaries of global and local variables, arrays of arguments, keywords and defaults, and a closure tuple of cells.

那么这是不可能做到的吗?

最佳答案

如果您查看 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;

所以我想在调用 PyEval_EvalCodeEx() 函数之前修改 co_firstfileno 字段可能就足够了,如下所示:

((PyCodeObject *)co)->co_firstlineno = 42;
PyEval_EvalCodeEx(co, ...);

这应该足够了,据我记得,您甚至不需要修改 co_lnotab,因为它包含与 co_firSTLineno 的偏移量,而不是绝对位置.

关于python - 将行号传递给嵌入式 Python 解释器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24827224/

相关文章:

c - 如何从正确存储的函数中获取该值?

c - 在 C 中调用 fgets 时出现段错误

python - 如何从 http.client.HTTPResponse 对象中获取 URL?

python - 使用新类型重新抛出 Python 异常

c - .h注释: previous declaration of 'QueueADT' was here typedef struct { } *QueueADT;

python - "return"和 "return None"生成器中的行为差异

python-3.x - python 3 datetime.strptime 不适用于德语格式

python - 更改 IPython 解释器

python - 可以使用 cmd ">>"登录 Django 开发服务器吗?

python - asyncio.Semaphore 运行时错误 : Task got Future attached to a different loop