I would like to translate this Python code into C++ code using Pybind11 or directly the Python C API:
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"))
Here is what I have currently using 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);
Unfortunately, the last line of C++ code raises a runtime error: SystemError: frame does not exist
.
I'm not sure I understand this error, I tried to pass the globals
and locals
to exec
, it didn't solve the issue.
EDIT: When passing globals
, it says: SystemError: <built-in function globals> returned NULL without setting an error
Any idea on how to achieve this properly?
I found my answer, I wasn't using the globals
function from Pybind11, but the built-in one from Python (builtins.attr("globals")()
).
This is the working version:
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());