| 30 | bool DependentGuard::enabled = false; |
| 31 | |
| 32 | TEST_SUBMODULE(call_policies, m) { |
| 33 | // Parent/Child are used in: |
| 34 | // test_keep_alive_argument, test_keep_alive_return_value, test_alive_gc_derived, |
| 35 | // test_alive_gc_multi_derived, test_return_none, test_keep_alive_constructor |
| 36 | class Child { |
| 37 | public: |
| 38 | Child() { py::print("Allocating child."); } |
| 39 | Child(const Child &) = default; |
| 40 | Child(Child &&) = default; |
| 41 | ~Child() { py::print("Releasing child."); } |
| 42 | }; |
| 43 | py::class_<Child>(m, "Child").def(py::init<>()); |
| 44 | |
| 45 | class Parent { |
| 46 | public: |
| 47 | Parent() { py::print("Allocating parent."); } |
| 48 | Parent(const Parent &parent) = default; |
| 49 | ~Parent() { py::print("Releasing parent."); } |
| 50 | void addChild(Child *) {} |
| 51 | Child *returnChild() { return new Child(); } |
| 52 | Child *returnNullChild() { return nullptr; } |
| 53 | static Child *staticFunction(Parent *) { return new Child(); } |
| 54 | }; |
| 55 | py::class_<Parent>(m, "Parent") |
| 56 | .def(py::init<>()) |
| 57 | .def(py::init([](Child *) { return new Parent(); }), py::keep_alive<1, 2>()) |
| 58 | .def("addChild", &Parent::addChild) |
| 59 | .def("addChildKeepAlive", &Parent::addChild, py::keep_alive<1, 2>()) |
| 60 | .def("returnChild", &Parent::returnChild) |
| 61 | .def("returnChildKeepAlive", &Parent::returnChild, py::keep_alive<1, 0>()) |
| 62 | .def("returnNullChildKeepAliveChild", &Parent::returnNullChild, py::keep_alive<1, 0>()) |
| 63 | .def("returnNullChildKeepAliveParent", &Parent::returnNullChild, py::keep_alive<0, 1>()) |
| 64 | .def_static("staticFunction", &Parent::staticFunction, py::keep_alive<1, 0>()); |
| 65 | |
| 66 | m.def("free_function", [](Parent *, Child *) {}, py::keep_alive<1, 2>()); |
| 67 | m.def("invalid_arg_index", [] {}, py::keep_alive<0, 1>()); |
| 68 | |
| 69 | #if !defined(PYPY_VERSION) |
| 70 | // test_alive_gc |
| 71 | class ParentGC : public Parent { |
| 72 | public: |
| 73 | using Parent::Parent; |
| 74 | }; |
| 75 | py::class_<ParentGC, Parent>(m, "ParentGC", py::dynamic_attr()).def(py::init<>()); |
| 76 | #endif |
| 77 | |
| 78 | // test_call_guard |
| 79 | m.def("unguarded_call", &CustomGuard::report_status); |
| 80 | m.def("guarded_call", &CustomGuard::report_status, py::call_guard<CustomGuard>()); |
| 81 | |
| 82 | m.def( |
| 83 | "multiple_guards_correct_order", |
| 84 | []() { |
| 85 | return CustomGuard::report_status() + std::string(" & ") |
| 86 | + DependentGuard::report_status(); |
| 87 | }, |
| 88 | py::call_guard<CustomGuard, DependentGuard>()); |
| 89 |
nothing calls this directly
no test coverage detected