test_eval.cpp 3.06 KB
Newer Older
Klemens Morgenstern's avatar
Klemens Morgenstern committed
1
/*
Dean Moldovan's avatar
Dean Moldovan committed
2
    tests/test_eval.cpp -- Usage of eval() and eval_file()
Klemens Morgenstern's avatar
Klemens Morgenstern committed
3
4
5
6
7
8
9
10

    Copyright (c) 2016 Klemens D. Morgenstern

    All rights reserved. Use of this source code is governed by a
    BSD-style license that can be found in the LICENSE file.
*/


11
#include <pybind11/eval.h>
12

Dean Moldovan's avatar
Dean Moldovan committed
13
#include "pybind11_tests.h"
14
#include <utility>
Klemens Morgenstern's avatar
Klemens Morgenstern committed
15

16
17
18
TEST_SUBMODULE(eval_, m) {
    // test_evals

19
    auto global = py::dict(py::module_::import("__main__").attr("__dict__"));
20
21
22
23
24
25

    m.def("test_eval_statements", [global]() {
        auto local = py::dict();
        local["call_test"] = py::cpp_function([&]() -> int {
            return 42;
        });
Klemens Morgenstern's avatar
Klemens Morgenstern committed
26

27
        // Regular string literal
28
        py::exec(
29
30
            "message = 'Hello World!'\n"
            "x = call_test()",
31
32
            global, local
        );
33
34

        // Multi-line raw string literal
35
        py::exec(R"(
36
37
38
39
40
41
            if x == 42:
                print(message)
            else:
                raise RuntimeError
            )", global, local
        );
42
        auto x = local["x"].cast<int>();
Klemens Morgenstern's avatar
Klemens Morgenstern committed
43

44
        return x == 42;
45
    });
Klemens Morgenstern's avatar
Klemens Morgenstern committed
46

47
48
49
50
51
52
    m.def("test_eval", [global]() {
        auto local = py::dict();
        local["x"] = py::int_(42);
        auto x = py::eval("x", global, local);
        return x.cast<int>() == 42;
    });
Klemens Morgenstern's avatar
Klemens Morgenstern committed
53

54
55
56
57
58
    m.def("test_eval_single_statement", []() {
        auto local = py::dict();
        local["call_test"] = py::cpp_function([&]() -> int {
            return 42;
        });
Klemens Morgenstern's avatar
Klemens Morgenstern committed
59

60
61
        auto result = py::eval<py::eval_single_statement>("x = call_test()", py::dict(), local);
        auto x = local["x"].cast<int>();
62
        return result.is_none() && x == 42;
63
64
65
66
67
68
    });

    m.def("test_eval_file", [global](py::str filename) {
        auto local = py::dict();
        local["y"] = py::int_(43);

69
        int val_out = 0;
70
71
        local["call_test2"] = py::cpp_function([&](int value) { val_out = value; });

72
        auto result = py::eval_file(std::move(filename), global, local);
73
        return val_out == 43 && result.is_none();
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
    });

    m.def("test_eval_failure", []() {
        try {
            py::eval("nonsense code ...");
        } catch (py::error_already_set &) {
            return true;
        }
        return false;
    });

    m.def("test_eval_file_failure", []() {
        try {
            py::eval_file("non-existing file");
        } catch (std::exception &) {
            return true;
        }
        return false;
    });
93
94
95
96
97
98
99
100

    // test_eval_empty_globals
    m.def("eval_empty_globals", [](py::object global) {
        if (global.is_none())
            global = py::dict();
        auto int_class = py::eval("isinstance(42, int)", global);
        return global;
    });
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

    // test_eval_closure
    m.def("test_eval_closure", []() {
        py::dict global;
        global["closure_value"] = 42;
        py::dict local;
        local["closure_value"] = 0;
        py::exec(R"(
            local_value = closure_value

            def func_global():
                return closure_value

            def func_local():
                return local_value
            )", global, local);
        return std::make_pair(global, local);
    });
119
}