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  }