test_custom_type_casters.cpp
Go to the documentation of this file.
1 /*
2  tests/test_custom_type_casters.cpp -- tests type_caster<T>
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_tests.h"
11 #include "constructor_stats.h"
12 
13 
14 // py::arg/py::arg_v testing: these arguments just record their argument when invoked
15 class ArgInspector1 { public: std::string arg = "(default arg inspector 1)"; };
16 class ArgInspector2 { public: std::string arg = "(default arg inspector 2)"; };
18 namespace pybind11 { namespace detail {
19 template <> struct type_caster<ArgInspector1> {
20 public:
21  PYBIND11_TYPE_CASTER(ArgInspector1, _("ArgInspector1"));
22 
23  bool load(handle src, bool convert) {
24  value.arg = "loading ArgInspector1 argument " +
25  std::string(convert ? "WITH" : "WITHOUT") + " conversion allowed. "
26  "Argument value = " + (std::string) str(src);
27  return true;
28  }
29 
31  return str(src.arg).release();
32  }
33 };
34 template <> struct type_caster<ArgInspector2> {
35 public:
36  PYBIND11_TYPE_CASTER(ArgInspector2, _("ArgInspector2"));
37 
38  bool load(handle src, bool convert) {
39  value.arg = "loading ArgInspector2 argument " +
40  std::string(convert ? "WITH" : "WITHOUT") + " conversion allowed. "
41  "Argument value = " + (std::string) str(src);
42  return true;
43  }
44 
46  return str(src.arg).release();
47  }
48 };
49 template <> struct type_caster<ArgAlwaysConverts> {
50 public:
51  PYBIND11_TYPE_CASTER(ArgAlwaysConverts, _("ArgAlwaysConverts"));
52 
53  bool load(handle, bool convert) {
54  return convert;
55  }
56 
58  return py::none().release();
59  }
60 };
61 } // namespace detail
62 } // namespace pybind11
63 
64 // test_custom_caster_destruction
66 public:
73 };
74 namespace pybind11 { namespace detail {
75 template <> struct type_caster<DestructionTester> {
76  PYBIND11_TYPE_CASTER(DestructionTester, _("DestructionTester"));
77  bool load(handle, bool) { return true; }
78 
80  return py::bool_(true).release();
81  }
82 };
83 } // namespace detail
84 } // namespace pybind11
85 
86 TEST_SUBMODULE(custom_type_casters, m) {
87  // test_custom_type_casters
88 
89  // test_noconvert_args
90  //
91  // Test converting. The ArgAlwaysConverts is just there to make the first no-conversion pass
92  // fail so that our call always ends up happening via the second dispatch (the one that allows
93  // some conversion).
94  class ArgInspector {
95  public:
97  std::string g(ArgInspector1 a, const ArgInspector1 &b, int c, ArgInspector2 *d, ArgAlwaysConverts) {
98  return a.arg + "\n" + b.arg + "\n" + std::to_string(c) + "\n" + d->arg;
99  }
100  static ArgInspector2 h(ArgInspector2 a, ArgAlwaysConverts) { return a; }
101  };
102  py::class_<ArgInspector>(m, "ArgInspector")
103  .def(py::init<>())
104  .def("f", &ArgInspector::f, py::arg(), py::arg() = ArgAlwaysConverts())
105  .def("g", &ArgInspector::g, "a"_a.noconvert(), "b"_a, "c"_a.noconvert()=13, "d"_a=ArgInspector2(), py::arg() = ArgAlwaysConverts())
106  .def_static("h", &ArgInspector::h, py::arg().noconvert(), py::arg() = ArgAlwaysConverts())
107  ;
108  m.def("arg_inspect_func", [](ArgInspector2 a, ArgInspector1 b, ArgAlwaysConverts) { return a.arg + "\n" + b.arg; },
109  py::arg().noconvert(false), py::arg_v(nullptr, ArgInspector1()).noconvert(true), py::arg() = ArgAlwaysConverts());
110 
111  m.def("floats_preferred", [](double f) { return 0.5 * f; }, py::arg("f"));
112  m.def("floats_only", [](double f) { return 0.5 * f; }, py::arg("f").noconvert());
113  m.def("ints_preferred", [](int i) { return i / 2; }, py::arg("i"));
114  m.def("ints_only", [](int i) { return i / 2; }, py::arg("i").noconvert());
115 
116  // test_custom_caster_destruction
117  // Test that `take_ownership` works on types with a custom type caster when given a pointer
118 
119  // default policy: don't take ownership:
120  m.def("custom_caster_no_destroy", []() { static auto *dt = new DestructionTester(); return dt; });
121 
122  m.def("custom_caster_destroy", []() { return new DestructionTester(); },
123  py::return_value_policy::take_ownership); // Takes ownership: destroy when finished
124  m.def("custom_caster_destroy_const", []() -> const DestructionTester * { return new DestructionTester(); },
125  py::return_value_policy::take_ownership); // Likewise (const doesn't inhibit destruction)
126  m.def("destruction_tester_cstats", &ConstructorStats::get<DestructionTester>, py::return_value_policy::reference);
127 }
Matrix3f m
static handle cast(const ArgInspector1 &src, return_value_policy, handle)
TEST_SUBMODULE(custom_type_casters, m)
static handle cast(const ArgAlwaysConverts &, return_value_policy, handle)
Scalar * b
Definition: benchVecAdd.cpp:17
DestructionTester(const DestructionTester &)
DestructionTester & operator=(DestructionTester &&)
Scalar Scalar * c
Definition: benchVecAdd.cpp:17
void print_destroyed(T *inst, Values &&...values)
void print_copy_assigned(T *inst, Values &&...values)
void print_copy_created(T *inst, Values &&...values)
Definition: cast.h:1853
DestructionTester & operator=(const DestructionTester &)
void g(const string &key, int i)
Definition: testBTree.cpp:43
static handle cast(const DestructionTester &, return_value_policy, handle)
Array33i a
const double dt
void print_default_created(T *inst, Values &&...values)
void print_move_assigned(T *inst, Values &&...values)
bool convert(const int &y)
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
DestructionTester(DestructionTester &&)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const ArgReturnType arg() const
const double h
static handle cast(const ArgInspector2 &src, return_value_policy, handle)
void print_move_created(T *inst, Values &&...values)
return_value_policy
Approach used to cast a previously unknown C++ instance into a Python object.
#define PYBIND11_TYPE_CASTER(type, py_name)
Definition: cast.h:979


gtsam
Author(s):
autogenerated on Sat May 8 2021 02:46:03