diff --git a/docs/advanced/pycpp/utilities.rst b/docs/advanced/pycpp/utilities.rst index 442d0e9c9..e3d9c6c56 100644 --- a/docs/advanced/pycpp/utilities.rst +++ b/docs/advanced/pycpp/utilities.rst @@ -24,16 +24,10 @@ expected in Python: 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 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 // At beginning of file @@ -48,7 +42,7 @@ is always ``none``). int result = py::eval("my_variable + 10", scope).cast(); // Evaluate a sequence of statements - py::eval( + py::exec( "print('Hello')\n" "print('world!');", scope); @@ -62,7 +56,7 @@ the raw string delimiter ``R"(``, ensuring all lines have common leading indent: .. code-block:: cpp - py::eval(R"( + py::exec(R"( x = get_answer() if x == 42: print('Hello World!') @@ -70,3 +64,13 @@ the raw string delimiter ``R"(``, ensuring all lines have common leading indent: print('Bye!') )", 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``. diff --git a/include/pybind11/eval.h b/include/pybind11/eval.h index d4d26c12b..c829b0cb9 100644 --- a/include/pybind11/eval.h +++ b/include/pybind11/eval.h @@ -62,6 +62,15 @@ object eval(const char (&s)[N], object global = object(), object local = object( return eval(expr, global, local); } +inline void exec(str expr, object global = object(), object local = object()) { + eval(expr, global, local); +} + +template +void exec(const char (&s)[N], object global = object(), object local = object()) { + eval(s, global, local); +} + template object eval_file(str fname, object global = object(), object local = object()) { if (!global) { diff --git a/tests/test_eval.cpp b/tests/test_eval.cpp index 9a8ac216b..610d0e2e5 100644 --- a/tests/test_eval.cpp +++ b/tests/test_eval.cpp @@ -21,14 +21,14 @@ test_initializer eval([](py::module &m) { }); // Regular string literal - py::eval( + py::exec( "message = 'Hello World!'\n" "x = call_test()", global, local ); // Multi-line raw string literal - auto result = py::eval(R"( + py::exec(R"( if x == 42: print(message) else: @@ -37,7 +37,7 @@ test_initializer eval([](py::module &m) { ); auto x = local["x"].cast(); - return result.is_none() && x == 42; + return x == 42; }); m.def("test_eval", [global]() {