github.com/kaydxh/golang@v0.0.131/pkg/gocv/cgo/third_path/pybind11/tests/test_kwargs_and_defaults.cpp (about) 1 /* 2 tests/test_kwargs_and_defaults.cpp -- keyword arguments and default values 3 4 Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch> 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 #include <pybind11/stl.h> 11 12 #include "constructor_stats.h" 13 #include "pybind11_tests.h" 14 15 #include <utility> 16 17 TEST_SUBMODULE(kwargs_and_defaults, m) { 18 auto kw_func 19 = [](int x, int y) { return "x=" + std::to_string(x) + ", y=" + std::to_string(y); }; 20 21 // test_named_arguments 22 m.def("kw_func0", kw_func); 23 m.def("kw_func1", kw_func, py::arg("x"), py::arg("y")); 24 m.def("kw_func2", kw_func, py::arg("x") = 100, py::arg("y") = 200); 25 m.def( 26 "kw_func3", [](const char *) {}, py::arg("data") = std::string("Hello world!")); 27 28 /* A fancier default argument */ 29 std::vector<int> list{{13, 17}}; 30 m.def( 31 "kw_func4", 32 [](const std::vector<int> &entries) { 33 std::string ret = "{"; 34 for (int i : entries) { 35 ret += std::to_string(i) + " "; 36 } 37 ret.back() = '}'; 38 return ret; 39 }, 40 py::arg("myList") = list); 41 42 m.def("kw_func_udl", kw_func, "x"_a, "y"_a = 300); 43 m.def("kw_func_udl_z", kw_func, "x"_a, "y"_a = 0); 44 45 // test_args_and_kwargs 46 m.def("args_function", [](py::args args) -> py::tuple { 47 PYBIND11_WARNING_PUSH 48 49 #ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING 50 PYBIND11_WARNING_DISABLE_CLANG("-Wreturn-std-move") 51 #endif 52 return args; 53 PYBIND11_WARNING_POP 54 }); 55 m.def("args_kwargs_function", [](const py::args &args, const py::kwargs &kwargs) { 56 return py::make_tuple(args, kwargs); 57 }); 58 59 // test_mixed_args_and_kwargs 60 m.def("mixed_plus_args", 61 [](int i, double j, const py::args &args) { return py::make_tuple(i, j, args); }); 62 m.def("mixed_plus_kwargs", 63 [](int i, double j, const py::kwargs &kwargs) { return py::make_tuple(i, j, kwargs); }); 64 auto mixed_plus_both = [](int i, double j, const py::args &args, const py::kwargs &kwargs) { 65 return py::make_tuple(i, j, args, kwargs); 66 }; 67 m.def("mixed_plus_args_kwargs", mixed_plus_both); 68 69 m.def("mixed_plus_args_kwargs_defaults", 70 mixed_plus_both, 71 py::arg("i") = 1, 72 py::arg("j") = 3.14159); 73 74 m.def( 75 "args_kwonly", 76 [](int i, double j, const py::args &args, int z) { return py::make_tuple(i, j, args, z); }, 77 "i"_a, 78 "j"_a, 79 "z"_a); 80 m.def( 81 "args_kwonly_kwargs", 82 [](int i, double j, const py::args &args, int z, const py::kwargs &kwargs) { 83 return py::make_tuple(i, j, args, z, kwargs); 84 }, 85 "i"_a, 86 "j"_a, 87 py::kw_only{}, 88 "z"_a); 89 m.def( 90 "args_kwonly_kwargs_defaults", 91 [](int i, double j, const py::args &args, int z, const py::kwargs &kwargs) { 92 return py::make_tuple(i, j, args, z, kwargs); 93 }, 94 "i"_a = 1, 95 "j"_a = 3.14159, 96 "z"_a = 42); 97 m.def( 98 "args_kwonly_full_monty", 99 [](int h, int i, double j, const py::args &args, int z, const py::kwargs &kwargs) { 100 return py::make_tuple(h, i, j, args, z, kwargs); 101 }, 102 py::arg() = 1, 103 py::arg() = 2, 104 py::pos_only{}, 105 "j"_a = 3.14159, 106 "z"_a = 42); 107 108 // test_args_refcount 109 // PyPy needs a garbage collection to get the reference count values to match CPython's behaviour 110 #ifdef PYPY_VERSION 111 # define GC_IF_NEEDED ConstructorStats::gc() 112 #else 113 # define GC_IF_NEEDED 114 #endif 115 m.def("arg_refcount_h", [](py::handle h) { 116 GC_IF_NEEDED; 117 return h.ref_count(); 118 }); 119 m.def("arg_refcount_h", [](py::handle h, py::handle, py::handle) { 120 GC_IF_NEEDED; 121 return h.ref_count(); 122 }); 123 m.def("arg_refcount_o", [](const py::object &o) { 124 GC_IF_NEEDED; 125 return o.ref_count(); 126 }); 127 m.def("args_refcount", [](py::args a) { 128 GC_IF_NEEDED; 129 py::tuple t(a.size()); 130 for (size_t i = 0; i < a.size(); i++) { 131 // Use raw Python API here to avoid an extra, intermediate incref on the tuple item: 132 t[i] = (int) Py_REFCNT(PyTuple_GET_ITEM(a.ptr(), static_cast<py::ssize_t>(i))); 133 } 134 return t; 135 }); 136 m.def("mixed_args_refcount", [](const py::object &o, py::args a) { 137 GC_IF_NEEDED; 138 py::tuple t(a.size() + 1); 139 t[0] = o.ref_count(); 140 for (size_t i = 0; i < a.size(); i++) { 141 // Use raw Python API here to avoid an extra, intermediate incref on the tuple item: 142 t[i + 1] = (int) Py_REFCNT(PyTuple_GET_ITEM(a.ptr(), static_cast<py::ssize_t>(i))); 143 } 144 return t; 145 }); 146 147 // pybind11 won't allow these to be bound: args and kwargs, if present, must be at the end. 148 // Uncomment these to test that the static_assert is indeed working: 149 // m.def("bad_args1", [](py::args, int) {}); 150 // m.def("bad_args2", [](py::kwargs, int) {}); 151 // m.def("bad_args3", [](py::kwargs, py::args) {}); 152 // m.def("bad_args4", [](py::args, int, py::kwargs) {}); 153 // m.def("bad_args5", [](py::args, py::kwargs, int) {}); 154 // m.def("bad_args6", [](py::args, py::args) {}); 155 // m.def("bad_args7", [](py::kwargs, py::kwargs) {}); 156 157 // test_keyword_only_args 158 m.def( 159 "kw_only_all", 160 [](int i, int j) { return py::make_tuple(i, j); }, 161 py::kw_only(), 162 py::arg("i"), 163 py::arg("j")); 164 m.def( 165 "kw_only_some", 166 [](int i, int j, int k) { return py::make_tuple(i, j, k); }, 167 py::arg(), 168 py::kw_only(), 169 py::arg("j"), 170 py::arg("k")); 171 m.def( 172 "kw_only_with_defaults", 173 [](int i, int j, int k, int z) { return py::make_tuple(i, j, k, z); }, 174 py::arg() = 3, 175 "j"_a = 4, 176 py::kw_only(), 177 "k"_a = 5, 178 "z"_a); 179 m.def( 180 "kw_only_mixed", 181 [](int i, int j) { return py::make_tuple(i, j); }, 182 "i"_a, 183 py::kw_only(), 184 "j"_a); 185 m.def( 186 "kw_only_plus_more", 187 [](int i, int j, int k, const py::kwargs &kwargs) { 188 return py::make_tuple(i, j, k, kwargs); 189 }, 190 py::arg() /* positional */, 191 py::arg("j") = -1 /* both */, 192 py::kw_only(), 193 py::arg("k") /* kw-only */); 194 195 m.def("register_invalid_kw_only", [](py::module_ m) { 196 m.def( 197 "bad_kw_only", 198 [](int i, int j) { return py::make_tuple(i, j); }, 199 py::kw_only(), 200 py::arg() /* invalid unnamed argument */, 201 "j"_a); 202 }); 203 204 // test_positional_only_args 205 m.def( 206 "pos_only_all", 207 [](int i, int j) { return py::make_tuple(i, j); }, 208 py::arg("i"), 209 py::arg("j"), 210 py::pos_only()); 211 m.def( 212 "pos_only_mix", 213 [](int i, int j) { return py::make_tuple(i, j); }, 214 py::arg("i"), 215 py::pos_only(), 216 py::arg("j")); 217 m.def( 218 "pos_kw_only_mix", 219 [](int i, int j, int k) { return py::make_tuple(i, j, k); }, 220 py::arg("i"), 221 py::pos_only(), 222 py::arg("j"), 223 py::kw_only(), 224 py::arg("k")); 225 m.def( 226 "pos_only_def_mix", 227 [](int i, int j, int k) { return py::make_tuple(i, j, k); }, 228 py::arg("i"), 229 py::arg("j") = 2, 230 py::pos_only(), 231 py::arg("k") = 3); 232 233 // These should fail to compile: 234 #ifdef PYBIND11_NEVER_DEFINED_EVER 235 // argument annotations are required when using kw_only 236 m.def( 237 "bad_kw_only1", [](int) {}, py::kw_only()); 238 // can't specify both `py::kw_only` and a `py::args` argument 239 m.def( 240 "bad_kw_only2", [](int i, py::args) {}, py::kw_only(), "i"_a); 241 #endif 242 243 // test_function_signatures (along with most of the above) 244 struct KWClass { 245 void foo(int, float) {} 246 }; 247 py::class_<KWClass>(m, "KWClass") 248 .def("foo0", &KWClass::foo) 249 .def("foo1", &KWClass::foo, "x"_a, "y"_a); 250 251 // Make sure a class (not an instance) can be used as a default argument. 252 // The return value doesn't matter, only that the module is importable. 253 m.def( 254 "class_default_argument", 255 [](py::object a) { return py::repr(std::move(a)); }, 256 "a"_a = py::module_::import("decimal").attr("Decimal")); 257 258 // Initial implementation of kw_only was broken when used on a method/constructor before any 259 // other arguments 260 // https://github.com/pybind/pybind11/pull/3402#issuecomment-963341987 261 262 struct first_arg_kw_only {}; 263 py::class_<first_arg_kw_only>(m, "first_arg_kw_only") 264 .def(py::init([](int) { return first_arg_kw_only(); }), 265 py::kw_only(), // This being before any args was broken 266 py::arg("i") = 0) 267 .def( 268 "method", 269 [](first_arg_kw_only &, int, int) {}, 270 py::kw_only(), // and likewise here 271 py::arg("i") = 1, 272 py::arg("j") = 2) 273 // Closely related: pos_only marker didn't show up properly when it was before any other 274 // arguments (although that is fairly useless in practice). 275 .def( 276 "pos_only", 277 [](first_arg_kw_only &, int, int) {}, 278 py::pos_only{}, 279 py::arg("i"), 280 py::arg("j")); 281 }