Скомпилируйте и выполните AST, используя pybind11 или Python C API - PullRequest
0 голосов
/ 02 ноября 2018

Я хотел бы перевести этот код Python в код C ++, используя Pybind11 или непосредственно 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"))

Вот что я сейчас использую в 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.

Я не уверен, что понимаю эту ошибку, я пытался передать globals и locals на exec, проблема не решилась.

РЕДАКТИРОВАТЬ : при прохождении globals, это говорит: SystemError: <built-in function globals> returned NULL without setting an error

Есть идеи, как этого добиться?

1 Ответ

0 голосов
/ 02 ноября 2018

Я нашел свой ответ, я не использовал функцию globals из Pybind11, а встроенную функцию из 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());
...