Add py::exec() as a shortcut for py::eval<py::eval_statements>()

This commit is contained in:
Dean Moldovan 2017-04-30 01:53:06 +02:00
parent 0c4e0372a3
commit 076c738641
3 changed files with 25 additions and 12 deletions

View File

@ -24,16 +24,10 @@ expected in Python:
Evaluating Python expressions from strings and files Evaluating Python expressions from strings and files
==================================================== ====================================================
pybind11 provides the :func:`eval` and :func:`eval_file` functions to evaluate pybind11 provides the `eval`, `exec` and `eval_file` functions to evaluate
Python expressions and statements. The following example illustrates how they Python expressions and statements. The following example illustrates how they
can be used. can be used.
Both functions accept a template parameter that describes how the argument
should be interpreted. Possible choices include ``eval_expr`` (isolated
expression), ``eval_single_statement`` (a single statement, return value is
always ``none``), and ``eval_statements`` (sequence of statements, return value
is always ``none``).
.. code-block:: cpp .. code-block:: cpp
// At beginning of file // At beginning of file
@ -48,7 +42,7 @@ is always ``none``).
int result = py::eval("my_variable + 10", scope).cast<int>(); int result = py::eval("my_variable + 10", scope).cast<int>();
// Evaluate a sequence of statements // Evaluate a sequence of statements
py::eval<py::eval_statements>( py::exec(
"print('Hello')\n" "print('Hello')\n"
"print('world!');", "print('world!');",
scope); scope);
@ -62,7 +56,7 @@ the raw string delimiter ``R"(``, ensuring all lines have common leading indent:
.. code-block:: cpp .. code-block:: cpp
py::eval<py::eval_statements>(R"( py::exec(R"(
x = get_answer() x = get_answer()
if x == 42: if x == 42:
print('Hello World!') print('Hello World!')
@ -70,3 +64,13 @@ the raw string delimiter ``R"(``, ensuring all lines have common leading indent:
print('Bye!') print('Bye!')
)", scope )", scope
); );
.. note::
`eval` and `eval_file` accept a template parameter that describes how the
string/file should be interpreted. Possible choices include ``eval_expr``
(isolated expression), ``eval_single_statement`` (a single statement, return
value is always ``none``), and ``eval_statements`` (sequence of statements,
return value is always ``none``). `eval` defaults to ``eval_expr``,
`eval_file` defaults to ``eval_statements`` and `exec` is just a shortcut
for ``eval<eval_statements>``.

View File

@ -62,6 +62,15 @@ object eval(const char (&s)[N], object global = object(), object local = object(
return eval<mode>(expr, global, local); return eval<mode>(expr, global, local);
} }
inline void exec(str expr, object global = object(), object local = object()) {
eval<eval_statements>(expr, global, local);
}
template <size_t N>
void exec(const char (&s)[N], object global = object(), object local = object()) {
eval<eval_statements>(s, global, local);
}
template <eval_mode mode = eval_statements> template <eval_mode mode = eval_statements>
object eval_file(str fname, object global = object(), object local = object()) { object eval_file(str fname, object global = object(), object local = object()) {
if (!global) { if (!global) {

View File

@ -21,14 +21,14 @@ test_initializer eval([](py::module &m) {
}); });
// Regular string literal // Regular string literal
py::eval<py::eval_statements>( py::exec(
"message = 'Hello World!'\n" "message = 'Hello World!'\n"
"x = call_test()", "x = call_test()",
global, local global, local
); );
// Multi-line raw string literal // Multi-line raw string literal
auto result = py::eval<py::eval_statements>(R"( py::exec(R"(
if x == 42: if x == 42:
print(message) print(message)
else: else:
@ -37,7 +37,7 @@ test_initializer eval([](py::module &m) {
); );
auto x = local["x"].cast<int>(); auto x = local["x"].cast<int>();
return result.is_none() && x == 42; return x == 42;
}); });
m.def("test_eval", [global]() { m.def("test_eval", [global]() {