【问题标题】:Compile and execute AST using pybind11 or Python C API使用 pybind11 或 Python C API 编译和执行 AST
【发布时间】:2018-11-02 09:07:14
【问题描述】:

我想使用 Pybind11 或直接使用 Python C API 将此 Python 代码转换为 C++ 代码:

import ast

code = "print('Hello World!')"

code_ast = ast.parse(code, mode="exec") # "code" being a string containing code
# ... perform some modifications on "code_ast"
exec(compile(code_ast, filename="<ast>", mode="exec"))

这是我目前使用的 Pybind11:

#include <iostream>
#include "pybind11/embed.h"

namespace py = pybind11;

std::string code = "print('Hello World!')";

py::module ast = py::module::import("ast");
py::module builtins = py::module::import("builtins");

py::object code_ast = ast.attr("parse")(code, "<unknown>", "exec");
// ... perform some modifications on "code_ast"
py::object compiled_code = builtins.attr("compile")(code_ast, "<ast>", "exec");
builtins.attr("exec")(compiled_code);

不幸的是,最后一行 C++ 代码引发了运行时错误:SystemError: frame does not exist

我不确定我是否理解此错误,我尝试将globalslocals 传递给exec,但没有解决问题。

编辑:当传递globals时,它说:SystemError: &lt;built-in function globals&gt; returned NULL without setting an error

知道如何正确实现这一点吗?

【问题讨论】:

  • 您应该发布minimal reproducible example,由于某种原因缺少框架对象,这与您发布的代码无关。您发布的代码很好。
  • 我的代码中没有框架对象,它是 Python 解释器的内部对象。发布的代码不好,解释器抱怨,因为我没有将全局命名空间传递给 exec 函数。
  • 唯一缺少的是所需头文件的include,我将编辑问题。

标签: python c++ abstract-syntax-tree python-c-api pybind11


【解决方案1】:

我找到了答案,我没有使用 Pybind11 中的 globals 函数,而是 Python 中的内置函数 (builtins.attr("globals")())。

这是工作版本:

py::module ast = py::module::import("ast");
py::module builtins = py::module::import("builtins");

py::object code_ast = ast.attr("parse")(code, "<unknown>", "exec");
// ... perform some modifications on "code_ast"
py::object compiled_code = builtins.attr("compile")(code_ast, "<ast>", "exec");
builtins.attr("exec")(compiled_code, py::globals());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-21
    • 2020-11-14
    • 1970-01-01
    • 2011-10-27
    • 2016-01-15
    • 2015-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多