mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 05:05:11 +00:00
Support raw string literals as input for py::eval (#766)
* Support raw string literals as input for py::eval * Dedent only when needed
This commit is contained in:
parent
6db60cd945
commit
194d8b99b3
@ -55,3 +55,18 @@ is always ``none``).
|
|||||||
|
|
||||||
// Evaluate the statements in an separate Python file on disk
|
// Evaluate the statements in an separate Python file on disk
|
||||||
py::eval_file("script.py", scope);
|
py::eval_file("script.py", scope);
|
||||||
|
|
||||||
|
C++11 raw string literals are also supported and quite handy for this purpose.
|
||||||
|
The only requirement is that the first statement must be on a new line following
|
||||||
|
the raw string delimiter ``R"(``, ensuring all lines have common leading indent:
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
py::eval<py::eval_statements>(R"(
|
||||||
|
x = get_answer()
|
||||||
|
if x == 42:
|
||||||
|
print('Hello World!')
|
||||||
|
else:
|
||||||
|
print('Bye!')
|
||||||
|
)", scope
|
||||||
|
);
|
||||||
|
@ -11,8 +11,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "pybind11.h"
|
#include "pybind11.h"
|
||||||
|
|
||||||
NAMESPACE_BEGIN(pybind11)
|
NAMESPACE_BEGIN(pybind11)
|
||||||
@ -56,6 +54,14 @@ object eval(str expr, object global = object(), object local = object()) {
|
|||||||
return reinterpret_steal<object>(result);
|
return reinterpret_steal<object>(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <eval_mode mode = eval_expr, size_t N>
|
||||||
|
object eval(const char (&s)[N], object global = object(), object local = object()) {
|
||||||
|
/* Support raw string literals by removing common leading whitespace */
|
||||||
|
auto expr = (s[0] == '\n') ? str(module::import("textwrap").attr("dedent")(s))
|
||||||
|
: str(s);
|
||||||
|
return eval<mode>(expr, 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) {
|
||||||
|
@ -20,11 +20,21 @@ test_initializer eval([](py::module &m) {
|
|||||||
return 42;
|
return 42;
|
||||||
});
|
});
|
||||||
|
|
||||||
auto result = py::eval<py::eval_statements>(
|
// Regular string literal
|
||||||
"print('Hello World!');\n"
|
py::eval<py::eval_statements>(
|
||||||
"x = call_test();",
|
"message = 'Hello World!'\n"
|
||||||
|
"x = call_test()",
|
||||||
global, local
|
global, local
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Multi-line raw string literal
|
||||||
|
auto result = py::eval<py::eval_statements>(R"(
|
||||||
|
if x == 42:
|
||||||
|
print(message)
|
||||||
|
else:
|
||||||
|
raise RuntimeError
|
||||||
|
)", global, local
|
||||||
|
);
|
||||||
auto x = local["x"].cast<int>();
|
auto x = local["x"].cast<int>();
|
||||||
|
|
||||||
return result == py::none() && x == 42;
|
return result == py::none() && x == 42;
|
||||||
|
Loading…
Reference in New Issue
Block a user