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 <vector>
9 
10 namespace {
11 
12 std::vector<PyObject *> make_vector_pyobject_ptr(const py::object &ValueHolder) {
13  std::vector<PyObject *> vec_obj;
14  for (int i = 1; i < 3; i++) {
15  vec_obj.push_back(ValueHolder(i * 93).release().ptr());
16  }
17  // This vector now owns the refcounts.
18  return vec_obj;
19 }
20 
21 } // namespace
22 
23 TEST_SUBMODULE(type_caster_pyobject_ptr, m) {
24  m.def("cast_from_pyobject_ptr", []() {
25  PyObject *ptr = PyLong_FromLongLong(6758L);
26  return py::cast(ptr, py::return_value_policy::take_ownership);
27  });
28  m.def("cast_handle_to_pyobject_ptr", [](py::handle obj) {
29  auto rc1 = obj.ref_count();
30  auto *ptr = py::cast<PyObject *>(obj);
31  auto rc2 = obj.ref_count();
32  if (rc2 != rc1 + 1) {
33  return -1;
34  }
35  return 100 - py::reinterpret_steal<py::object>(ptr).attr("value").cast<int>();
36  });
37  m.def("cast_object_to_pyobject_ptr", [](py::object obj) {
38  py::handle hdl = obj;
39  auto rc1 = hdl.ref_count();
40  auto *ptr = py::cast<PyObject *>(std::move(obj));
41  auto rc2 = hdl.ref_count();
42  if (rc2 != rc1) {
43  return -1;
44  }
45  return 300 - py::reinterpret_steal<py::object>(ptr).attr("value").cast<int>();
46  });
47  m.def("cast_list_to_pyobject_ptr", [](py::list lst) {
48  // This is to cover types implicitly convertible to object.
49  py::handle hdl = lst;
50  auto rc1 = hdl.ref_count();
51  auto *ptr = py::cast<PyObject *>(std::move(lst));
52  auto rc2 = hdl.ref_count();
53  if (rc2 != rc1) {
54  return -1;
55  }
56  return 400 - static_cast<int>(py::len(py::reinterpret_steal<py::list>(ptr)));
57  });
58 
59  m.def(
60  "return_pyobject_ptr",
61  []() { return PyLong_FromLongLong(2314L); },
62  py::return_value_policy::take_ownership);
63  m.def("pass_pyobject_ptr", [](PyObject *ptr) {
64  return 200 - py::reinterpret_borrow<py::object>(ptr).attr("value").cast<int>();
65  });
66 
67  m.def("call_callback_with_object_return",
68  [](const std::function<py::object(int)> &cb, int value) { return cb(value); });
69  m.def(
70  "call_callback_with_pyobject_ptr_return",
71  [](const std::function<PyObject *(int)> &cb, int value) { return cb(value); },
72  py::return_value_policy::take_ownership);
73  m.def(
74  "call_callback_with_pyobject_ptr_arg",
75  [](const std::function<int(PyObject *)> &cb, py::handle obj) { return cb(obj.ptr()); },
76  py::arg("cb"), // This triggers return_value_policy::automatic_reference
77  py::arg("obj"));
78 
79  m.def("cast_to_pyobject_ptr_nullptr", [](bool set_error) {
80  if (set_error) {
81  PyErr_SetString(PyExc_RuntimeError, "Reflective of healthy error handling.");
82  }
83  PyObject *ptr = nullptr;
84  py::cast(ptr);
85  });
86 
87  m.def("cast_to_pyobject_ptr_non_nullptr_with_error_set", []() {
88  PyErr_SetString(PyExc_RuntimeError, "Reflective of unhealthy error handling.");
89  py::cast(Py_None);
90  });
91 
92  m.def("pass_list_pyobject_ptr", [](const std::vector<PyObject *> &vec_obj) {
93  int acc = 0;
94  for (const auto &ptr : vec_obj) {
95  acc = acc * 1000 + py::reinterpret_borrow<py::object>(ptr).attr("value").cast<int>();
96  }
97  return acc;
98  });
99 
100  m.def("return_list_pyobject_ptr_take_ownership",
101  make_vector_pyobject_ptr,
102  // Ownership is transferred one-by-one when the vector is converted to a Python list.
103  py::return_value_policy::take_ownership);
104 
105  m.def("return_list_pyobject_ptr_reference",
106  make_vector_pyobject_ptr,
107  // Ownership is not transferred.
108  py::return_value_policy::reference);
109 
110  m.def("dec_ref_each_pyobject_ptr", [](const std::vector<PyObject *> &vec_obj) {
111  std::size_t i = 0;
112  for (; i < vec_obj.size(); i++) {
113  py::handle h(vec_obj[i]);
114  if (static_cast<std::size_t>(h.ref_count()) < 2) {
115  break; // Something is badly wrong.
116  }
117  h.dec_ref();
118  }
119  return i;
120  });
121 
122  m.def("pass_pyobject_ptr_and_int", [](PyObject *, int) {});
123 
124 #ifdef PYBIND11_NO_COMPILE_SECTION // Change to ifndef for manual testing.
125  {
126  PyObject *ptr = nullptr;
127  (void) py::cast(*ptr);
128  }
129 #endif
130 }
stl.h
h
const double h
Definition: testSimpleHelicopter.cpp:19
conf.release
release
Definition: gtsam/3rdparty/GeographicLib/python/doc/conf.py:69
L
MatrixXd L
Definition: LLT_example.cpp:6
m
Matrix3f m
Definition: AngleAxis_mimic_euler.cpp:1
arg
EIGEN_DEVICE_FUNC const EIGEN_STRONG_INLINE ArgReturnType arg() const
Definition: ArrayCwiseUnaryOps.h:66
functional.h
size_t
std::size_t size_t
Definition: wrap/pybind11/include/pybind11/detail/common.h:476
TEST_SUBMODULE
TEST_SUBMODULE(type_caster_pyobject_ptr, m)
Definition: test_type_caster_pyobject_ptr.cpp:23
pybind11_tests.h
len
size_t len(handle h)
Get the length of a Python object.
Definition: pytypes.h:2399
type_caster_pyobject_ptr.h
test_callbacks.value
value
Definition: test_callbacks.py:158
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


gtsam
Author(s):
autogenerated on Tue Jun 25 2024 03:05:31