From f07d5069d86e31ecf195664850f79fb00c445bd3 Mon Sep 17 00:00:00 2001 From: Jason Lowe-Power Date: Fri, 17 Nov 2017 17:02:05 -0800 Subject: ext: Upgrade PyBind11 to version 2.2.1 This upgrade is necessary for pybind to build with GCC 7.2. We still need to add the patch for stl.h. MSC_FULL_VER change is no longer needed. See https://gem5-review.googlesource.com/c/public/gem5/+/2230 Change-Id: I806729217d022070583994c2dfcaa74476aef30f Signed-off-by: Jason Lowe-Power Reviewed-on: https://gem5-review.googlesource.com/5801 Reviewed-by: Andreas Sandberg Maintainer: Andreas Sandberg --- ext/pybind11/tests/test_callbacks.cpp | 167 ++++++++++++++-------------------- 1 file changed, 67 insertions(+), 100 deletions(-) (limited to 'ext/pybind11/tests/test_callbacks.cpp') diff --git a/ext/pybind11/tests/test_callbacks.cpp b/ext/pybind11/tests/test_callbacks.cpp index f89cc1c79..273eacc30 100644 --- a/ext/pybind11/tests/test_callbacks.cpp +++ b/ext/pybind11/tests/test_callbacks.cpp @@ -12,97 +12,20 @@ #include -py::object test_callback1(py::object func) { - return func(); -} - -py::tuple test_callback2(py::object func) { - return func("Hello", 'x', true, 5); -} - -std::string test_callback3(const std::function &func) { - return "func(43) = " + std::to_string(func(43)); -} - -std::function test_callback4() { - return [](int i) { return i+1; }; -} - -py::cpp_function test_callback5() { - return py::cpp_function([](int i) { return i+1; }, - py::arg("number")); -} - int dummy_function(int i) { return i + 1; } -int dummy_function2(int i, int j) { return i + j; } -std::function roundtrip(std::function f, bool expect_none = false) { - if (expect_none && f) { - throw std::runtime_error("Expected None to be converted to empty std::function"); - } - return f; -} -std::string test_dummy_function(const std::function &f) { - using fn_type = int (*)(int); - auto result = f.target(); - if (!result) { - auto r = f(1); - return "can't convert to function pointer: eval(1) = " + std::to_string(r); - } else if (*result == dummy_function) { - auto r = (*result)(1); - return "matches dummy_function: eval(1) = " + std::to_string(r); - } else { - return "argument does NOT match dummy_function. This should never happen!"; - } -} +TEST_SUBMODULE(callbacks, m) { + // test_callbacks, test_function_signatures + m.def("test_callback1", [](py::object func) { return func(); }); + m.def("test_callback2", [](py::object func) { return func("Hello", 'x', true, 5); }); + m.def("test_callback3", [](const std::function &func) { + return "func(43) = " + std::to_string(func(43)); }); + m.def("test_callback4", []() -> std::function { return [](int i) { return i+1; }; }); + m.def("test_callback5", []() { + return py::cpp_function([](int i) { return i+1; }, py::arg("number")); + }); -struct Payload { - Payload() { - print_default_created(this); - } - ~Payload() { - print_destroyed(this); - } - Payload(const Payload &) { - print_copy_created(this); - } - Payload(Payload &&) { - print_move_created(this); - } -}; - -/// Something to trigger a conversion error -struct Unregistered {}; - -class AbstractBase { -public: - virtual unsigned int func() = 0; -}; - -void func_accepting_func_accepting_base(std::function) { } - -struct MovableObject { - bool valid = true; - - MovableObject() = default; - MovableObject(const MovableObject &) = default; - MovableObject &operator=(const MovableObject &) = default; - MovableObject(MovableObject &&o) : valid(o.valid) { o.valid = false; } - MovableObject &operator=(MovableObject &&o) { - valid = o.valid; - o.valid = false; - return *this; - } -}; - -test_initializer callbacks([](py::module &m) { - m.def("test_callback1", &test_callback1); - m.def("test_callback2", &test_callback2); - m.def("test_callback3", &test_callback3); - m.def("test_callback4", &test_callback4); - m.def("test_callback5", &test_callback5); - - // Test keyword args and generalized unpacking + // test_keyword_args_and_generalized_unpacking m.def("test_tuple_unpacking", [](py::function f) { auto t1 = py::make_tuple(2, 3); auto t2 = py::make_tuple(5, 6); @@ -144,13 +67,22 @@ test_initializer callbacks([](py::module &m) { }); m.def("test_arg_conversion_error1", [](py::function f) { - f(234, Unregistered(), "kw"_a=567); + f(234, UnregisteredType(), "kw"_a=567); }); m.def("test_arg_conversion_error2", [](py::function f) { - f(234, "expected_name"_a=Unregistered(), "kw"_a=567); + f(234, "expected_name"_a=UnregisteredType(), "kw"_a=567); }); + // test_lambda_closure_cleanup + struct Payload { + Payload() { print_default_created(this); } + ~Payload() { print_destroyed(this); } + Payload(const Payload &) { print_copy_created(this); } + Payload(Payload &&) { print_move_created(this); } + }; + // Export the payload constructor statistics for testing purposes: + m.def("payload_cstats", &ConstructorStats::get); /* Test cleanup of lambda closure */ m.def("test_cleanup", []() -> std::function { Payload p; @@ -161,22 +93,57 @@ test_initializer callbacks([](py::module &m) { }; }); + // test_cpp_function_roundtrip /* Test if passing a function pointer from C++ -> Python -> C++ yields the original pointer */ m.def("dummy_function", &dummy_function); - m.def("dummy_function2", &dummy_function2); - m.def("roundtrip", &roundtrip, py::arg("f"), py::arg("expect_none")=false); - m.def("test_dummy_function", &test_dummy_function); - // Export the payload constructor statistics for testing purposes: - m.def("payload_cstats", &ConstructorStats::get); - - m.def("func_accepting_func_accepting_base", - func_accepting_func_accepting_base); + m.def("dummy_function2", [](int i, int j) { return i + j; }); + m.def("roundtrip", [](std::function f, bool expect_none = false) { + if (expect_none && f) + throw std::runtime_error("Expected None to be converted to empty std::function"); + return f; + }, py::arg("f"), py::arg("expect_none")=false); + m.def("test_dummy_function", [](const std::function &f) -> std::string { + using fn_type = int (*)(int); + auto result = f.target(); + if (!result) { + auto r = f(1); + return "can't convert to function pointer: eval(1) = " + std::to_string(r); + } else if (*result == dummy_function) { + auto r = (*result)(1); + return "matches dummy_function: eval(1) = " + std::to_string(r); + } else { + return "argument does NOT match dummy_function. This should never happen!"; + } + }); + class AbstractBase { public: virtual unsigned int func() = 0; }; + m.def("func_accepting_func_accepting_base", [](std::function) { }); + + struct MovableObject { + bool valid = true; + + MovableObject() = default; + MovableObject(const MovableObject &) = default; + MovableObject &operator=(const MovableObject &) = default; + MovableObject(MovableObject &&o) : valid(o.valid) { o.valid = false; } + MovableObject &operator=(MovableObject &&o) { + valid = o.valid; + o.valid = false; + return *this; + } + }; py::class_(m, "MovableObject"); + // test_movable_object m.def("callback_with_movable", [](std::function f) { auto x = MovableObject(); f(x); // lvalue reference shouldn't move out object return x.valid; // must still return `true` - }); -}); + }); + + // test_bound_method_callback + struct CppBoundMethodTest {}; + py::class_(m, "CppBoundMethodTest") + .def(py::init<>()) + .def("triple", [](CppBoundMethodTest &, int val) { return 3 * val; }); +} -- cgit v1.2.3