1/* 2 tests/test_eval.cpp -- Usage of eval() and eval_file() 3 4 Copyright (c) 2016 Klemens D. Morgenstern 5 6 All rights reserved. Use of this source code is governed by a 7 BSD-style license that can be found in the LICENSE file. 8*/ 9 10 11#include <pybind11/eval.h> 12#include "pybind11_tests.h" 13 14TEST_SUBMODULE(eval_, m) { 15 // test_evals 16 17 auto global = py::dict(py::module::import("__main__").attr("__dict__")); 18 19 m.def("test_eval_statements", [global]() { 20 auto local = py::dict(); 21 local["call_test"] = py::cpp_function([&]() -> int { 22 return 42; 23 }); 24 25 // Regular string literal 26 py::exec( 27 "message = 'Hello World!'\n" 28 "x = call_test()", 29 global, local 30 ); 31 32 // Multi-line raw string literal 33 py::exec(R"( 34 if x == 42: 35 print(message) 36 else: 37 raise RuntimeError 38 )", global, local 39 ); 40 auto x = local["x"].cast<int>(); 41 42 return x == 42; 43 }); 44 45 m.def("test_eval", [global]() { 46 auto local = py::dict(); 47 local["x"] = py::int_(42); 48 auto x = py::eval("x", global, local); 49 return x.cast<int>() == 42; 50 }); 51 52 m.def("test_eval_single_statement", []() { 53 auto local = py::dict(); 54 local["call_test"] = py::cpp_function([&]() -> int { 55 return 42; 56 }); 57 58 auto result = py::eval<py::eval_single_statement>("x = call_test()", py::dict(), local); 59 auto x = local["x"].cast<int>(); 60 return result.is_none() && x == 42; 61 }); 62 63 m.def("test_eval_file", [global](py::str filename) { 64 auto local = py::dict(); 65 local["y"] = py::int_(43); 66 67 int val_out; 68 local["call_test2"] = py::cpp_function([&](int value) { val_out = value; }); 69 70 auto result = py::eval_file(filename, global, local); 71 return val_out == 43 && result.is_none(); 72 }); 73 74 m.def("test_eval_failure", []() { 75 try { 76 py::eval("nonsense code ..."); 77 } catch (py::error_already_set &) { 78 return true; 79 } 80 return false; 81 }); 82 83 m.def("test_eval_file_failure", []() { 84 try { 85 py::eval_file("non-existing file"); 86 } catch (std::exception &) { 87 return true; 88 } 89 return false; 90 }); 91} 92