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 "constructor_stats.h"
11 #include "pybind11_tests.h"
12 
13 // py::arg/py::arg_v testing: these arguments just record their argument when invoked
15 public:
16  std::string arg = "(default arg inspector 1)";
17 };
19 public:
20  std::string arg = "(default arg inspector 2)";
21 };
23 
24 namespace PYBIND11_NAMESPACE {
25 namespace detail {
26 template <>
28 public:
29  // Classic
30 #ifdef PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY
31  PYBIND11_TYPE_CASTER(ArgInspector1, _("ArgInspector1"));
32 #else
34 #endif
35 
36  bool load(handle src, bool convert) {
37  value.arg = "loading ArgInspector1 argument " + std::string(convert ? "WITH" : "WITHOUT")
38  + " conversion allowed. "
39  "Argument value = "
40  + (std::string) str(src);
41  return true;
42  }
43 
45  return str(src.arg).release();
46  }
47 };
48 template <>
50 public:
52 
53  bool load(handle src, bool convert) {
54  value.arg = "loading ArgInspector2 argument " + std::string(convert ? "WITH" : "WITHOUT")
55  + " conversion allowed. "
56  "Argument value = "
57  + (std::string) str(src);
58  return true;
59  }
60 
62  return str(src.arg).release();
63  }
64 };
65 template <>
67 public:
68  PYBIND11_TYPE_CASTER(ArgAlwaysConverts, const_name("ArgAlwaysConverts"));
69 
70  bool load(handle, bool convert) { return convert; }
71 
73  return py::none().release();
74  }
75 };
76 } // namespace detail
77 } // namespace PYBIND11_NAMESPACE
78 
79 // test_custom_caster_destruction
81 public:
87  print_copy_assigned(this);
88  return *this;
89  }
91  print_move_assigned(this);
92  return *this;
93  }
94 };
95 namespace PYBIND11_NAMESPACE {
96 namespace detail {
97 template <>
99  PYBIND11_TYPE_CASTER(DestructionTester, const_name("DestructionTester"));
100  bool load(handle, bool) { return true; }
101 
103  return py::bool_(true).release();
104  }
105 };
106 } // namespace detail
107 } // namespace PYBIND11_NAMESPACE
108 
109 // Define type caster outside of `pybind11::detail` and then alias it.
110 namespace other_lib {
111 struct MyType {};
112 // Corrupt `py` shorthand alias for surrounding context.
113 namespace py {}
114 // Corrupt unqualified relative `pybind11` namespace.
115 namespace PYBIND11_NAMESPACE {}
116 // Correct alias.
117 namespace py_ = ::pybind11;
118 // Define caster. This is effectively no-op, we only ensure it compiles and we
119 // don't have any symbol collision when using macro mixin.
120 struct my_caster {
122  bool load(py_::handle, bool) { return true; }
123 
124  static py_::handle cast(const MyType &, py_::return_value_policy, py_::handle) {
125  return py_::bool_(true).release();
126  }
127 };
128 } // namespace other_lib
129 // Effectively "alias" it into correct namespace (via inheritance).
130 namespace PYBIND11_NAMESPACE {
131 namespace detail {
132 template <>
134 } // namespace detail
135 } // namespace PYBIND11_NAMESPACE
136 
137 TEST_SUBMODULE(custom_type_casters, m) {
138  // test_custom_type_casters
139 
140  // test_noconvert_args
141  //
142  // Test converting. The ArgAlwaysConverts is just there to make the first no-conversion pass
143  // fail so that our call always ends up happening via the second dispatch (the one that allows
144  // some conversion).
145  class ArgInspector {
146  public:
148  std::string g(const ArgInspector1 &a,
149  const ArgInspector1 &b,
150  int c,
151  ArgInspector2 *d,
153  return a.arg + "\n" + b.arg + "\n" + std::to_string(c) + "\n" + d->arg;
154  }
155  static ArgInspector2 h(ArgInspector2 a, ArgAlwaysConverts) { return a; }
156  };
157  // [workaround(intel)] ICC 20/21 breaks with py::arg().stuff, using py::arg{}.stuff works.
158  py::class_<ArgInspector>(m, "ArgInspector")
159  .def(py::init<>())
160  .def("f", &ArgInspector::f, py::arg(), py::arg() = ArgAlwaysConverts())
161  .def("g",
163  "a"_a.noconvert(),
164  "b"_a,
165  "c"_a.noconvert() = 13,
166  "d"_a = ArgInspector2(),
168  .def_static("h", &ArgInspector::h, py::arg{}.noconvert(), py::arg() = ArgAlwaysConverts());
169  m.def(
170  "arg_inspect_func",
171  [](const ArgInspector2 &a, const ArgInspector1 &b, ArgAlwaysConverts) {
172  return a.arg + "\n" + b.arg;
173  },
174  py::arg{}.noconvert(false),
175  py::arg_v(nullptr, ArgInspector1()).noconvert(true),
176  py::arg() = ArgAlwaysConverts());
177 
178  m.def(
179  "floats_preferred", [](double f) { return 0.5 * f; }, "f"_a);
180  m.def(
181  "floats_only", [](double f) { return 0.5 * f; }, "f"_a.noconvert());
182  m.def(
183  "ints_preferred", [](int i) { return i / 2; }, "i"_a);
184  m.def(
185  "ints_only", [](int i) { return i / 2; }, "i"_a.noconvert());
186 
187  // test_custom_caster_destruction
188  // Test that `take_ownership` works on types with a custom type caster when given a pointer
189 
190  // default policy: don't take ownership:
191  m.def("custom_caster_no_destroy", []() {
192  static auto *dt = new DestructionTester();
193  return dt;
194  });
195 
196  m.def(
197  "custom_caster_destroy",
198  []() { return new DestructionTester(); },
199  py::return_value_policy::take_ownership); // Takes ownership: destroy when finished
200  m.def(
201  "custom_caster_destroy_const",
202  []() -> const DestructionTester * { return new DestructionTester(); },
203  py::return_value_policy::take_ownership); // Likewise (const doesn't inhibit destruction)
204  m.def("destruction_tester_cstats",
205  &ConstructorStats::get<DestructionTester>,
206  py::return_value_policy::reference);
207 
208  m.def("other_lib_type", [](other_lib::MyType x) { return x; });
209 }
PYBIND11_NAMESPACE::detail::type_caster< ArgAlwaysConverts >::load
bool load(handle, bool convert)
Definition: test_custom_type_casters.cpp:70
DestructionTester
Definition: test_custom_type_casters.cpp:80
DestructionTester::operator=
DestructionTester & operator=(DestructionTester &&) noexcept
Definition: test_custom_type_casters.cpp:90
DestructionTester::DestructionTester
DestructionTester(const DestructionTester &)
Definition: test_custom_type_casters.cpp:84
const_name
constexpr descr< N - 1 > const_name(char const (&text)[N])
Definition: descr.h:60
d
static const double d[K][N]
Definition: igam.h:11
return_value_policy
return_value_policy
Approach used to cast a previously unknown C++ instance into a Python object.
Definition: wrap/pybind11/include/pybind11/detail/common.h:485
c
Scalar Scalar * c
Definition: benchVecAdd.cpp:17
b
Scalar * b
Definition: benchVecAdd.cpp:17
x
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy x
Definition: gnuplot_common_settings.hh:12
dt
const double dt
Definition: testVelocityConstraint.cpp:15
other_lib::my_caster
Definition: test_custom_type_casters.cpp:120
ArgInspector2
Definition: test_custom_type_casters.cpp:18
detail
Definition: testSerializationNonlinear.cpp:70
h
const double h
Definition: testSimpleHelicopter.cpp:19
constructor_stats.h
MyType
Definition: testNonlinearOptimizer.cpp:633
other_lib::my_caster::PYBIND11_TYPE_CASTER
PYBIND11_TYPE_CASTER(MyType, py_::detail::const_name("MyType"))
PYBIND11_NAMESPACE::detail::type_caster< DestructionTester >::load
bool load(handle, bool)
Definition: test_custom_type_casters.cpp:100
print_copy_created
void print_copy_created(T *inst, Values &&...values)
Definition: constructor_stats.h:282
print_default_created
void print_default_created(T *inst, Values &&...values)
Definition: constructor_stats.h:304
PYBIND11_NAMESPACE::detail::type_caster< ArgInspector2 >::cast
static handle cast(const ArgInspector2 &src, return_value_policy, handle)
Definition: test_custom_type_casters.cpp:61
handle
Definition: pytypes.h:217
type_caster
Definition: cast.h:38
DestructionTester::DestructionTester
DestructionTester()
Definition: test_custom_type_casters.cpp:82
print_copy_assigned
void print_copy_assigned(T *inst, Values &&...values)
Definition: constructor_stats.h:294
DestructionTester::operator=
DestructionTester & operator=(const DestructionTester &)
Definition: test_custom_type_casters.cpp:86
ArgAlwaysConverts
Definition: test_custom_type_casters.cpp:22
arg
Definition: cast.h:1277
PYBIND11_NAMESPACE
Definition: test_custom_type_casters.cpp:24
m
Matrix3f m
Definition: AngleAxis_mimic_euler.cpp:1
PYBIND11_NAMESPACE::detail::type_caster< DestructionTester >::cast
static handle cast(const DestructionTester &, return_value_policy, handle)
Definition: test_custom_type_casters.cpp:102
arg
EIGEN_DEVICE_FUNC const EIGEN_STRONG_INLINE ArgReturnType arg() const
Definition: ArrayCwiseUnaryOps.h:66
PYBIND11_NAMESPACE::detail::type_caster< ArgInspector1 >::load
bool load(handle src, bool convert)
Definition: test_custom_type_casters.cpp:36
g
void g(const string &key, int i)
Definition: testBTree.cpp:41
tree::f
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
Definition: testExpression.cpp:218
PYBIND11_TYPE_CASTER
#define PYBIND11_TYPE_CASTER(type, py_name)
Definition: cast.h:85
DestructionTester::DestructionTester
DestructionTester(DestructionTester &&) noexcept
Definition: test_custom_type_casters.cpp:85
other_lib
Definition: test_custom_type_casters.cpp:110
a
ArrayXXi a
Definition: Array_initializer_list_23_cxx11.cpp:1
PYBIND11_NAMESPACE::detail::type_caster< ArgInspector1 >::cast
static handle cast(const ArgInspector1 &src, return_value_policy, handle)
Definition: test_custom_type_casters.cpp:44
print_move_created
void print_move_created(T *inst, Values &&...values)
Definition: constructor_stats.h:288
PYBIND11_NAMESPACE::detail::type_caster< ArgAlwaysConverts >::cast
static handle cast(const ArgAlwaysConverts &, return_value_policy, handle)
Definition: test_custom_type_casters.cpp:72
other_lib::my_caster::cast
static py_::handle cast(const MyType &, py_::return_value_policy, py_::handle)
Definition: test_custom_type_casters.cpp:124
pybind11_tests.h
print_destroyed
void print_destroyed(T *inst, Values &&...values)
Definition: constructor_stats.h:314
ArgInspector1::arg
std::string arg
Definition: test_custom_type_casters.cpp:16
other_lib::my_caster::load
bool load(py_::handle, bool)
Definition: test_custom_type_casters.cpp:122
pybind11
Definition: wrap/pybind11/pybind11/__init__.py:1
print_move_assigned
void print_move_assigned(T *inst, Values &&...values)
Definition: constructor_stats.h:299
DestructionTester::~DestructionTester
~DestructionTester()
Definition: test_custom_type_casters.cpp:83
TEST_SUBMODULE
TEST_SUBMODULE(custom_type_casters, m)
Definition: test_custom_type_casters.cpp:137
ArgInspector2::arg
std::string arg
Definition: test_custom_type_casters.cpp:20
_
constexpr descr< N - 1 > _(char const (&text)[N])
Definition: descr.h:109
gtsam::convert
static BinaryMeasurement< Rot3 > convert(const BetweenFactor< Pose3 >::shared_ptr &f)
Definition: ShonanAveraging.cpp:998
gtsam.examples.ShonanAveragingCLI.str
str
Definition: ShonanAveragingCLI.py:115
PYBIND11_NAMESPACE::detail::type_caster< ArgInspector2 >::load
bool load(handle src, bool convert)
Definition: test_custom_type_casters.cpp:53
test_callbacks.value
value
Definition: test_callbacks.py:158
i
int i
Definition: BiCGSTAB_step_by_step.cpp:9
other_lib::MyType
Definition: test_custom_type_casters.cpp:111
ArgInspector1
Definition: test_custom_type_casters.cpp:14


gtsam
Author(s):
autogenerated on Thu Jun 13 2024 03:08:52