test_type_caster_pyobject_ptr.cpp
Go to the documentation of this file.
1 #include <pybind11/functional.h>
2 #include <pybind11/stl.h>
4 
5 #include "pybind11_tests.h"
6 
7 #include <cstddef>
8 #include <string>
9 #include <vector>
10 
12 
13 std::vector<PyObject *> make_vector_pyobject_ptr(const py::object &ValueHolder) {
14  std::vector<PyObject *> vec_obj;
15  for (int i = 1; i < 3; i++) {
16  vec_obj.push_back(ValueHolder(i * 93).release().ptr());
17  }
18  // This vector now owns the refcounts.
19  return vec_obj;
20 }
21 
23 #if defined(__clang_major__) && __clang_major__ < 4
24  WithPyObjectPtrReturn() = default;
26 #endif
27  virtual ~WithPyObjectPtrReturn() = default;
28  virtual PyObject *return_pyobject_ptr() const = 0;
29 };
30 
32  PyObject *return_pyobject_ptr() const override {
34  /* no arguments */);
35  }
36 };
37 
38 std::string call_return_pyobject_ptr(const WithPyObjectPtrReturn *base_class_ptr) {
39  PyObject *returned_obj = base_class_ptr->return_pyobject_ptr();
40 #if !defined(PYPY_VERSION) // It is not worth the trouble doing something special for PyPy.
41  if (Py_REFCNT(returned_obj) != 1) {
42  py::pybind11_fail(__FILE__ ":" PYBIND11_TOSTRING(__LINE__));
43  }
44 #endif
45  auto ret_val = py::repr(returned_obj).cast<std::string>();
46  Py_DECREF(returned_obj);
47  return ret_val;
48 }
49 
50 } // namespace test_type_caster_pyobject_ptr
51 
52 TEST_SUBMODULE(type_caster_pyobject_ptr, m) {
53  using namespace test_type_caster_pyobject_ptr;
54 
55  m.def("cast_from_pyobject_ptr", []() {
56  PyObject *ptr = PyLong_FromLongLong(6758L);
57  return py::cast(ptr, py::return_value_policy::take_ownership);
58  });
59  m.def("cast_handle_to_pyobject_ptr", [](py::handle obj) {
60  auto rc1 = obj.ref_count();
61  auto *ptr = py::cast<PyObject *>(obj);
62  auto rc2 = obj.ref_count();
63  if (rc2 != rc1 + 1) {
64  return -1;
65  }
66  return 100 - py::reinterpret_steal<py::object>(ptr).attr("value").cast<int>();
67  });
68  m.def("cast_object_to_pyobject_ptr", [](py::object obj) {
69  py::handle hdl = obj;
70  auto rc1 = hdl.ref_count();
71  auto *ptr = py::cast<PyObject *>(std::move(obj));
72  auto rc2 = hdl.ref_count();
73  if (rc2 != rc1) {
74  return -1;
75  }
76  return 300 - py::reinterpret_steal<py::object>(ptr).attr("value").cast<int>();
77  });
78  m.def("cast_list_to_pyobject_ptr", [](py::list lst) {
79  // This is to cover types implicitly convertible to object.
80  py::handle hdl = lst;
81  auto rc1 = hdl.ref_count();
82  auto *ptr = py::cast<PyObject *>(std::move(lst));
83  auto rc2 = hdl.ref_count();
84  if (rc2 != rc1) {
85  return -1;
86  }
87  return 400 - static_cast<int>(py::len(py::reinterpret_steal<py::list>(ptr)));
88  });
89 
90  m.def(
91  "return_pyobject_ptr",
92  []() { return PyLong_FromLongLong(2314L); },
93  py::return_value_policy::take_ownership);
94  m.def("pass_pyobject_ptr", [](PyObject *ptr) {
95  return 200 - py::reinterpret_borrow<py::object>(ptr).attr("value").cast<int>();
96  });
97 
98  m.def("call_callback_with_object_return",
99  [](const std::function<py::object(int)> &cb, int value) { return cb(value); });
100  m.def(
101  "call_callback_with_pyobject_ptr_return",
102  [](const std::function<PyObject *(int)> &cb, int value) { return cb(value); },
103  py::return_value_policy::take_ownership);
104  m.def(
105  "call_callback_with_pyobject_ptr_arg",
106  [](const std::function<int(PyObject *)> &cb, py::handle obj) { return cb(obj.ptr()); },
107  py::arg("cb"), // This triggers return_value_policy::automatic_reference
108  py::arg("obj"));
109 
110  m.def("cast_to_pyobject_ptr_nullptr", [](bool set_error) {
111  if (set_error) {
112  py::set_error(PyExc_RuntimeError, "Reflective of healthy error handling.");
113  }
114  PyObject *ptr = nullptr;
115  py::cast(ptr);
116  });
117 
118  m.def("cast_to_pyobject_ptr_non_nullptr_with_error_set", []() {
119  py::set_error(PyExc_RuntimeError, "Reflective of unhealthy error handling.");
120  py::cast(Py_None);
121  });
122 
123  m.def("pass_list_pyobject_ptr", [](const std::vector<PyObject *> &vec_obj) {
124  int acc = 0;
125  for (const auto &ptr : vec_obj) {
126  acc = acc * 1000 + py::reinterpret_borrow<py::object>(ptr).attr("value").cast<int>();
127  }
128  return acc;
129  });
130 
131  m.def("return_list_pyobject_ptr_take_ownership",
133  // Ownership is transferred one-by-one when the vector is converted to a Python list.
134  py::return_value_policy::take_ownership);
135 
136  m.def("return_list_pyobject_ptr_reference",
138  // Ownership is not transferred.
139  py::return_value_policy::reference);
140 
141  m.def("dec_ref_each_pyobject_ptr", [](const std::vector<PyObject *> &vec_obj) {
142  std::size_t i = 0;
143  for (; i < vec_obj.size(); i++) {
144  py::handle h(vec_obj[i]);
145  if (static_cast<std::size_t>(h.ref_count()) < 2) {
146  break; // Something is badly wrong.
147  }
148  h.dec_ref();
149  }
150  return i;
151  });
152 
153  m.def("pass_pyobject_ptr_and_int", [](PyObject *, int) {});
154 
155 #ifdef PYBIND11_NO_COMPILE_SECTION // Change to ifndef for manual testing.
156  {
157  PyObject *ptr = nullptr;
158  (void) py::cast(*ptr);
159  }
160 #endif
161 
162  py::class_<WithPyObjectPtrReturn, WithPyObjectPtrReturnTrampoline>(m, "WithPyObjectPtrReturn")
163  .def(py::init<>())
164  .def("return_pyobject_ptr", &WithPyObjectPtrReturn::return_pyobject_ptr);
165 
166  m.def("call_return_pyobject_ptr", call_return_pyobject_ptr);
167 }
test_type_caster_pyobject_ptr
Definition: test_type_caster_pyobject_ptr.cpp:11
stl.h
test_type_caster_pyobject_ptr::WithPyObjectPtrReturn
Definition: test_type_caster_pyobject_ptr.cpp:22
h
const double h
Definition: testSimpleHelicopter.cpp:19
test_type_caster_pyobject_ptr::WithPyObjectPtrReturn::return_pyobject_ptr
virtual PyObject * return_pyobject_ptr() const =0
PYBIND11_OVERRIDE_PURE
#define PYBIND11_OVERRIDE_PURE(ret_type, cname, fn,...)
Definition: pybind11.h:2997
test_type_caster_pyobject_ptr::WithPyObjectPtrReturn::~WithPyObjectPtrReturn
virtual ~WithPyObjectPtrReturn()=default
test_type_caster_pyobject_ptr::WithPyObjectPtrReturnTrampoline
Definition: test_type_caster_pyobject_ptr.cpp:31
conf.release
release
Definition: gtsam/3rdparty/GeographicLib/python/doc/conf.py:69
test_type_caster_pyobject_ptr.ValueHolder
Definition: test_type_caster_pyobject_ptr.py:9
L
MatrixXd L
Definition: LLT_example.cpp:6
test_type_caster_pyobject_ptr::WithPyObjectPtrReturnTrampoline::return_pyobject_ptr
PyObject * return_pyobject_ptr() const override
Definition: test_type_caster_pyobject_ptr.cpp:32
PYBIND11_TOSTRING
#define PYBIND11_TOSTRING(x)
Definition: wrap/pybind11/include/pybind11/detail/common.h:386
m
Matrix3f m
Definition: AngleAxis_mimic_euler.cpp:1
test_type_caster_pyobject_ptr::make_vector_pyobject_ptr
std::vector< PyObject * > make_vector_pyobject_ptr(const py::object &ValueHolder)
Definition: test_type_caster_pyobject_ptr.cpp:13
arg
EIGEN_DEVICE_FUNC const EIGEN_STRONG_INLINE ArgReturnType arg() const
Definition: ArrayCwiseUnaryOps.h:66
pybind11_fail
PyExc_RuntimeError PYBIND11_NOINLINE void pybind11_fail(const char *reason)
Used internally.
Definition: wrap/pybind11/include/pybind11/detail/common.h:1026
functional.h
size_t
std::size_t size_t
Definition: wrap/pybind11/include/pybind11/detail/common.h:490
set_error
void set_error(const handle &type, const char *message)
Definition: pytypes.h:346
TEST_SUBMODULE
TEST_SUBMODULE(type_caster_pyobject_ptr, m)
Definition: test_type_caster_pyobject_ptr.cpp:52
pybind11_tests.h
len
size_t len(handle h)
Get the length of a Python object.
Definition: pytypes.h:2446
object::cast
T cast() const &
Definition: cast.h:1293
type_caster_pyobject_ptr.h
test_callbacks.value
value
Definition: test_callbacks.py:160
i
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Eigen::internal::cast
EIGEN_DEVICE_FUNC NewType cast(const OldType &x)
Definition: Eigen/src/Core/MathFunctions.h:460
repr
str repr(handle h)
Definition: pytypes.h:2467
test_type_caster_pyobject_ptr::call_return_pyobject_ptr
std::string call_return_pyobject_ptr(const WithPyObjectPtrReturn *base_class_ptr)
Definition: test_type_caster_pyobject_ptr.cpp:38


gtsam
Author(s):
autogenerated on Thu Jul 4 2024 03:06:05