Techt3o commited on
Commit
120ae60
·
verified ·
1 Parent(s): d09b1e1

0308a1b16ebf8b9711d3d72c37774bd06959075a0fa32d7c6521ae3e95b8fa89

Browse files
Files changed (50) hide show
  1. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_buffers.cpp +212 -0
  2. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_buffers.py +164 -0
  3. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_builtin_casters.cpp +278 -0
  4. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_builtin_casters.py +537 -0
  5. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_call_policies.cpp +107 -0
  6. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_call_policies.py +249 -0
  7. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_callbacks.cpp +188 -0
  8. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_callbacks.py +195 -0
  9. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_chrono.cpp +84 -0
  10. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_chrono.py +209 -0
  11. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_class.cpp +534 -0
  12. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_class.py +466 -0
  13. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_cmake_build/CMakeLists.txt +84 -0
  14. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_cmake_build/embed.cpp +21 -0
  15. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_cmake_build/installed_embed/CMakeLists.txt +26 -0
  16. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_cmake_build/installed_function/CMakeLists.txt +38 -0
  17. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_cmake_build/installed_target/CMakeLists.txt +45 -0
  18. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_cmake_build/main.cpp +6 -0
  19. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_cmake_build/subdirectory_embed/CMakeLists.txt +39 -0
  20. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_cmake_build/subdirectory_function/CMakeLists.txt +34 -0
  21. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_cmake_build/subdirectory_target/CMakeLists.txt +40 -0
  22. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_cmake_build/test.py +6 -0
  23. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_constants_and_functions.cpp +165 -0
  24. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_constants_and_functions.py +53 -0
  25. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_copy_move.cpp +238 -0
  26. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_copy_move.py +125 -0
  27. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_custom_type_casters.cpp +141 -0
  28. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_custom_type_casters.py +116 -0
  29. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_docstring_options.cpp +69 -0
  30. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_docstring_options.py +42 -0
  31. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_eigen.cpp +341 -0
  32. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_eigen.py +770 -0
  33. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_embed/CMakeLists.txt +46 -0
  34. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_embed/catch.cpp +22 -0
  35. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_embed/external_module.cpp +23 -0
  36. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_embed/test_interpreter.cpp +285 -0
  37. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_embed/test_interpreter.py +10 -0
  38. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_enum.cpp +87 -0
  39. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_enum.py +236 -0
  40. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_eval.cpp +101 -0
  41. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_eval.py +35 -0
  42. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_eval_call.py +5 -0
  43. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_exceptions.cpp +238 -0
  44. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_exceptions.h +12 -0
  45. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_exceptions.py +223 -0
  46. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_factory_constructors.cpp +382 -0
  47. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_factory_constructors.py +520 -0
  48. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_gil_scoped.cpp +49 -0
  49. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_gil_scoped.py +94 -0
  50. third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_iostream.cpp +125 -0
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_buffers.cpp ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ tests/test_buffers.cpp -- supporting Pythons' buffer protocol
3
+
4
+ Copyright (c) 2016 Wenzel Jakob <[email protected]>
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
+ #include <pybind11/stl.h>
13
+
14
+ TEST_SUBMODULE(buffers, m) {
15
+ // test_from_python / test_to_python:
16
+ class Matrix {
17
+ public:
18
+ Matrix(py::ssize_t rows, py::ssize_t cols) : m_rows(rows), m_cols(cols) {
19
+ print_created(this, std::to_string(m_rows) + "x" + std::to_string(m_cols) + " matrix");
20
+ m_data = new float[(size_t) (rows*cols)];
21
+ memset(m_data, 0, sizeof(float) * (size_t) (rows * cols));
22
+ }
23
+
24
+ Matrix(const Matrix &s) : m_rows(s.m_rows), m_cols(s.m_cols) {
25
+ print_copy_created(this, std::to_string(m_rows) + "x" + std::to_string(m_cols) + " matrix");
26
+ m_data = new float[(size_t) (m_rows * m_cols)];
27
+ memcpy(m_data, s.m_data, sizeof(float) * (size_t) (m_rows * m_cols));
28
+ }
29
+
30
+ Matrix(Matrix &&s) noexcept : m_rows(s.m_rows), m_cols(s.m_cols), m_data(s.m_data) {
31
+ print_move_created(this);
32
+ s.m_rows = 0;
33
+ s.m_cols = 0;
34
+ s.m_data = nullptr;
35
+ }
36
+
37
+ ~Matrix() {
38
+ print_destroyed(this, std::to_string(m_rows) + "x" + std::to_string(m_cols) + " matrix");
39
+ delete[] m_data;
40
+ }
41
+
42
+ Matrix &operator=(const Matrix &s) {
43
+ print_copy_assigned(this, std::to_string(m_rows) + "x" + std::to_string(m_cols) + " matrix");
44
+ delete[] m_data;
45
+ m_rows = s.m_rows;
46
+ m_cols = s.m_cols;
47
+ m_data = new float[(size_t) (m_rows * m_cols)];
48
+ memcpy(m_data, s.m_data, sizeof(float) * (size_t) (m_rows * m_cols));
49
+ return *this;
50
+ }
51
+
52
+ Matrix &operator=(Matrix &&s) noexcept {
53
+ print_move_assigned(this, std::to_string(m_rows) + "x" + std::to_string(m_cols) + " matrix");
54
+ if (&s != this) {
55
+ delete[] m_data;
56
+ m_rows = s.m_rows; m_cols = s.m_cols; m_data = s.m_data;
57
+ s.m_rows = 0; s.m_cols = 0; s.m_data = nullptr;
58
+ }
59
+ return *this;
60
+ }
61
+
62
+ float operator()(py::ssize_t i, py::ssize_t j) const {
63
+ return m_data[(size_t) (i*m_cols + j)];
64
+ }
65
+
66
+ float &operator()(py::ssize_t i, py::ssize_t j) {
67
+ return m_data[(size_t) (i*m_cols + j)];
68
+ }
69
+
70
+ float *data() { return m_data; }
71
+
72
+ py::ssize_t rows() const { return m_rows; }
73
+ py::ssize_t cols() const { return m_cols; }
74
+ private:
75
+ py::ssize_t m_rows;
76
+ py::ssize_t m_cols;
77
+ float *m_data;
78
+ };
79
+ py::class_<Matrix>(m, "Matrix", py::buffer_protocol())
80
+ .def(py::init<py::ssize_t, py::ssize_t>())
81
+ /// Construct from a buffer
82
+ .def(py::init([](const py::buffer &b) {
83
+ py::buffer_info info = b.request();
84
+ if (info.format != py::format_descriptor<float>::format() || info.ndim != 2)
85
+ throw std::runtime_error("Incompatible buffer format!");
86
+
87
+ auto v = new Matrix(info.shape[0], info.shape[1]);
88
+ memcpy(v->data(), info.ptr, sizeof(float) * (size_t) (v->rows() * v->cols()));
89
+ return v;
90
+ }))
91
+
92
+ .def("rows", &Matrix::rows)
93
+ .def("cols", &Matrix::cols)
94
+
95
+ /// Bare bones interface
96
+ .def("__getitem__",
97
+ [](const Matrix &m, std::pair<py::ssize_t, py::ssize_t> i) {
98
+ if (i.first >= m.rows() || i.second >= m.cols())
99
+ throw py::index_error();
100
+ return m(i.first, i.second);
101
+ })
102
+ .def("__setitem__",
103
+ [](Matrix &m, std::pair<py::ssize_t, py::ssize_t> i, float v) {
104
+ if (i.first >= m.rows() || i.second >= m.cols())
105
+ throw py::index_error();
106
+ m(i.first, i.second) = v;
107
+ })
108
+ /// Provide buffer access
109
+ .def_buffer([](Matrix &m) -> py::buffer_info {
110
+ return py::buffer_info(
111
+ m.data(), /* Pointer to buffer */
112
+ { m.rows(), m.cols() }, /* Buffer dimensions */
113
+ { sizeof(float) * size_t(m.cols()), /* Strides (in bytes) for each index */
114
+ sizeof(float) }
115
+ );
116
+ });
117
+
118
+ // test_inherited_protocol
119
+ class SquareMatrix : public Matrix {
120
+ public:
121
+ SquareMatrix(py::ssize_t n) : Matrix(n, n) { }
122
+ };
123
+ // Derived classes inherit the buffer protocol and the buffer access function
124
+ py::class_<SquareMatrix, Matrix>(m, "SquareMatrix")
125
+ .def(py::init<py::ssize_t>());
126
+
127
+
128
+ // test_pointer_to_member_fn
129
+ // Tests that passing a pointer to member to the base class works in
130
+ // the derived class.
131
+ struct Buffer {
132
+ int32_t value = 0;
133
+
134
+ py::buffer_info get_buffer_info() {
135
+ return py::buffer_info(&value, sizeof(value),
136
+ py::format_descriptor<int32_t>::format(), 1);
137
+ }
138
+ };
139
+ py::class_<Buffer>(m, "Buffer", py::buffer_protocol())
140
+ .def(py::init<>())
141
+ .def_readwrite("value", &Buffer::value)
142
+ .def_buffer(&Buffer::get_buffer_info);
143
+
144
+
145
+ class ConstBuffer {
146
+ std::unique_ptr<int32_t> value;
147
+
148
+ public:
149
+ int32_t get_value() const { return *value; }
150
+ void set_value(int32_t v) { *value = v; }
151
+
152
+ py::buffer_info get_buffer_info() const {
153
+ return py::buffer_info(value.get(), sizeof(*value),
154
+ py::format_descriptor<int32_t>::format(), 1);
155
+ }
156
+
157
+ ConstBuffer() : value(new int32_t{0}) {}
158
+ };
159
+ py::class_<ConstBuffer>(m, "ConstBuffer", py::buffer_protocol())
160
+ .def(py::init<>())
161
+ .def_property("value", &ConstBuffer::get_value, &ConstBuffer::set_value)
162
+ .def_buffer(&ConstBuffer::get_buffer_info);
163
+
164
+ struct DerivedBuffer : public Buffer { };
165
+ py::class_<DerivedBuffer>(m, "DerivedBuffer", py::buffer_protocol())
166
+ .def(py::init<>())
167
+ .def_readwrite("value", (int32_t DerivedBuffer::*) &DerivedBuffer::value)
168
+ .def_buffer(&DerivedBuffer::get_buffer_info);
169
+
170
+ struct BufferReadOnly {
171
+ const uint8_t value = 0;
172
+ BufferReadOnly(uint8_t value): value(value) {}
173
+
174
+ py::buffer_info get_buffer_info() {
175
+ return py::buffer_info(&value, 1);
176
+ }
177
+ };
178
+ py::class_<BufferReadOnly>(m, "BufferReadOnly", py::buffer_protocol())
179
+ .def(py::init<uint8_t>())
180
+ .def_buffer(&BufferReadOnly::get_buffer_info);
181
+
182
+ struct BufferReadOnlySelect {
183
+ uint8_t value = 0;
184
+ bool readonly = false;
185
+
186
+ py::buffer_info get_buffer_info() {
187
+ return py::buffer_info(&value, 1, readonly);
188
+ }
189
+ };
190
+ py::class_<BufferReadOnlySelect>(m, "BufferReadOnlySelect", py::buffer_protocol())
191
+ .def(py::init<>())
192
+ .def_readwrite("value", &BufferReadOnlySelect::value)
193
+ .def_readwrite("readonly", &BufferReadOnlySelect::readonly)
194
+ .def_buffer(&BufferReadOnlySelect::get_buffer_info);
195
+
196
+ // Expose buffer_info for testing.
197
+ py::class_<py::buffer_info>(m, "buffer_info")
198
+ .def(py::init<>())
199
+ .def_readonly("itemsize", &py::buffer_info::itemsize)
200
+ .def_readonly("size", &py::buffer_info::size)
201
+ .def_readonly("format", &py::buffer_info::format)
202
+ .def_readonly("ndim", &py::buffer_info::ndim)
203
+ .def_readonly("shape", &py::buffer_info::shape)
204
+ .def_readonly("strides", &py::buffer_info::strides)
205
+ .def_readonly("readonly", &py::buffer_info::readonly)
206
+ .def("__repr__", [](py::handle self) {
207
+ return py::str("itemsize={0.itemsize!r}, size={0.size!r}, format={0.format!r}, ndim={0.ndim!r}, shape={0.shape!r}, strides={0.strides!r}, readonly={0.readonly!r}").format(self);
208
+ })
209
+ ;
210
+
211
+ m.def("get_buffer_info", [](const py::buffer &buffer) { return buffer.request(); });
212
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_buffers.py ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ import io
3
+ import struct
4
+ import ctypes
5
+
6
+ import pytest
7
+
8
+ import env # noqa: F401
9
+
10
+ from pybind11_tests import buffers as m
11
+ from pybind11_tests import ConstructorStats
12
+
13
+ np = pytest.importorskip("numpy")
14
+
15
+
16
+ def test_from_python():
17
+ with pytest.raises(RuntimeError) as excinfo:
18
+ m.Matrix(np.array([1, 2, 3])) # trying to assign a 1D array
19
+ assert str(excinfo.value) == "Incompatible buffer format!"
20
+
21
+ m3 = np.array([[1, 2, 3], [4, 5, 6]]).astype(np.float32)
22
+ m4 = m.Matrix(m3)
23
+
24
+ for i in range(m4.rows()):
25
+ for j in range(m4.cols()):
26
+ assert m3[i, j] == m4[i, j]
27
+
28
+ cstats = ConstructorStats.get(m.Matrix)
29
+ assert cstats.alive() == 1
30
+ del m3, m4
31
+ assert cstats.alive() == 0
32
+ assert cstats.values() == ["2x3 matrix"]
33
+ assert cstats.copy_constructions == 0
34
+ # assert cstats.move_constructions >= 0 # Don't invoke any
35
+ assert cstats.copy_assignments == 0
36
+ assert cstats.move_assignments == 0
37
+
38
+
39
+ # https://foss.heptapod.net/pypy/pypy/-/issues/2444
40
+ def test_to_python():
41
+ mat = m.Matrix(5, 4)
42
+ assert memoryview(mat).shape == (5, 4)
43
+
44
+ assert mat[2, 3] == 0
45
+ mat[2, 3] = 4.0
46
+ mat[3, 2] = 7.0
47
+ assert mat[2, 3] == 4
48
+ assert mat[3, 2] == 7
49
+ assert struct.unpack_from("f", mat, (3 * 4 + 2) * 4) == (7,)
50
+ assert struct.unpack_from("f", mat, (2 * 4 + 3) * 4) == (4,)
51
+
52
+ mat2 = np.array(mat, copy=False)
53
+ assert mat2.shape == (5, 4)
54
+ assert abs(mat2).sum() == 11
55
+ assert mat2[2, 3] == 4 and mat2[3, 2] == 7
56
+ mat2[2, 3] = 5
57
+ assert mat2[2, 3] == 5
58
+
59
+ cstats = ConstructorStats.get(m.Matrix)
60
+ assert cstats.alive() == 1
61
+ del mat
62
+ pytest.gc_collect()
63
+ assert cstats.alive() == 1
64
+ del mat2 # holds a mat reference
65
+ pytest.gc_collect()
66
+ assert cstats.alive() == 0
67
+ assert cstats.values() == ["5x4 matrix"]
68
+ assert cstats.copy_constructions == 0
69
+ # assert cstats.move_constructions >= 0 # Don't invoke any
70
+ assert cstats.copy_assignments == 0
71
+ assert cstats.move_assignments == 0
72
+
73
+
74
+ def test_inherited_protocol():
75
+ """SquareMatrix is derived from Matrix and inherits the buffer protocol"""
76
+
77
+ matrix = m.SquareMatrix(5)
78
+ assert memoryview(matrix).shape == (5, 5)
79
+ assert np.asarray(matrix).shape == (5, 5)
80
+
81
+
82
+ def test_pointer_to_member_fn():
83
+ for cls in [m.Buffer, m.ConstBuffer, m.DerivedBuffer]:
84
+ buf = cls()
85
+ buf.value = 0x12345678
86
+ value = struct.unpack("i", bytearray(buf))[0]
87
+ assert value == 0x12345678
88
+
89
+
90
+ def test_readonly_buffer():
91
+ buf = m.BufferReadOnly(0x64)
92
+ view = memoryview(buf)
93
+ assert view[0] == b"d" if env.PY2 else 0x64
94
+ assert view.readonly
95
+ with pytest.raises(TypeError):
96
+ view[0] = b"\0" if env.PY2 else 0
97
+
98
+
99
+ def test_selective_readonly_buffer():
100
+ buf = m.BufferReadOnlySelect()
101
+
102
+ memoryview(buf)[0] = b"d" if env.PY2 else 0x64
103
+ assert buf.value == 0x64
104
+
105
+ io.BytesIO(b"A").readinto(buf)
106
+ assert buf.value == ord(b"A")
107
+
108
+ buf.readonly = True
109
+ with pytest.raises(TypeError):
110
+ memoryview(buf)[0] = b"\0" if env.PY2 else 0
111
+ with pytest.raises(TypeError):
112
+ io.BytesIO(b"1").readinto(buf)
113
+
114
+
115
+ def test_ctypes_array_1d():
116
+ char1d = (ctypes.c_char * 10)()
117
+ int1d = (ctypes.c_int * 15)()
118
+ long1d = (ctypes.c_long * 7)()
119
+
120
+ for carray in (char1d, int1d, long1d):
121
+ info = m.get_buffer_info(carray)
122
+ assert info.itemsize == ctypes.sizeof(carray._type_)
123
+ assert info.size == len(carray)
124
+ assert info.ndim == 1
125
+ assert info.shape == [info.size]
126
+ assert info.strides == [info.itemsize]
127
+ assert not info.readonly
128
+
129
+
130
+ def test_ctypes_array_2d():
131
+ char2d = ((ctypes.c_char * 10) * 4)()
132
+ int2d = ((ctypes.c_int * 15) * 3)()
133
+ long2d = ((ctypes.c_long * 7) * 2)()
134
+
135
+ for carray in (char2d, int2d, long2d):
136
+ info = m.get_buffer_info(carray)
137
+ assert info.itemsize == ctypes.sizeof(carray[0]._type_)
138
+ assert info.size == len(carray) * len(carray[0])
139
+ assert info.ndim == 2
140
+ assert info.shape == [len(carray), len(carray[0])]
141
+ assert info.strides == [info.itemsize * len(carray[0]), info.itemsize]
142
+ assert not info.readonly
143
+
144
+
145
+ @pytest.mark.skipif(
146
+ "env.PYPY and env.PY2", reason="PyPy2 bytes buffer not reported as readonly"
147
+ )
148
+ def test_ctypes_from_buffer():
149
+ test_pystr = b"0123456789"
150
+ for pyarray in (test_pystr, bytearray(test_pystr)):
151
+ pyinfo = m.get_buffer_info(pyarray)
152
+
153
+ if pyinfo.readonly:
154
+ cbytes = (ctypes.c_char * len(pyarray)).from_buffer_copy(pyarray)
155
+ cinfo = m.get_buffer_info(cbytes)
156
+ else:
157
+ cbytes = (ctypes.c_char * len(pyarray)).from_buffer(pyarray)
158
+ cinfo = m.get_buffer_info(cbytes)
159
+
160
+ assert cinfo.size == pyinfo.size
161
+ assert cinfo.ndim == pyinfo.ndim
162
+ assert cinfo.shape == pyinfo.shape
163
+ assert cinfo.strides == pyinfo.strides
164
+ assert not cinfo.readonly
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_builtin_casters.cpp ADDED
@@ -0,0 +1,278 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ tests/test_builtin_casters.cpp -- Casters available without any additional headers
3
+
4
+ Copyright (c) 2017 Wenzel Jakob <[email protected]>
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 <pybind11/complex.h>
12
+
13
+ #if defined(_MSC_VER)
14
+ # pragma warning(push)
15
+ # pragma warning(disable: 4127) // warning C4127: Conditional expression is constant
16
+ #endif
17
+
18
+ struct ConstRefCasted {
19
+ int tag;
20
+ };
21
+
22
+ PYBIND11_NAMESPACE_BEGIN(pybind11)
23
+ PYBIND11_NAMESPACE_BEGIN(detail)
24
+ template <>
25
+ class type_caster<ConstRefCasted> {
26
+ public:
27
+ static constexpr auto name = _<ConstRefCasted>();
28
+
29
+ // Input is unimportant, a new value will always be constructed based on the
30
+ // cast operator.
31
+ bool load(handle, bool) { return true; }
32
+
33
+ operator ConstRefCasted &&() {
34
+ value = {1};
35
+ // NOLINTNEXTLINE(performance-move-const-arg)
36
+ return std::move(value);
37
+ }
38
+ operator ConstRefCasted&() { value = {2}; return value; }
39
+ operator ConstRefCasted*() { value = {3}; return &value; }
40
+
41
+ operator const ConstRefCasted&() { value = {4}; return value; }
42
+ operator const ConstRefCasted*() { value = {5}; return &value; }
43
+
44
+ // custom cast_op to explicitly propagate types to the conversion operators.
45
+ template <typename T_>
46
+ using cast_op_type =
47
+ /// const
48
+ conditional_t<
49
+ std::is_same<remove_reference_t<T_>, const ConstRefCasted*>::value, const ConstRefCasted*,
50
+ conditional_t<
51
+ std::is_same<T_, const ConstRefCasted&>::value, const ConstRefCasted&,
52
+ /// non-const
53
+ conditional_t<
54
+ std::is_same<remove_reference_t<T_>, ConstRefCasted*>::value, ConstRefCasted*,
55
+ conditional_t<
56
+ std::is_same<T_, ConstRefCasted&>::value, ConstRefCasted&,
57
+ /* else */ConstRefCasted&&>>>>;
58
+
59
+ private:
60
+ ConstRefCasted value = {0};
61
+ };
62
+ PYBIND11_NAMESPACE_END(detail)
63
+ PYBIND11_NAMESPACE_END(pybind11)
64
+
65
+ TEST_SUBMODULE(builtin_casters, m) {
66
+ // test_simple_string
67
+ m.def("string_roundtrip", [](const char *s) { return s; });
68
+
69
+ // test_unicode_conversion
70
+ // Some test characters in utf16 and utf32 encodings. The last one (the 𝐀) contains a null byte
71
+ char32_t a32 = 0x61 /*a*/, z32 = 0x7a /*z*/, ib32 = 0x203d /*‽*/, cake32 = 0x1f382 /*🎂*/, mathbfA32 = 0x1d400 /*𝐀*/;
72
+ char16_t b16 = 0x62 /*b*/, z16 = 0x7a, ib16 = 0x203d, cake16_1 = 0xd83c, cake16_2 = 0xdf82, mathbfA16_1 = 0xd835, mathbfA16_2 = 0xdc00;
73
+ std::wstring wstr;
74
+ wstr.push_back(0x61); // a
75
+ wstr.push_back(0x2e18); // ⸘
76
+ if (sizeof(wchar_t) == 2) { wstr.push_back(mathbfA16_1); wstr.push_back(mathbfA16_2); } // 𝐀, utf16
77
+ else { wstr.push_back((wchar_t) mathbfA32); } // 𝐀, utf32
78
+ wstr.push_back(0x7a); // z
79
+
80
+ m.def("good_utf8_string", []() { return std::string((const char*)u8"Say utf8\u203d \U0001f382 \U0001d400"); }); // Say utf8‽ 🎂 𝐀
81
+ m.def("good_utf16_string", [=]() { return std::u16string({ b16, ib16, cake16_1, cake16_2, mathbfA16_1, mathbfA16_2, z16 }); }); // b‽🎂𝐀z
82
+ m.def("good_utf32_string", [=]() { return std::u32string({ a32, mathbfA32, cake32, ib32, z32 }); }); // a𝐀🎂‽z
83
+ m.def("good_wchar_string", [=]() { return wstr; }); // a‽𝐀z
84
+ m.def("bad_utf8_string", []() { return std::string("abc\xd0" "def"); });
85
+ m.def("bad_utf16_string", [=]() { return std::u16string({ b16, char16_t(0xd800), z16 }); });
86
+ // Under Python 2.7, invalid unicode UTF-32 characters don't appear to trigger UnicodeDecodeError
87
+ if (PY_MAJOR_VERSION >= 3)
88
+ m.def("bad_utf32_string", [=]() { return std::u32string({ a32, char32_t(0xd800), z32 }); });
89
+ if (PY_MAJOR_VERSION >= 3 || sizeof(wchar_t) == 2)
90
+ m.def("bad_wchar_string", [=]() { return std::wstring({ wchar_t(0x61), wchar_t(0xd800) }); });
91
+ m.def("u8_Z", []() -> char { return 'Z'; });
92
+ m.def("u8_eacute", []() -> char { return '\xe9'; });
93
+ m.def("u16_ibang", [=]() -> char16_t { return ib16; });
94
+ m.def("u32_mathbfA", [=]() -> char32_t { return mathbfA32; });
95
+ m.def("wchar_heart", []() -> wchar_t { return 0x2665; });
96
+
97
+ // test_single_char_arguments
98
+ m.attr("wchar_size") = py::cast(sizeof(wchar_t));
99
+ m.def("ord_char", [](char c) -> int { return static_cast<unsigned char>(c); });
100
+ m.def("ord_char_lv", [](char &c) -> int { return static_cast<unsigned char>(c); });
101
+ m.def("ord_char16", [](char16_t c) -> uint16_t { return c; });
102
+ m.def("ord_char16_lv", [](char16_t &c) -> uint16_t { return c; });
103
+ m.def("ord_char32", [](char32_t c) -> uint32_t { return c; });
104
+ m.def("ord_wchar", [](wchar_t c) -> int { return c; });
105
+
106
+ // test_bytes_to_string
107
+ m.def("strlen", [](char *s) { return strlen(s); });
108
+ m.def("string_length", [](const std::string &s) { return s.length(); });
109
+
110
+ #ifdef PYBIND11_HAS_U8STRING
111
+ m.attr("has_u8string") = true;
112
+ m.def("good_utf8_u8string", []() { return std::u8string(u8"Say utf8\u203d \U0001f382 \U0001d400"); }); // Say utf8‽ 🎂 𝐀
113
+ m.def("bad_utf8_u8string", []() { return std::u8string((const char8_t*)"abc\xd0" "def"); });
114
+
115
+ m.def("u8_char8_Z", []() -> char8_t { return u8'Z'; });
116
+
117
+ // test_single_char_arguments
118
+ m.def("ord_char8", [](char8_t c) -> int { return static_cast<unsigned char>(c); });
119
+ m.def("ord_char8_lv", [](char8_t &c) -> int { return static_cast<unsigned char>(c); });
120
+ #endif
121
+
122
+ // test_string_view
123
+ #ifdef PYBIND11_HAS_STRING_VIEW
124
+ m.attr("has_string_view") = true;
125
+ m.def("string_view_print", [](std::string_view s) { py::print(s, s.size()); });
126
+ m.def("string_view16_print", [](std::u16string_view s) { py::print(s, s.size()); });
127
+ m.def("string_view32_print", [](std::u32string_view s) { py::print(s, s.size()); });
128
+ m.def("string_view_chars", [](std::string_view s) { py::list l; for (auto c : s) l.append((std::uint8_t) c); return l; });
129
+ m.def("string_view16_chars", [](std::u16string_view s) { py::list l; for (auto c : s) l.append((int) c); return l; });
130
+ m.def("string_view32_chars", [](std::u32string_view s) { py::list l; for (auto c : s) l.append((int) c); return l; });
131
+ m.def("string_view_return", []() { return std::string_view((const char*)u8"utf8 secret \U0001f382"); });
132
+ m.def("string_view16_return", []() { return std::u16string_view(u"utf16 secret \U0001f382"); });
133
+ m.def("string_view32_return", []() { return std::u32string_view(U"utf32 secret \U0001f382"); });
134
+
135
+ # ifdef PYBIND11_HAS_U8STRING
136
+ m.def("string_view8_print", [](std::u8string_view s) { py::print(s, s.size()); });
137
+ m.def("string_view8_chars", [](std::u8string_view s) { py::list l; for (auto c : s) l.append((std::uint8_t) c); return l; });
138
+ m.def("string_view8_return", []() { return std::u8string_view(u8"utf8 secret \U0001f382"); });
139
+ # endif
140
+ #endif
141
+
142
+ // test_integer_casting
143
+ m.def("i32_str", [](std::int32_t v) { return std::to_string(v); });
144
+ m.def("u32_str", [](std::uint32_t v) { return std::to_string(v); });
145
+ m.def("i64_str", [](std::int64_t v) { return std::to_string(v); });
146
+ m.def("u64_str", [](std::uint64_t v) { return std::to_string(v); });
147
+
148
+ // test_int_convert
149
+ m.def("int_passthrough", [](int arg) { return arg; });
150
+ m.def("int_passthrough_noconvert", [](int arg) { return arg; }, py::arg{}.noconvert());
151
+
152
+ // test_tuple
153
+ m.def(
154
+ "pair_passthrough",
155
+ [](const std::pair<bool, std::string> &input) {
156
+ return std::make_pair(input.second, input.first);
157
+ },
158
+ "Return a pair in reversed order");
159
+ m.def("tuple_passthrough", [](std::tuple<bool, std::string, int> input) {
160
+ return std::make_tuple(std::get<2>(input), std::get<1>(input), std::get<0>(input));
161
+ }, "Return a triple in reversed order");
162
+ m.def("empty_tuple", []() { return std::tuple<>(); });
163
+ static std::pair<RValueCaster, RValueCaster> lvpair;
164
+ static std::tuple<RValueCaster, RValueCaster, RValueCaster> lvtuple;
165
+ static std::pair<RValueCaster, std::tuple<RValueCaster, std::pair<RValueCaster, RValueCaster>>> lvnested;
166
+ m.def("rvalue_pair", []() { return std::make_pair(RValueCaster{}, RValueCaster{}); });
167
+ m.def("lvalue_pair", []() -> const decltype(lvpair) & { return lvpair; });
168
+ m.def("rvalue_tuple", []() { return std::make_tuple(RValueCaster{}, RValueCaster{}, RValueCaster{}); });
169
+ m.def("lvalue_tuple", []() -> const decltype(lvtuple) & { return lvtuple; });
170
+ m.def("rvalue_nested", []() {
171
+ return std::make_pair(RValueCaster{}, std::make_tuple(RValueCaster{}, std::make_pair(RValueCaster{}, RValueCaster{}))); });
172
+ m.def("lvalue_nested", []() -> const decltype(lvnested) & { return lvnested; });
173
+
174
+ static std::pair<int, std::string> int_string_pair{2, "items"};
175
+ m.def("int_string_pair", []() { return &int_string_pair; });
176
+
177
+ // test_builtins_cast_return_none
178
+ m.def("return_none_string", []() -> std::string * { return nullptr; });
179
+ m.def("return_none_char", []() -> const char * { return nullptr; });
180
+ m.def("return_none_bool", []() -> bool * { return nullptr; });
181
+ m.def("return_none_int", []() -> int * { return nullptr; });
182
+ m.def("return_none_float", []() -> float * { return nullptr; });
183
+ m.def("return_none_pair", []() -> std::pair<int,int> * { return nullptr; });
184
+
185
+ // test_none_deferred
186
+ m.def("defer_none_cstring", [](char *) { return false; });
187
+ m.def("defer_none_cstring", [](const py::none &) { return true; });
188
+ m.def("defer_none_custom", [](UserType *) { return false; });
189
+ m.def("defer_none_custom", [](const py::none &) { return true; });
190
+ m.def("nodefer_none_void", [](void *) { return true; });
191
+ m.def("nodefer_none_void", [](const py::none &) { return false; });
192
+
193
+ // test_void_caster
194
+ m.def("load_nullptr_t", [](std::nullptr_t) {}); // not useful, but it should still compile
195
+ m.def("cast_nullptr_t", []() { return std::nullptr_t{}; });
196
+
197
+ // [workaround(intel)] ICC 20/21 breaks with py::arg().stuff, using py::arg{}.stuff works.
198
+
199
+ // test_bool_caster
200
+ m.def("bool_passthrough", [](bool arg) { return arg; });
201
+ m.def("bool_passthrough_noconvert", [](bool arg) { return arg; }, py::arg{}.noconvert());
202
+
203
+ // TODO: This should be disabled and fixed in future Intel compilers
204
+ #if !defined(__INTEL_COMPILER)
205
+ // Test "bool_passthrough_noconvert" again, but using () instead of {} to construct py::arg
206
+ // When compiled with the Intel compiler, this results in segmentation faults when importing
207
+ // the module. Tested with icc (ICC) 2021.1 Beta 20200827, this should be tested again when
208
+ // a newer version of icc is available.
209
+ m.def("bool_passthrough_noconvert2", [](bool arg) { return arg; }, py::arg().noconvert());
210
+ #endif
211
+
212
+ // test_reference_wrapper
213
+ m.def("refwrap_builtin", [](std::reference_wrapper<int> p) { return 10 * p.get(); });
214
+ m.def("refwrap_usertype", [](std::reference_wrapper<UserType> p) { return p.get().value(); });
215
+ m.def("refwrap_usertype_const", [](std::reference_wrapper<const UserType> p) { return p.get().value(); });
216
+
217
+ m.def("refwrap_lvalue", []() -> std::reference_wrapper<UserType> {
218
+ static UserType x(1);
219
+ return std::ref(x);
220
+ });
221
+ m.def("refwrap_lvalue_const", []() -> std::reference_wrapper<const UserType> {
222
+ static UserType x(1);
223
+ return std::cref(x);
224
+ });
225
+
226
+ // Not currently supported (std::pair caster has return-by-value cast operator);
227
+ // triggers static_assert failure.
228
+ //m.def("refwrap_pair", [](std::reference_wrapper<std::pair<int, int>>) { });
229
+
230
+ m.def("refwrap_list", [](bool copy) {
231
+ static IncType x1(1), x2(2);
232
+ py::list l;
233
+ for (auto &f : {std::ref(x1), std::ref(x2)}) {
234
+ l.append(py::cast(f, copy ? py::return_value_policy::copy
235
+ : py::return_value_policy::reference));
236
+ }
237
+ return l;
238
+ }, "copy"_a);
239
+
240
+ m.def("refwrap_iiw", [](const IncType &w) { return w.value(); });
241
+ m.def("refwrap_call_iiw", [](IncType &w, const py::function &f) {
242
+ py::list l;
243
+ l.append(f(std::ref(w)));
244
+ l.append(f(std::cref(w)));
245
+ IncType x(w.value());
246
+ l.append(f(std::ref(x)));
247
+ IncType y(w.value());
248
+ auto r3 = std::ref(y);
249
+ l.append(f(r3));
250
+ return l;
251
+ });
252
+
253
+ // test_complex
254
+ m.def("complex_cast", [](float x) { return "{}"_s.format(x); });
255
+ m.def("complex_cast", [](std::complex<float> x) { return "({}, {})"_s.format(x.real(), x.imag()); });
256
+
257
+ // test int vs. long (Python 2)
258
+ m.def("int_cast", []() {return (int) 42;});
259
+ m.def("long_cast", []() {return (long) 42;});
260
+ m.def("longlong_cast", []() {return ULLONG_MAX;});
261
+
262
+ /// test void* cast operator
263
+ m.def("test_void_caster", []() -> bool {
264
+ void *v = (void *) 0xabcd;
265
+ py::object o = py::cast(v);
266
+ return py::cast<void *>(o) == v;
267
+ });
268
+
269
+ // Tests const/non-const propagation in cast_op.
270
+ m.def("takes", [](ConstRefCasted x) { return x.tag; });
271
+ m.def("takes_move", [](ConstRefCasted&& x) { return x.tag; });
272
+ m.def("takes_ptr", [](ConstRefCasted* x) { return x->tag; });
273
+ m.def("takes_ref", [](ConstRefCasted& x) { return x.tag; });
274
+ m.def("takes_ref_wrap", [](std::reference_wrapper<ConstRefCasted> x) { return x.get().tag; });
275
+ m.def("takes_const_ptr", [](const ConstRefCasted* x) { return x->tag; });
276
+ m.def("takes_const_ref", [](const ConstRefCasted& x) { return x.tag; });
277
+ m.def("takes_const_ref_wrap", [](std::reference_wrapper<const ConstRefCasted> x) { return x.get().tag; });
278
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_builtin_casters.py ADDED
@@ -0,0 +1,537 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ import pytest
3
+
4
+ import env # noqa: F401
5
+
6
+ from pybind11_tests import builtin_casters as m
7
+ from pybind11_tests import UserType, IncType
8
+
9
+
10
+ def test_simple_string():
11
+ assert m.string_roundtrip("const char *") == "const char *"
12
+
13
+
14
+ def test_unicode_conversion():
15
+ """Tests unicode conversion and error reporting."""
16
+ assert m.good_utf8_string() == u"Say utf8‽ 🎂 𝐀"
17
+ assert m.good_utf16_string() == u"b‽🎂𝐀z"
18
+ assert m.good_utf32_string() == u"a𝐀🎂‽z"
19
+ assert m.good_wchar_string() == u"a⸘𝐀z"
20
+ if hasattr(m, "has_u8string"):
21
+ assert m.good_utf8_u8string() == u"Say utf8‽ 🎂 𝐀"
22
+
23
+ with pytest.raises(UnicodeDecodeError):
24
+ m.bad_utf8_string()
25
+
26
+ with pytest.raises(UnicodeDecodeError):
27
+ m.bad_utf16_string()
28
+
29
+ # These are provided only if they actually fail (they don't when 32-bit and under Python 2.7)
30
+ if hasattr(m, "bad_utf32_string"):
31
+ with pytest.raises(UnicodeDecodeError):
32
+ m.bad_utf32_string()
33
+ if hasattr(m, "bad_wchar_string"):
34
+ with pytest.raises(UnicodeDecodeError):
35
+ m.bad_wchar_string()
36
+ if hasattr(m, "has_u8string"):
37
+ with pytest.raises(UnicodeDecodeError):
38
+ m.bad_utf8_u8string()
39
+
40
+ assert m.u8_Z() == "Z"
41
+ assert m.u8_eacute() == u"é"
42
+ assert m.u16_ibang() == u"‽"
43
+ assert m.u32_mathbfA() == u"𝐀"
44
+ assert m.wchar_heart() == u"♥"
45
+ if hasattr(m, "has_u8string"):
46
+ assert m.u8_char8_Z() == "Z"
47
+
48
+
49
+ def test_single_char_arguments():
50
+ """Tests failures for passing invalid inputs to char-accepting functions"""
51
+
52
+ def toobig_message(r):
53
+ return "Character code point not in range({:#x})".format(r)
54
+
55
+ toolong_message = "Expected a character, but multi-character string found"
56
+
57
+ assert m.ord_char(u"a") == 0x61 # simple ASCII
58
+ assert m.ord_char_lv(u"b") == 0x62
59
+ assert (
60
+ m.ord_char(u"é") == 0xE9
61
+ ) # requires 2 bytes in utf-8, but can be stuffed in a char
62
+ with pytest.raises(ValueError) as excinfo:
63
+ assert m.ord_char(u"Ā") == 0x100 # requires 2 bytes, doesn't fit in a char
64
+ assert str(excinfo.value) == toobig_message(0x100)
65
+ with pytest.raises(ValueError) as excinfo:
66
+ assert m.ord_char(u"ab")
67
+ assert str(excinfo.value) == toolong_message
68
+
69
+ assert m.ord_char16(u"a") == 0x61
70
+ assert m.ord_char16(u"é") == 0xE9
71
+ assert m.ord_char16_lv(u"ê") == 0xEA
72
+ assert m.ord_char16(u"Ā") == 0x100
73
+ assert m.ord_char16(u"‽") == 0x203D
74
+ assert m.ord_char16(u"♥") == 0x2665
75
+ assert m.ord_char16_lv(u"♡") == 0x2661
76
+ with pytest.raises(ValueError) as excinfo:
77
+ assert m.ord_char16(u"🎂") == 0x1F382 # requires surrogate pair
78
+ assert str(excinfo.value) == toobig_message(0x10000)
79
+ with pytest.raises(ValueError) as excinfo:
80
+ assert m.ord_char16(u"aa")
81
+ assert str(excinfo.value) == toolong_message
82
+
83
+ assert m.ord_char32(u"a") == 0x61
84
+ assert m.ord_char32(u"é") == 0xE9
85
+ assert m.ord_char32(u"Ā") == 0x100
86
+ assert m.ord_char32(u"‽") == 0x203D
87
+ assert m.ord_char32(u"♥") == 0x2665
88
+ assert m.ord_char32(u"🎂") == 0x1F382
89
+ with pytest.raises(ValueError) as excinfo:
90
+ assert m.ord_char32(u"aa")
91
+ assert str(excinfo.value) == toolong_message
92
+
93
+ assert m.ord_wchar(u"a") == 0x61
94
+ assert m.ord_wchar(u"é") == 0xE9
95
+ assert m.ord_wchar(u"Ā") == 0x100
96
+ assert m.ord_wchar(u"‽") == 0x203D
97
+ assert m.ord_wchar(u"♥") == 0x2665
98
+ if m.wchar_size == 2:
99
+ with pytest.raises(ValueError) as excinfo:
100
+ assert m.ord_wchar(u"🎂") == 0x1F382 # requires surrogate pair
101
+ assert str(excinfo.value) == toobig_message(0x10000)
102
+ else:
103
+ assert m.ord_wchar(u"🎂") == 0x1F382
104
+ with pytest.raises(ValueError) as excinfo:
105
+ assert m.ord_wchar(u"aa")
106
+ assert str(excinfo.value) == toolong_message
107
+
108
+ if hasattr(m, "has_u8string"):
109
+ assert m.ord_char8(u"a") == 0x61 # simple ASCII
110
+ assert m.ord_char8_lv(u"b") == 0x62
111
+ assert (
112
+ m.ord_char8(u"é") == 0xE9
113
+ ) # requires 2 bytes in utf-8, but can be stuffed in a char
114
+ with pytest.raises(ValueError) as excinfo:
115
+ assert m.ord_char8(u"Ā") == 0x100 # requires 2 bytes, doesn't fit in a char
116
+ assert str(excinfo.value) == toobig_message(0x100)
117
+ with pytest.raises(ValueError) as excinfo:
118
+ assert m.ord_char8(u"ab")
119
+ assert str(excinfo.value) == toolong_message
120
+
121
+
122
+ def test_bytes_to_string():
123
+ """Tests the ability to pass bytes to C++ string-accepting functions. Note that this is
124
+ one-way: the only way to return bytes to Python is via the pybind11::bytes class."""
125
+ # Issue #816
126
+
127
+ def to_bytes(s):
128
+ b = s if env.PY2 else s.encode("utf8")
129
+ assert isinstance(b, bytes)
130
+ return b
131
+
132
+ assert m.strlen(to_bytes("hi")) == 2
133
+ assert m.string_length(to_bytes("world")) == 5
134
+ assert m.string_length(to_bytes("a\x00b")) == 3
135
+ assert m.strlen(to_bytes("a\x00b")) == 1 # C-string limitation
136
+
137
+ # passing in a utf8 encoded string should work
138
+ assert m.string_length(u"💩".encode("utf8")) == 4
139
+
140
+
141
+ @pytest.mark.skipif(not hasattr(m, "has_string_view"), reason="no <string_view>")
142
+ def test_string_view(capture):
143
+ """Tests support for C++17 string_view arguments and return values"""
144
+ assert m.string_view_chars("Hi") == [72, 105]
145
+ assert m.string_view_chars("Hi 🎂") == [72, 105, 32, 0xF0, 0x9F, 0x8E, 0x82]
146
+ assert m.string_view16_chars(u"Hi 🎂") == [72, 105, 32, 0xD83C, 0xDF82]
147
+ assert m.string_view32_chars(u"Hi 🎂") == [72, 105, 32, 127874]
148
+ if hasattr(m, "has_u8string"):
149
+ assert m.string_view8_chars("Hi") == [72, 105]
150
+ assert m.string_view8_chars(u"Hi 🎂") == [72, 105, 32, 0xF0, 0x9F, 0x8E, 0x82]
151
+
152
+ assert m.string_view_return() == u"utf8 secret 🎂"
153
+ assert m.string_view16_return() == u"utf16 secret 🎂"
154
+ assert m.string_view32_return() == u"utf32 secret 🎂"
155
+ if hasattr(m, "has_u8string"):
156
+ assert m.string_view8_return() == u"utf8 secret 🎂"
157
+
158
+ with capture:
159
+ m.string_view_print("Hi")
160
+ m.string_view_print("utf8 🎂")
161
+ m.string_view16_print(u"utf16 🎂")
162
+ m.string_view32_print(u"utf32 🎂")
163
+ assert (
164
+ capture
165
+ == u"""
166
+ Hi 2
167
+ utf8 🎂 9
168
+ utf16 🎂 8
169
+ utf32 🎂 7
170
+ """
171
+ )
172
+ if hasattr(m, "has_u8string"):
173
+ with capture:
174
+ m.string_view8_print("Hi")
175
+ m.string_view8_print(u"utf8 🎂")
176
+ assert (
177
+ capture
178
+ == u"""
179
+ Hi 2
180
+ utf8 🎂 9
181
+ """
182
+ )
183
+
184
+ with capture:
185
+ m.string_view_print("Hi, ascii")
186
+ m.string_view_print("Hi, utf8 🎂")
187
+ m.string_view16_print(u"Hi, utf16 🎂")
188
+ m.string_view32_print(u"Hi, utf32 🎂")
189
+ assert (
190
+ capture
191
+ == u"""
192
+ Hi, ascii 9
193
+ Hi, utf8 🎂 13
194
+ Hi, utf16 🎂 12
195
+ Hi, utf32 🎂 11
196
+ """
197
+ )
198
+ if hasattr(m, "has_u8string"):
199
+ with capture:
200
+ m.string_view8_print("Hi, ascii")
201
+ m.string_view8_print(u"Hi, utf8 🎂")
202
+ assert (
203
+ capture
204
+ == u"""
205
+ Hi, ascii 9
206
+ Hi, utf8 🎂 13
207
+ """
208
+ )
209
+
210
+
211
+ def test_integer_casting():
212
+ """Issue #929 - out-of-range integer values shouldn't be accepted"""
213
+ assert m.i32_str(-1) == "-1"
214
+ assert m.i64_str(-1) == "-1"
215
+ assert m.i32_str(2000000000) == "2000000000"
216
+ assert m.u32_str(2000000000) == "2000000000"
217
+ if env.PY2:
218
+ assert m.i32_str(long(-1)) == "-1" # noqa: F821 undefined name 'long'
219
+ assert m.i64_str(long(-1)) == "-1" # noqa: F821 undefined name 'long'
220
+ assert (
221
+ m.i64_str(long(-999999999999)) # noqa: F821 undefined name 'long'
222
+ == "-999999999999"
223
+ )
224
+ assert (
225
+ m.u64_str(long(999999999999)) # noqa: F821 undefined name 'long'
226
+ == "999999999999"
227
+ )
228
+ else:
229
+ assert m.i64_str(-999999999999) == "-999999999999"
230
+ assert m.u64_str(999999999999) == "999999999999"
231
+
232
+ with pytest.raises(TypeError) as excinfo:
233
+ m.u32_str(-1)
234
+ assert "incompatible function arguments" in str(excinfo.value)
235
+ with pytest.raises(TypeError) as excinfo:
236
+ m.u64_str(-1)
237
+ assert "incompatible function arguments" in str(excinfo.value)
238
+ with pytest.raises(TypeError) as excinfo:
239
+ m.i32_str(-3000000000)
240
+ assert "incompatible function arguments" in str(excinfo.value)
241
+ with pytest.raises(TypeError) as excinfo:
242
+ m.i32_str(3000000000)
243
+ assert "incompatible function arguments" in str(excinfo.value)
244
+
245
+ if env.PY2:
246
+ with pytest.raises(TypeError) as excinfo:
247
+ m.u32_str(long(-1)) # noqa: F821 undefined name 'long'
248
+ assert "incompatible function arguments" in str(excinfo.value)
249
+ with pytest.raises(TypeError) as excinfo:
250
+ m.u64_str(long(-1)) # noqa: F821 undefined name 'long'
251
+ assert "incompatible function arguments" in str(excinfo.value)
252
+
253
+
254
+ def test_int_convert():
255
+ class Int(object):
256
+ def __int__(self):
257
+ return 42
258
+
259
+ class NotInt(object):
260
+ pass
261
+
262
+ class Float(object):
263
+ def __float__(self):
264
+ return 41.99999
265
+
266
+ class Index(object):
267
+ def __index__(self):
268
+ return 42
269
+
270
+ class IntAndIndex(object):
271
+ def __int__(self):
272
+ return 42
273
+
274
+ def __index__(self):
275
+ return 0
276
+
277
+ class RaisingTypeErrorOnIndex(object):
278
+ def __index__(self):
279
+ raise TypeError
280
+
281
+ def __int__(self):
282
+ return 42
283
+
284
+ class RaisingValueErrorOnIndex(object):
285
+ def __index__(self):
286
+ raise ValueError
287
+
288
+ def __int__(self):
289
+ return 42
290
+
291
+ convert, noconvert = m.int_passthrough, m.int_passthrough_noconvert
292
+
293
+ def requires_conversion(v):
294
+ pytest.raises(TypeError, noconvert, v)
295
+
296
+ def cant_convert(v):
297
+ pytest.raises(TypeError, convert, v)
298
+
299
+ assert convert(7) == 7
300
+ assert noconvert(7) == 7
301
+ cant_convert(3.14159)
302
+ # TODO: Avoid DeprecationWarning in `PyLong_AsLong` (and similar)
303
+ if (3, 8) <= env.PY < (3, 10):
304
+ with env.deprecated_call():
305
+ assert convert(Int()) == 42
306
+ else:
307
+ assert convert(Int()) == 42
308
+ requires_conversion(Int())
309
+ cant_convert(NotInt())
310
+ cant_convert(Float())
311
+
312
+ # Before Python 3.8, `PyLong_AsLong` does not pick up on `obj.__index__`,
313
+ # but pybind11 "backports" this behavior.
314
+ assert convert(Index()) == 42
315
+ assert noconvert(Index()) == 42
316
+ assert convert(IntAndIndex()) == 0 # Fishy; `int(DoubleThought)` == 42
317
+ assert noconvert(IntAndIndex()) == 0
318
+ assert convert(RaisingTypeErrorOnIndex()) == 42
319
+ requires_conversion(RaisingTypeErrorOnIndex())
320
+ assert convert(RaisingValueErrorOnIndex()) == 42
321
+ requires_conversion(RaisingValueErrorOnIndex())
322
+
323
+
324
+ def test_numpy_int_convert():
325
+ np = pytest.importorskip("numpy")
326
+
327
+ convert, noconvert = m.int_passthrough, m.int_passthrough_noconvert
328
+
329
+ def require_implicit(v):
330
+ pytest.raises(TypeError, noconvert, v)
331
+
332
+ # `np.intc` is an alias that corresponds to a C++ `int`
333
+ assert convert(np.intc(42)) == 42
334
+ assert noconvert(np.intc(42)) == 42
335
+
336
+ # The implicit conversion from np.float32 is undesirable but currently accepted.
337
+ # TODO: Avoid DeprecationWarning in `PyLong_AsLong` (and similar)
338
+ if (3, 8) <= env.PY < (3, 10):
339
+ with env.deprecated_call():
340
+ assert convert(np.float32(3.14159)) == 3
341
+ else:
342
+ assert convert(np.float32(3.14159)) == 3
343
+ require_implicit(np.float32(3.14159))
344
+
345
+
346
+ def test_tuple(doc):
347
+ """std::pair <-> tuple & std::tuple <-> tuple"""
348
+ assert m.pair_passthrough((True, "test")) == ("test", True)
349
+ assert m.tuple_passthrough((True, "test", 5)) == (5, "test", True)
350
+ # Any sequence can be cast to a std::pair or std::tuple
351
+ assert m.pair_passthrough([True, "test"]) == ("test", True)
352
+ assert m.tuple_passthrough([True, "test", 5]) == (5, "test", True)
353
+ assert m.empty_tuple() == ()
354
+
355
+ assert (
356
+ doc(m.pair_passthrough)
357
+ == """
358
+ pair_passthrough(arg0: Tuple[bool, str]) -> Tuple[str, bool]
359
+
360
+ Return a pair in reversed order
361
+ """
362
+ )
363
+ assert (
364
+ doc(m.tuple_passthrough)
365
+ == """
366
+ tuple_passthrough(arg0: Tuple[bool, str, int]) -> Tuple[int, str, bool]
367
+
368
+ Return a triple in reversed order
369
+ """
370
+ )
371
+
372
+ assert m.rvalue_pair() == ("rvalue", "rvalue")
373
+ assert m.lvalue_pair() == ("lvalue", "lvalue")
374
+ assert m.rvalue_tuple() == ("rvalue", "rvalue", "rvalue")
375
+ assert m.lvalue_tuple() == ("lvalue", "lvalue", "lvalue")
376
+ assert m.rvalue_nested() == ("rvalue", ("rvalue", ("rvalue", "rvalue")))
377
+ assert m.lvalue_nested() == ("lvalue", ("lvalue", ("lvalue", "lvalue")))
378
+
379
+ assert m.int_string_pair() == (2, "items")
380
+
381
+
382
+ def test_builtins_cast_return_none():
383
+ """Casters produced with PYBIND11_TYPE_CASTER() should convert nullptr to None"""
384
+ assert m.return_none_string() is None
385
+ assert m.return_none_char() is None
386
+ assert m.return_none_bool() is None
387
+ assert m.return_none_int() is None
388
+ assert m.return_none_float() is None
389
+ assert m.return_none_pair() is None
390
+
391
+
392
+ def test_none_deferred():
393
+ """None passed as various argument types should defer to other overloads"""
394
+ assert not m.defer_none_cstring("abc")
395
+ assert m.defer_none_cstring(None)
396
+ assert not m.defer_none_custom(UserType())
397
+ assert m.defer_none_custom(None)
398
+ assert m.nodefer_none_void(None)
399
+
400
+
401
+ def test_void_caster():
402
+ assert m.load_nullptr_t(None) is None
403
+ assert m.cast_nullptr_t() is None
404
+
405
+
406
+ def test_reference_wrapper():
407
+ """std::reference_wrapper for builtin and user types"""
408
+ assert m.refwrap_builtin(42) == 420
409
+ assert m.refwrap_usertype(UserType(42)) == 42
410
+ assert m.refwrap_usertype_const(UserType(42)) == 42
411
+
412
+ with pytest.raises(TypeError) as excinfo:
413
+ m.refwrap_builtin(None)
414
+ assert "incompatible function arguments" in str(excinfo.value)
415
+
416
+ with pytest.raises(TypeError) as excinfo:
417
+ m.refwrap_usertype(None)
418
+ assert "incompatible function arguments" in str(excinfo.value)
419
+
420
+ assert m.refwrap_lvalue().value == 1
421
+ assert m.refwrap_lvalue_const().value == 1
422
+
423
+ a1 = m.refwrap_list(copy=True)
424
+ a2 = m.refwrap_list(copy=True)
425
+ assert [x.value for x in a1] == [2, 3]
426
+ assert [x.value for x in a2] == [2, 3]
427
+ assert not a1[0] is a2[0] and not a1[1] is a2[1]
428
+
429
+ b1 = m.refwrap_list(copy=False)
430
+ b2 = m.refwrap_list(copy=False)
431
+ assert [x.value for x in b1] == [1, 2]
432
+ assert [x.value for x in b2] == [1, 2]
433
+ assert b1[0] is b2[0] and b1[1] is b2[1]
434
+
435
+ assert m.refwrap_iiw(IncType(5)) == 5
436
+ assert m.refwrap_call_iiw(IncType(10), m.refwrap_iiw) == [10, 10, 10, 10]
437
+
438
+
439
+ def test_complex_cast():
440
+ """std::complex casts"""
441
+ assert m.complex_cast(1) == "1.0"
442
+ assert m.complex_cast(2j) == "(0.0, 2.0)"
443
+
444
+
445
+ def test_bool_caster():
446
+ """Test bool caster implicit conversions."""
447
+ convert, noconvert = m.bool_passthrough, m.bool_passthrough_noconvert
448
+
449
+ def require_implicit(v):
450
+ pytest.raises(TypeError, noconvert, v)
451
+
452
+ def cant_convert(v):
453
+ pytest.raises(TypeError, convert, v)
454
+
455
+ # straight up bool
456
+ assert convert(True) is True
457
+ assert convert(False) is False
458
+ assert noconvert(True) is True
459
+ assert noconvert(False) is False
460
+
461
+ # None requires implicit conversion
462
+ require_implicit(None)
463
+ assert convert(None) is False
464
+
465
+ class A(object):
466
+ def __init__(self, x):
467
+ self.x = x
468
+
469
+ def __nonzero__(self):
470
+ return self.x
471
+
472
+ def __bool__(self):
473
+ return self.x
474
+
475
+ class B(object):
476
+ pass
477
+
478
+ # Arbitrary objects are not accepted
479
+ cant_convert(object())
480
+ cant_convert(B())
481
+
482
+ # Objects with __nonzero__ / __bool__ defined can be converted
483
+ require_implicit(A(True))
484
+ assert convert(A(True)) is True
485
+ assert convert(A(False)) is False
486
+
487
+
488
+ def test_numpy_bool():
489
+ np = pytest.importorskip("numpy")
490
+
491
+ convert, noconvert = m.bool_passthrough, m.bool_passthrough_noconvert
492
+
493
+ def cant_convert(v):
494
+ pytest.raises(TypeError, convert, v)
495
+
496
+ # np.bool_ is not considered implicit
497
+ assert convert(np.bool_(True)) is True
498
+ assert convert(np.bool_(False)) is False
499
+ assert noconvert(np.bool_(True)) is True
500
+ assert noconvert(np.bool_(False)) is False
501
+ cant_convert(np.zeros(2, dtype="int"))
502
+
503
+
504
+ def test_int_long():
505
+ """In Python 2, a C++ int should return a Python int rather than long
506
+ if possible: longs are not always accepted where ints are used (such
507
+ as the argument to sys.exit()). A C++ long long is always a Python
508
+ long."""
509
+
510
+ import sys
511
+
512
+ must_be_long = type(getattr(sys, "maxint", 1) + 1)
513
+ assert isinstance(m.int_cast(), int)
514
+ assert isinstance(m.long_cast(), int)
515
+ assert isinstance(m.longlong_cast(), must_be_long)
516
+
517
+
518
+ def test_void_caster_2():
519
+ assert m.test_void_caster()
520
+
521
+
522
+ def test_const_ref_caster():
523
+ """Verifies that const-ref is propagated through type_caster cast_op.
524
+ The returned ConstRefCasted type is a minimal type that is constructed to
525
+ reference the casting mode used.
526
+ """
527
+ x = False
528
+ assert m.takes(x) == 1
529
+ assert m.takes_move(x) == 1
530
+
531
+ assert m.takes_ptr(x) == 3
532
+ assert m.takes_ref(x) == 2
533
+ assert m.takes_ref_wrap(x) == 2
534
+
535
+ assert m.takes_const_ptr(x) == 5
536
+ assert m.takes_const_ref(x) == 4
537
+ assert m.takes_const_ref_wrap(x) == 4
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_call_policies.cpp ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ tests/test_call_policies.cpp -- keep_alive and call_guard
3
+
4
+ Copyright (c) 2016 Wenzel Jakob <[email protected]>
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
+
12
+ struct CustomGuard {
13
+ static bool enabled;
14
+
15
+ CustomGuard() { enabled = true; }
16
+ ~CustomGuard() { enabled = false; }
17
+
18
+ static const char *report_status() { return enabled ? "guarded" : "unguarded"; }
19
+ };
20
+ bool CustomGuard::enabled = false;
21
+
22
+ struct DependentGuard {
23
+ static bool enabled;
24
+
25
+ DependentGuard() { enabled = CustomGuard::enabled; }
26
+ ~DependentGuard() { enabled = false; }
27
+
28
+ static const char *report_status() { return enabled ? "guarded" : "unguarded"; }
29
+ };
30
+ bool DependentGuard::enabled = false;
31
+
32
+ TEST_SUBMODULE(call_policies, m) {
33
+ // Parent/Child are used in:
34
+ // test_keep_alive_argument, test_keep_alive_return_value, test_alive_gc_derived,
35
+ // test_alive_gc_multi_derived, test_return_none, test_keep_alive_constructor
36
+ class Child {
37
+ public:
38
+ Child() { py::print("Allocating child."); }
39
+ Child(const Child &) = default;
40
+ Child(Child &&) = default;
41
+ ~Child() { py::print("Releasing child."); }
42
+ };
43
+ py::class_<Child>(m, "Child")
44
+ .def(py::init<>());
45
+
46
+ class Parent {
47
+ public:
48
+ Parent() { py::print("Allocating parent."); }
49
+ Parent(const Parent& parent) = default;
50
+ ~Parent() { py::print("Releasing parent."); }
51
+ void addChild(Child *) { }
52
+ Child *returnChild() { return new Child(); }
53
+ Child *returnNullChild() { return nullptr; }
54
+ static Child *staticFunction(Parent*) { return new Child(); }
55
+ };
56
+ py::class_<Parent>(m, "Parent")
57
+ .def(py::init<>())
58
+ .def(py::init([](Child *) { return new Parent(); }), py::keep_alive<1, 2>())
59
+ .def("addChild", &Parent::addChild)
60
+ .def("addChildKeepAlive", &Parent::addChild, py::keep_alive<1, 2>())
61
+ .def("returnChild", &Parent::returnChild)
62
+ .def("returnChildKeepAlive", &Parent::returnChild, py::keep_alive<1, 0>())
63
+ .def("returnNullChildKeepAliveChild", &Parent::returnNullChild, py::keep_alive<1, 0>())
64
+ .def("returnNullChildKeepAliveParent", &Parent::returnNullChild, py::keep_alive<0, 1>())
65
+ .def_static(
66
+ "staticFunction", &Parent::staticFunction, py::keep_alive<1, 0>());
67
+
68
+ m.def("free_function", [](Parent*, Child*) {}, py::keep_alive<1, 2>());
69
+ m.def("invalid_arg_index", []{}, py::keep_alive<0, 1>());
70
+
71
+ #if !defined(PYPY_VERSION)
72
+ // test_alive_gc
73
+ class ParentGC : public Parent {
74
+ public:
75
+ using Parent::Parent;
76
+ };
77
+ py::class_<ParentGC, Parent>(m, "ParentGC", py::dynamic_attr())
78
+ .def(py::init<>());
79
+ #endif
80
+
81
+ // test_call_guard
82
+ m.def("unguarded_call", &CustomGuard::report_status);
83
+ m.def("guarded_call", &CustomGuard::report_status, py::call_guard<CustomGuard>());
84
+
85
+ m.def("multiple_guards_correct_order", []() {
86
+ return CustomGuard::report_status() + std::string(" & ") + DependentGuard::report_status();
87
+ }, py::call_guard<CustomGuard, DependentGuard>());
88
+
89
+ m.def("multiple_guards_wrong_order", []() {
90
+ return DependentGuard::report_status() + std::string(" & ") + CustomGuard::report_status();
91
+ }, py::call_guard<DependentGuard, CustomGuard>());
92
+
93
+ #if defined(WITH_THREAD) && !defined(PYPY_VERSION)
94
+ // `py::call_guard<py::gil_scoped_release>()` should work in PyPy as well,
95
+ // but it's unclear how to test it without `PyGILState_GetThisThreadState`.
96
+ auto report_gil_status = []() {
97
+ auto is_gil_held = false;
98
+ if (auto tstate = py::detail::get_thread_state_unchecked())
99
+ is_gil_held = (tstate == PyGILState_GetThisThreadState());
100
+
101
+ return is_gil_held ? "GIL held" : "GIL released";
102
+ };
103
+
104
+ m.def("with_gil", report_gil_status);
105
+ m.def("without_gil", report_gil_status, py::call_guard<py::gil_scoped_release>());
106
+ #endif
107
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_call_policies.py ADDED
@@ -0,0 +1,249 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ import pytest
3
+
4
+ import env # noqa: F401
5
+
6
+ from pybind11_tests import call_policies as m
7
+ from pybind11_tests import ConstructorStats
8
+
9
+
10
+ @pytest.mark.xfail("env.PYPY", reason="sometimes comes out 1 off on PyPy", strict=False)
11
+ def test_keep_alive_argument(capture):
12
+ n_inst = ConstructorStats.detail_reg_inst()
13
+ with capture:
14
+ p = m.Parent()
15
+ assert capture == "Allocating parent."
16
+ with capture:
17
+ p.addChild(m.Child())
18
+ assert ConstructorStats.detail_reg_inst() == n_inst + 1
19
+ assert (
20
+ capture
21
+ == """
22
+ Allocating child.
23
+ Releasing child.
24
+ """
25
+ )
26
+ with capture:
27
+ del p
28
+ assert ConstructorStats.detail_reg_inst() == n_inst
29
+ assert capture == "Releasing parent."
30
+
31
+ with capture:
32
+ p = m.Parent()
33
+ assert capture == "Allocating parent."
34
+ with capture:
35
+ p.addChildKeepAlive(m.Child())
36
+ assert ConstructorStats.detail_reg_inst() == n_inst + 2
37
+ assert capture == "Allocating child."
38
+ with capture:
39
+ del p
40
+ assert ConstructorStats.detail_reg_inst() == n_inst
41
+ assert (
42
+ capture
43
+ == """
44
+ Releasing parent.
45
+ Releasing child.
46
+ """
47
+ )
48
+
49
+ p = m.Parent()
50
+ c = m.Child()
51
+ assert ConstructorStats.detail_reg_inst() == n_inst + 2
52
+ m.free_function(p, c)
53
+ del c
54
+ assert ConstructorStats.detail_reg_inst() == n_inst + 2
55
+ del p
56
+ assert ConstructorStats.detail_reg_inst() == n_inst
57
+
58
+ with pytest.raises(RuntimeError) as excinfo:
59
+ m.invalid_arg_index()
60
+ assert str(excinfo.value) == "Could not activate keep_alive!"
61
+
62
+
63
+ def test_keep_alive_return_value(capture):
64
+ n_inst = ConstructorStats.detail_reg_inst()
65
+ with capture:
66
+ p = m.Parent()
67
+ assert capture == "Allocating parent."
68
+ with capture:
69
+ p.returnChild()
70
+ assert ConstructorStats.detail_reg_inst() == n_inst + 1
71
+ assert (
72
+ capture
73
+ == """
74
+ Allocating child.
75
+ Releasing child.
76
+ """
77
+ )
78
+ with capture:
79
+ del p
80
+ assert ConstructorStats.detail_reg_inst() == n_inst
81
+ assert capture == "Releasing parent."
82
+
83
+ with capture:
84
+ p = m.Parent()
85
+ assert capture == "Allocating parent."
86
+ with capture:
87
+ p.returnChildKeepAlive()
88
+ assert ConstructorStats.detail_reg_inst() == n_inst + 2
89
+ assert capture == "Allocating child."
90
+ with capture:
91
+ del p
92
+ assert ConstructorStats.detail_reg_inst() == n_inst
93
+ assert (
94
+ capture
95
+ == """
96
+ Releasing parent.
97
+ Releasing child.
98
+ """
99
+ )
100
+
101
+ p = m.Parent()
102
+ assert ConstructorStats.detail_reg_inst() == n_inst + 1
103
+ with capture:
104
+ m.Parent.staticFunction(p)
105
+ assert ConstructorStats.detail_reg_inst() == n_inst + 2
106
+ assert capture == "Allocating child."
107
+ with capture:
108
+ del p
109
+ assert ConstructorStats.detail_reg_inst() == n_inst
110
+ assert (
111
+ capture
112
+ == """
113
+ Releasing parent.
114
+ Releasing child.
115
+ """
116
+ )
117
+
118
+
119
+ # https://foss.heptapod.net/pypy/pypy/-/issues/2447
120
+ @pytest.mark.xfail("env.PYPY", reason="_PyObject_GetDictPtr is unimplemented")
121
+ def test_alive_gc(capture):
122
+ n_inst = ConstructorStats.detail_reg_inst()
123
+ p = m.ParentGC()
124
+ p.addChildKeepAlive(m.Child())
125
+ assert ConstructorStats.detail_reg_inst() == n_inst + 2
126
+ lst = [p]
127
+ lst.append(lst) # creates a circular reference
128
+ with capture:
129
+ del p, lst
130
+ assert ConstructorStats.detail_reg_inst() == n_inst
131
+ assert (
132
+ capture
133
+ == """
134
+ Releasing parent.
135
+ Releasing child.
136
+ """
137
+ )
138
+
139
+
140
+ def test_alive_gc_derived(capture):
141
+ class Derived(m.Parent):
142
+ pass
143
+
144
+ n_inst = ConstructorStats.detail_reg_inst()
145
+ p = Derived()
146
+ p.addChildKeepAlive(m.Child())
147
+ assert ConstructorStats.detail_reg_inst() == n_inst + 2
148
+ lst = [p]
149
+ lst.append(lst) # creates a circular reference
150
+ with capture:
151
+ del p, lst
152
+ assert ConstructorStats.detail_reg_inst() == n_inst
153
+ assert (
154
+ capture
155
+ == """
156
+ Releasing parent.
157
+ Releasing child.
158
+ """
159
+ )
160
+
161
+
162
+ def test_alive_gc_multi_derived(capture):
163
+ class Derived(m.Parent, m.Child):
164
+ def __init__(self):
165
+ m.Parent.__init__(self)
166
+ m.Child.__init__(self)
167
+
168
+ n_inst = ConstructorStats.detail_reg_inst()
169
+ p = Derived()
170
+ p.addChildKeepAlive(m.Child())
171
+ # +3 rather than +2 because Derived corresponds to two registered instances
172
+ assert ConstructorStats.detail_reg_inst() == n_inst + 3
173
+ lst = [p]
174
+ lst.append(lst) # creates a circular reference
175
+ with capture:
176
+ del p, lst
177
+ assert ConstructorStats.detail_reg_inst() == n_inst
178
+ assert (
179
+ capture
180
+ == """
181
+ Releasing parent.
182
+ Releasing child.
183
+ Releasing child.
184
+ """
185
+ )
186
+
187
+
188
+ def test_return_none(capture):
189
+ n_inst = ConstructorStats.detail_reg_inst()
190
+ with capture:
191
+ p = m.Parent()
192
+ assert capture == "Allocating parent."
193
+ with capture:
194
+ p.returnNullChildKeepAliveChild()
195
+ assert ConstructorStats.detail_reg_inst() == n_inst + 1
196
+ assert capture == ""
197
+ with capture:
198
+ del p
199
+ assert ConstructorStats.detail_reg_inst() == n_inst
200
+ assert capture == "Releasing parent."
201
+
202
+ with capture:
203
+ p = m.Parent()
204
+ assert capture == "Allocating parent."
205
+ with capture:
206
+ p.returnNullChildKeepAliveParent()
207
+ assert ConstructorStats.detail_reg_inst() == n_inst + 1
208
+ assert capture == ""
209
+ with capture:
210
+ del p
211
+ assert ConstructorStats.detail_reg_inst() == n_inst
212
+ assert capture == "Releasing parent."
213
+
214
+
215
+ def test_keep_alive_constructor(capture):
216
+ n_inst = ConstructorStats.detail_reg_inst()
217
+
218
+ with capture:
219
+ p = m.Parent(m.Child())
220
+ assert ConstructorStats.detail_reg_inst() == n_inst + 2
221
+ assert (
222
+ capture
223
+ == """
224
+ Allocating child.
225
+ Allocating parent.
226
+ """
227
+ )
228
+ with capture:
229
+ del p
230
+ assert ConstructorStats.detail_reg_inst() == n_inst
231
+ assert (
232
+ capture
233
+ == """
234
+ Releasing parent.
235
+ Releasing child.
236
+ """
237
+ )
238
+
239
+
240
+ def test_call_guard():
241
+ assert m.unguarded_call() == "unguarded"
242
+ assert m.guarded_call() == "guarded"
243
+
244
+ assert m.multiple_guards_correct_order() == "guarded & guarded"
245
+ assert m.multiple_guards_wrong_order() == "unguarded & guarded"
246
+
247
+ if hasattr(m, "with_gil"):
248
+ assert m.with_gil() == "GIL held"
249
+ assert m.without_gil() == "GIL released"
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_callbacks.cpp ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ tests/test_callbacks.cpp -- callbacks
3
+
4
+ Copyright (c) 2016 Wenzel Jakob <[email protected]>
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
+ #include <pybind11/functional.h>
13
+ #include <thread>
14
+
15
+
16
+ int dummy_function(int i) { return i + 1; }
17
+
18
+ TEST_SUBMODULE(callbacks, m) {
19
+ // test_callbacks, test_function_signatures
20
+ m.def("test_callback1", [](const py::object &func) { return func(); });
21
+ m.def("test_callback2", [](const py::object &func) { return func("Hello", 'x', true, 5); });
22
+ m.def("test_callback3", [](const std::function<int(int)> &func) {
23
+ return "func(43) = " + std::to_string(func(43)); });
24
+ m.def("test_callback4", []() -> std::function<int(int)> { return [](int i) { return i+1; }; });
25
+ m.def("test_callback5", []() {
26
+ return py::cpp_function([](int i) { return i+1; }, py::arg("number"));
27
+ });
28
+
29
+ // test_keyword_args_and_generalized_unpacking
30
+ m.def("test_tuple_unpacking", [](const py::function &f) {
31
+ auto t1 = py::make_tuple(2, 3);
32
+ auto t2 = py::make_tuple(5, 6);
33
+ return f("positional", 1, *t1, 4, *t2);
34
+ });
35
+
36
+ m.def("test_dict_unpacking", [](const py::function &f) {
37
+ auto d1 = py::dict("key"_a="value", "a"_a=1);
38
+ auto d2 = py::dict();
39
+ auto d3 = py::dict("b"_a=2);
40
+ return f("positional", 1, **d1, **d2, **d3);
41
+ });
42
+
43
+ m.def("test_keyword_args", [](const py::function &f) { return f("x"_a = 10, "y"_a = 20); });
44
+
45
+ m.def("test_unpacking_and_keywords1", [](const py::function &f) {
46
+ auto args = py::make_tuple(2);
47
+ auto kwargs = py::dict("d"_a=4);
48
+ return f(1, *args, "c"_a=3, **kwargs);
49
+ });
50
+
51
+ m.def("test_unpacking_and_keywords2", [](const py::function &f) {
52
+ auto kwargs1 = py::dict("a"_a=1);
53
+ auto kwargs2 = py::dict("c"_a=3, "d"_a=4);
54
+ return f("positional", *py::make_tuple(1), 2, *py::make_tuple(3, 4), 5,
55
+ "key"_a="value", **kwargs1, "b"_a=2, **kwargs2, "e"_a=5);
56
+ });
57
+
58
+ m.def("test_unpacking_error1", [](const py::function &f) {
59
+ auto kwargs = py::dict("x"_a=3);
60
+ return f("x"_a=1, "y"_a=2, **kwargs); // duplicate ** after keyword
61
+ });
62
+
63
+ m.def("test_unpacking_error2", [](const py::function &f) {
64
+ auto kwargs = py::dict("x"_a=3);
65
+ return f(**kwargs, "x"_a=1); // duplicate keyword after **
66
+ });
67
+
68
+ m.def("test_arg_conversion_error1",
69
+ [](const py::function &f) { f(234, UnregisteredType(), "kw"_a = 567); });
70
+
71
+ m.def("test_arg_conversion_error2", [](const py::function &f) {
72
+ f(234, "expected_name"_a=UnregisteredType(), "kw"_a=567);
73
+ });
74
+
75
+ // test_lambda_closure_cleanup
76
+ struct Payload {
77
+ Payload() { print_default_created(this); }
78
+ ~Payload() { print_destroyed(this); }
79
+ Payload(const Payload &) { print_copy_created(this); }
80
+ Payload(Payload &&) noexcept { print_move_created(this); }
81
+ };
82
+ // Export the payload constructor statistics for testing purposes:
83
+ m.def("payload_cstats", &ConstructorStats::get<Payload>);
84
+ /* Test cleanup of lambda closure */
85
+ m.def("test_cleanup", []() -> std::function<void()> {
86
+ Payload p;
87
+
88
+ return [p]() {
89
+ /* p should be cleaned up when the returned function is garbage collected */
90
+ (void) p;
91
+ };
92
+ });
93
+
94
+ // test_cpp_function_roundtrip
95
+ /* Test if passing a function pointer from C++ -> Python -> C++ yields the original pointer */
96
+ m.def("dummy_function", &dummy_function);
97
+ m.def("dummy_function_overloaded", [](int i, int j) { return i + j; });
98
+ m.def("dummy_function_overloaded", &dummy_function);
99
+ m.def("dummy_function2", [](int i, int j) { return i + j; });
100
+ m.def("roundtrip", [](std::function<int(int)> f, bool expect_none = false) {
101
+ if (expect_none && f)
102
+ throw std::runtime_error("Expected None to be converted to empty std::function");
103
+ return f;
104
+ }, py::arg("f"), py::arg("expect_none")=false);
105
+ m.def("test_dummy_function", [](const std::function<int(int)> &f) -> std::string {
106
+ using fn_type = int (*)(int);
107
+ auto result = f.target<fn_type>();
108
+ if (!result) {
109
+ auto r = f(1);
110
+ return "can't convert to function pointer: eval(1) = " + std::to_string(r);
111
+ }
112
+ if (*result == dummy_function) {
113
+ auto r = (*result)(1);
114
+ return "matches dummy_function: eval(1) = " + std::to_string(r);
115
+ }
116
+ return "argument does NOT match dummy_function. This should never happen!";
117
+
118
+ });
119
+
120
+ class AbstractBase {
121
+ public:
122
+ // [workaround(intel)] = default does not work here
123
+ // Defaulting this destructor results in linking errors with the Intel compiler
124
+ // (in Debug builds only, tested with icpc (ICC) 2021.1 Beta 20200827)
125
+ virtual ~AbstractBase() {} // NOLINT(modernize-use-equals-default)
126
+ virtual unsigned int func() = 0;
127
+ };
128
+ m.def("func_accepting_func_accepting_base",
129
+ [](const std::function<double(AbstractBase &)> &) {});
130
+
131
+ struct MovableObject {
132
+ bool valid = true;
133
+
134
+ MovableObject() = default;
135
+ MovableObject(const MovableObject &) = default;
136
+ MovableObject &operator=(const MovableObject &) = default;
137
+ MovableObject(MovableObject &&o) noexcept : valid(o.valid) { o.valid = false; }
138
+ MovableObject &operator=(MovableObject &&o) noexcept {
139
+ valid = o.valid;
140
+ o.valid = false;
141
+ return *this;
142
+ }
143
+ };
144
+ py::class_<MovableObject>(m, "MovableObject");
145
+
146
+ // test_movable_object
147
+ m.def("callback_with_movable", [](const std::function<void(MovableObject &)> &f) {
148
+ auto x = MovableObject();
149
+ f(x); // lvalue reference shouldn't move out object
150
+ return x.valid; // must still return `true`
151
+ });
152
+
153
+ // test_bound_method_callback
154
+ struct CppBoundMethodTest {};
155
+ py::class_<CppBoundMethodTest>(m, "CppBoundMethodTest")
156
+ .def(py::init<>())
157
+ .def("triple", [](CppBoundMethodTest &, int val) { return 3 * val; });
158
+
159
+ // This checks that builtin functions can be passed as callbacks
160
+ // rather than throwing RuntimeError due to trying to extract as capsule
161
+ m.def("test_sum_builtin", [](const std::function<double(py::iterable)> &sum_builtin, const py::iterable &i) {
162
+ return sum_builtin(i);
163
+ });
164
+
165
+ // test async Python callbacks
166
+ using callback_f = std::function<void(int)>;
167
+ m.def("test_async_callback", [](const callback_f &f, const py::list &work) {
168
+ // make detached thread that calls `f` with piece of work after a little delay
169
+ auto start_f = [f](int j) {
170
+ auto invoke_f = [f, j] {
171
+ std::this_thread::sleep_for(std::chrono::milliseconds(50));
172
+ f(j);
173
+ };
174
+ auto t = std::thread(std::move(invoke_f));
175
+ t.detach();
176
+ };
177
+
178
+ // spawn worker threads
179
+ for (auto i : work)
180
+ start_f(py::cast<int>(i));
181
+ });
182
+
183
+ m.def("callback_num_times", [](const py::function &f, std::size_t num) {
184
+ for (std::size_t i = 0; i < num; i++) {
185
+ f();
186
+ }
187
+ });
188
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_callbacks.py ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ import pytest
3
+ from pybind11_tests import callbacks as m
4
+ from threading import Thread
5
+ import time
6
+ import env # NOQA: F401
7
+
8
+
9
+ def test_callbacks():
10
+ from functools import partial
11
+
12
+ def func1():
13
+ return "func1"
14
+
15
+ def func2(a, b, c, d):
16
+ return "func2", a, b, c, d
17
+
18
+ def func3(a):
19
+ return "func3({})".format(a)
20
+
21
+ assert m.test_callback1(func1) == "func1"
22
+ assert m.test_callback2(func2) == ("func2", "Hello", "x", True, 5)
23
+ assert m.test_callback1(partial(func2, 1, 2, 3, 4)) == ("func2", 1, 2, 3, 4)
24
+ assert m.test_callback1(partial(func3, "partial")) == "func3(partial)"
25
+ assert m.test_callback3(lambda i: i + 1) == "func(43) = 44"
26
+
27
+ f = m.test_callback4()
28
+ assert f(43) == 44
29
+ f = m.test_callback5()
30
+ assert f(number=43) == 44
31
+
32
+
33
+ def test_bound_method_callback():
34
+ # Bound Python method:
35
+ class MyClass:
36
+ def double(self, val):
37
+ return 2 * val
38
+
39
+ z = MyClass()
40
+ assert m.test_callback3(z.double) == "func(43) = 86"
41
+
42
+ z = m.CppBoundMethodTest()
43
+ assert m.test_callback3(z.triple) == "func(43) = 129"
44
+
45
+
46
+ def test_keyword_args_and_generalized_unpacking():
47
+ def f(*args, **kwargs):
48
+ return args, kwargs
49
+
50
+ assert m.test_tuple_unpacking(f) == (("positional", 1, 2, 3, 4, 5, 6), {})
51
+ assert m.test_dict_unpacking(f) == (
52
+ ("positional", 1),
53
+ {"key": "value", "a": 1, "b": 2},
54
+ )
55
+ assert m.test_keyword_args(f) == ((), {"x": 10, "y": 20})
56
+ assert m.test_unpacking_and_keywords1(f) == ((1, 2), {"c": 3, "d": 4})
57
+ assert m.test_unpacking_and_keywords2(f) == (
58
+ ("positional", 1, 2, 3, 4, 5),
59
+ {"key": "value", "a": 1, "b": 2, "c": 3, "d": 4, "e": 5},
60
+ )
61
+
62
+ with pytest.raises(TypeError) as excinfo:
63
+ m.test_unpacking_error1(f)
64
+ assert "Got multiple values for keyword argument" in str(excinfo.value)
65
+
66
+ with pytest.raises(TypeError) as excinfo:
67
+ m.test_unpacking_error2(f)
68
+ assert "Got multiple values for keyword argument" in str(excinfo.value)
69
+
70
+ with pytest.raises(RuntimeError) as excinfo:
71
+ m.test_arg_conversion_error1(f)
72
+ assert "Unable to convert call argument" in str(excinfo.value)
73
+
74
+ with pytest.raises(RuntimeError) as excinfo:
75
+ m.test_arg_conversion_error2(f)
76
+ assert "Unable to convert call argument" in str(excinfo.value)
77
+
78
+
79
+ def test_lambda_closure_cleanup():
80
+ m.test_cleanup()
81
+ cstats = m.payload_cstats()
82
+ assert cstats.alive() == 0
83
+ assert cstats.copy_constructions == 1
84
+ assert cstats.move_constructions >= 1
85
+
86
+
87
+ def test_cpp_function_roundtrip():
88
+ """Test if passing a function pointer from C++ -> Python -> C++ yields the original pointer"""
89
+
90
+ assert (
91
+ m.test_dummy_function(m.dummy_function) == "matches dummy_function: eval(1) = 2"
92
+ )
93
+ assert (
94
+ m.test_dummy_function(m.roundtrip(m.dummy_function))
95
+ == "matches dummy_function: eval(1) = 2"
96
+ )
97
+ assert (
98
+ m.test_dummy_function(m.dummy_function_overloaded)
99
+ == "matches dummy_function: eval(1) = 2"
100
+ )
101
+ assert m.roundtrip(None, expect_none=True) is None
102
+ assert (
103
+ m.test_dummy_function(lambda x: x + 2)
104
+ == "can't convert to function pointer: eval(1) = 3"
105
+ )
106
+
107
+ with pytest.raises(TypeError) as excinfo:
108
+ m.test_dummy_function(m.dummy_function2)
109
+ assert "incompatible function arguments" in str(excinfo.value)
110
+
111
+ with pytest.raises(TypeError) as excinfo:
112
+ m.test_dummy_function(lambda x, y: x + y)
113
+ assert any(
114
+ s in str(excinfo.value)
115
+ for s in ("missing 1 required positional argument", "takes exactly 2 arguments")
116
+ )
117
+
118
+
119
+ def test_function_signatures(doc):
120
+ assert doc(m.test_callback3) == "test_callback3(arg0: Callable[[int], int]) -> str"
121
+ assert doc(m.test_callback4) == "test_callback4() -> Callable[[int], int]"
122
+
123
+
124
+ def test_movable_object():
125
+ assert m.callback_with_movable(lambda _: None) is True
126
+
127
+
128
+ @pytest.mark.skipif(
129
+ "env.PYPY",
130
+ reason="PyPy segfaults on here. See discussion on #1413.",
131
+ )
132
+ def test_python_builtins():
133
+ """Test if python builtins like sum() can be used as callbacks"""
134
+ assert m.test_sum_builtin(sum, [1, 2, 3]) == 6
135
+ assert m.test_sum_builtin(sum, []) == 0
136
+
137
+
138
+ def test_async_callbacks():
139
+ # serves as state for async callback
140
+ class Item:
141
+ def __init__(self, value):
142
+ self.value = value
143
+
144
+ res = []
145
+
146
+ # generate stateful lambda that will store result in `res`
147
+ def gen_f():
148
+ s = Item(3)
149
+ return lambda j: res.append(s.value + j)
150
+
151
+ # do some work async
152
+ work = [1, 2, 3, 4]
153
+ m.test_async_callback(gen_f(), work)
154
+ # wait until work is done
155
+ from time import sleep
156
+
157
+ sleep(0.5)
158
+ assert sum(res) == sum(x + 3 for x in work)
159
+
160
+
161
+ def test_async_async_callbacks():
162
+ t = Thread(target=test_async_callbacks)
163
+ t.start()
164
+ t.join()
165
+
166
+
167
+ def test_callback_num_times():
168
+ # Super-simple micro-benchmarking related to PR #2919.
169
+ # Example runtimes (Intel Xeon 2.2GHz, fully optimized):
170
+ # num_millions 1, repeats 2: 0.1 secs
171
+ # num_millions 20, repeats 10: 11.5 secs
172
+ one_million = 1000000
173
+ num_millions = 1 # Try 20 for actual micro-benchmarking.
174
+ repeats = 2 # Try 10.
175
+ rates = []
176
+ for rep in range(repeats):
177
+ t0 = time.time()
178
+ m.callback_num_times(lambda: None, num_millions * one_million)
179
+ td = time.time() - t0
180
+ rate = num_millions / td if td else 0
181
+ rates.append(rate)
182
+ if not rep:
183
+ print()
184
+ print(
185
+ "callback_num_times: {:d} million / {:.3f} seconds = {:.3f} million / second".format(
186
+ num_millions, td, rate
187
+ )
188
+ )
189
+ if len(rates) > 1:
190
+ print("Min Mean Max")
191
+ print(
192
+ "{:6.3f} {:6.3f} {:6.3f}".format(
193
+ min(rates), sum(rates) / len(rates), max(rates)
194
+ )
195
+ )
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_chrono.cpp ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ tests/test_chrono.cpp -- test conversions to/from std::chrono types
3
+
4
+ Copyright (c) 2016 Trent Houliston <[email protected]> and
5
+ Wenzel Jakob <[email protected]>
6
+
7
+ All rights reserved. Use of this source code is governed by a
8
+ BSD-style license that can be found in the LICENSE file.
9
+ */
10
+
11
+ #include "pybind11_tests.h"
12
+ #include <pybind11/chrono.h>
13
+ #include <chrono>
14
+
15
+ struct different_resolutions {
16
+ using time_point_h = std::chrono::time_point<
17
+ std::chrono::system_clock, std::chrono::hours>;
18
+ using time_point_m = std::chrono::time_point<
19
+ std::chrono::system_clock, std::chrono::minutes>;
20
+ using time_point_s = std::chrono::time_point<
21
+ std::chrono::system_clock, std::chrono::seconds>;
22
+ using time_point_ms = std::chrono::time_point<
23
+ std::chrono::system_clock, std::chrono::milliseconds>;
24
+ using time_point_us = std::chrono::time_point<
25
+ std::chrono::system_clock, std::chrono::microseconds>;
26
+ time_point_h timestamp_h;
27
+ time_point_m timestamp_m;
28
+ time_point_s timestamp_s;
29
+ time_point_ms timestamp_ms;
30
+ time_point_us timestamp_us;
31
+ };
32
+
33
+ TEST_SUBMODULE(chrono, m) {
34
+ using system_time = std::chrono::system_clock::time_point;
35
+ using steady_time = std::chrono::steady_clock::time_point;
36
+
37
+ using timespan = std::chrono::duration<int64_t, std::nano>;
38
+ using timestamp = std::chrono::time_point<std::chrono::system_clock, timespan>;
39
+
40
+ // test_chrono_system_clock
41
+ // Return the current time off the wall clock
42
+ m.def("test_chrono1", []() { return std::chrono::system_clock::now(); });
43
+
44
+ // test_chrono_system_clock_roundtrip
45
+ // Round trip the passed in system clock time
46
+ m.def("test_chrono2", [](system_time t) { return t; });
47
+
48
+ // test_chrono_duration_roundtrip
49
+ // Round trip the passed in duration
50
+ m.def("test_chrono3", [](std::chrono::system_clock::duration d) { return d; });
51
+
52
+ // test_chrono_duration_subtraction_equivalence
53
+ // Difference between two passed in time_points
54
+ m.def("test_chrono4", [](system_time a, system_time b) { return a - b; });
55
+
56
+ // test_chrono_steady_clock
57
+ // Return the current time off the steady_clock
58
+ m.def("test_chrono5", []() { return std::chrono::steady_clock::now(); });
59
+
60
+ // test_chrono_steady_clock_roundtrip
61
+ // Round trip a steady clock timepoint
62
+ m.def("test_chrono6", [](steady_time t) { return t; });
63
+
64
+ // test_floating_point_duration
65
+ // Roundtrip a duration in microseconds from a float argument
66
+ m.def("test_chrono7", [](std::chrono::microseconds t) { return t; });
67
+ // Float durations (issue #719)
68
+ m.def("test_chrono_float_diff", [](std::chrono::duration<float> a, std::chrono::duration<float> b) {
69
+ return a - b; });
70
+
71
+ m.def("test_nano_timepoint", [](timestamp start, timespan delta) -> timestamp {
72
+ return start + delta;
73
+ });
74
+
75
+ // Test different resolutions
76
+ py::class_<different_resolutions>(m, "different_resolutions")
77
+ .def(py::init<>())
78
+ .def_readwrite("timestamp_h", &different_resolutions::timestamp_h)
79
+ .def_readwrite("timestamp_m", &different_resolutions::timestamp_m)
80
+ .def_readwrite("timestamp_s", &different_resolutions::timestamp_s)
81
+ .def_readwrite("timestamp_ms", &different_resolutions::timestamp_ms)
82
+ .def_readwrite("timestamp_us", &different_resolutions::timestamp_us)
83
+ ;
84
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_chrono.py ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ from pybind11_tests import chrono as m
3
+ import datetime
4
+ import pytest
5
+
6
+ import env # noqa: F401
7
+
8
+
9
+ def test_chrono_system_clock():
10
+
11
+ # Get the time from both c++ and datetime
12
+ date0 = datetime.datetime.today()
13
+ date1 = m.test_chrono1()
14
+ date2 = datetime.datetime.today()
15
+
16
+ # The returned value should be a datetime
17
+ assert isinstance(date1, datetime.datetime)
18
+
19
+ # The numbers should vary by a very small amount (time it took to execute)
20
+ diff_python = abs(date2 - date0)
21
+ diff = abs(date1 - date2)
22
+
23
+ # There should never be a days difference
24
+ assert diff.days == 0
25
+
26
+ # Since datetime.datetime.today() calls time.time(), and on some platforms
27
+ # that has 1 second accuracy, we compare this way
28
+ assert diff.seconds <= diff_python.seconds
29
+
30
+
31
+ def test_chrono_system_clock_roundtrip():
32
+ date1 = datetime.datetime.today()
33
+
34
+ # Roundtrip the time
35
+ date2 = m.test_chrono2(date1)
36
+
37
+ # The returned value should be a datetime
38
+ assert isinstance(date2, datetime.datetime)
39
+
40
+ # They should be identical (no information lost on roundtrip)
41
+ diff = abs(date1 - date2)
42
+ assert diff == datetime.timedelta(0)
43
+
44
+
45
+ def test_chrono_system_clock_roundtrip_date():
46
+ date1 = datetime.date.today()
47
+
48
+ # Roundtrip the time
49
+ datetime2 = m.test_chrono2(date1)
50
+ date2 = datetime2.date()
51
+ time2 = datetime2.time()
52
+
53
+ # The returned value should be a datetime
54
+ assert isinstance(datetime2, datetime.datetime)
55
+ assert isinstance(date2, datetime.date)
56
+ assert isinstance(time2, datetime.time)
57
+
58
+ # They should be identical (no information lost on roundtrip)
59
+ diff = abs(date1 - date2)
60
+ assert diff.days == 0
61
+ assert diff.seconds == 0
62
+ assert diff.microseconds == 0
63
+
64
+ # Year, Month & Day should be the same after the round trip
65
+ assert date1 == date2
66
+
67
+ # There should be no time information
68
+ assert time2.hour == 0
69
+ assert time2.minute == 0
70
+ assert time2.second == 0
71
+ assert time2.microsecond == 0
72
+
73
+
74
+ SKIP_TZ_ENV_ON_WIN = pytest.mark.skipif(
75
+ "env.WIN", reason="TZ environment variable only supported on POSIX"
76
+ )
77
+
78
+
79
+ @pytest.mark.parametrize(
80
+ "time1",
81
+ [
82
+ datetime.datetime.today().time(),
83
+ datetime.time(0, 0, 0),
84
+ datetime.time(0, 0, 0, 1),
85
+ datetime.time(0, 28, 45, 109827),
86
+ datetime.time(0, 59, 59, 999999),
87
+ datetime.time(1, 0, 0),
88
+ datetime.time(5, 59, 59, 0),
89
+ datetime.time(5, 59, 59, 1),
90
+ ],
91
+ )
92
+ @pytest.mark.parametrize(
93
+ "tz",
94
+ [
95
+ None,
96
+ pytest.param("Europe/Brussels", marks=SKIP_TZ_ENV_ON_WIN),
97
+ pytest.param("Asia/Pyongyang", marks=SKIP_TZ_ENV_ON_WIN),
98
+ pytest.param("America/New_York", marks=SKIP_TZ_ENV_ON_WIN),
99
+ ],
100
+ )
101
+ def test_chrono_system_clock_roundtrip_time(time1, tz, monkeypatch):
102
+ if tz is not None:
103
+ monkeypatch.setenv("TZ", "/usr/share/zoneinfo/{}".format(tz))
104
+
105
+ # Roundtrip the time
106
+ datetime2 = m.test_chrono2(time1)
107
+ date2 = datetime2.date()
108
+ time2 = datetime2.time()
109
+
110
+ # The returned value should be a datetime
111
+ assert isinstance(datetime2, datetime.datetime)
112
+ assert isinstance(date2, datetime.date)
113
+ assert isinstance(time2, datetime.time)
114
+
115
+ # Hour, Minute, Second & Microsecond should be the same after the round trip
116
+ assert time1 == time2
117
+
118
+ # There should be no date information (i.e. date = python base date)
119
+ assert date2.year == 1970
120
+ assert date2.month == 1
121
+ assert date2.day == 1
122
+
123
+
124
+ def test_chrono_duration_roundtrip():
125
+
126
+ # Get the difference between two times (a timedelta)
127
+ date1 = datetime.datetime.today()
128
+ date2 = datetime.datetime.today()
129
+ diff = date2 - date1
130
+
131
+ # Make sure this is a timedelta
132
+ assert isinstance(diff, datetime.timedelta)
133
+
134
+ cpp_diff = m.test_chrono3(diff)
135
+
136
+ assert cpp_diff == diff
137
+
138
+ # Negative timedelta roundtrip
139
+ diff = datetime.timedelta(microseconds=-1)
140
+ cpp_diff = m.test_chrono3(diff)
141
+
142
+ assert cpp_diff == diff
143
+
144
+
145
+ def test_chrono_duration_subtraction_equivalence():
146
+
147
+ date1 = datetime.datetime.today()
148
+ date2 = datetime.datetime.today()
149
+
150
+ diff = date2 - date1
151
+ cpp_diff = m.test_chrono4(date2, date1)
152
+
153
+ assert cpp_diff == diff
154
+
155
+
156
+ def test_chrono_duration_subtraction_equivalence_date():
157
+
158
+ date1 = datetime.date.today()
159
+ date2 = datetime.date.today()
160
+
161
+ diff = date2 - date1
162
+ cpp_diff = m.test_chrono4(date2, date1)
163
+
164
+ assert cpp_diff == diff
165
+
166
+
167
+ def test_chrono_steady_clock():
168
+ time1 = m.test_chrono5()
169
+ assert isinstance(time1, datetime.timedelta)
170
+
171
+
172
+ def test_chrono_steady_clock_roundtrip():
173
+ time1 = datetime.timedelta(days=10, seconds=10, microseconds=100)
174
+ time2 = m.test_chrono6(time1)
175
+
176
+ assert isinstance(time2, datetime.timedelta)
177
+
178
+ # They should be identical (no information lost on roundtrip)
179
+ assert time1 == time2
180
+
181
+
182
+ def test_floating_point_duration():
183
+ # Test using a floating point number in seconds
184
+ time = m.test_chrono7(35.525123)
185
+
186
+ assert isinstance(time, datetime.timedelta)
187
+
188
+ assert time.seconds == 35
189
+ assert 525122 <= time.microseconds <= 525123
190
+
191
+ diff = m.test_chrono_float_diff(43.789012, 1.123456)
192
+ assert diff.seconds == 42
193
+ assert 665556 <= diff.microseconds <= 665557
194
+
195
+
196
+ def test_nano_timepoint():
197
+ time = datetime.datetime.now()
198
+ time1 = m.test_nano_timepoint(time, datetime.timedelta(seconds=60))
199
+ assert time1 == time + datetime.timedelta(seconds=60)
200
+
201
+
202
+ def test_chrono_different_resolutions():
203
+ resolutions = m.different_resolutions()
204
+ time = datetime.datetime.now()
205
+ resolutions.timestamp_h = time
206
+ resolutions.timestamp_m = time
207
+ resolutions.timestamp_s = time
208
+ resolutions.timestamp_ms = time
209
+ resolutions.timestamp_us = time
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_class.cpp ADDED
@@ -0,0 +1,534 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ tests/test_class.cpp -- test py::class_ definitions and basic functionality
3
+
4
+ Copyright (c) 2016 Wenzel Jakob <[email protected]>
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
+ #if defined(__INTEL_COMPILER) && __cplusplus >= 201703L
11
+ // Intel compiler requires a separate header file to support aligned new operators
12
+ // and does not set the __cpp_aligned_new feature macro.
13
+ // This header needs to be included before pybind11.
14
+ #include <aligned_new>
15
+ #endif
16
+
17
+ #include "pybind11_tests.h"
18
+ #include "constructor_stats.h"
19
+ #include "local_bindings.h"
20
+ #include <pybind11/stl.h>
21
+
22
+ #include <utility>
23
+
24
+ #if defined(_MSC_VER)
25
+ # pragma warning(disable: 4324) // warning C4324: structure was padded due to alignment specifier
26
+ #endif
27
+
28
+ // test_brace_initialization
29
+ struct NoBraceInitialization {
30
+ NoBraceInitialization(std::vector<int> v) : vec{std::move(v)} {}
31
+ template <typename T>
32
+ NoBraceInitialization(std::initializer_list<T> l) : vec(l) {}
33
+
34
+ std::vector<int> vec;
35
+ };
36
+
37
+ TEST_SUBMODULE(class_, m) {
38
+ // test_instance
39
+ struct NoConstructor {
40
+ NoConstructor() = default;
41
+ NoConstructor(const NoConstructor &) = default;
42
+ NoConstructor(NoConstructor &&) = default;
43
+ static NoConstructor *new_instance() {
44
+ auto *ptr = new NoConstructor();
45
+ print_created(ptr, "via new_instance");
46
+ return ptr;
47
+ }
48
+ ~NoConstructor() { print_destroyed(this); }
49
+ };
50
+
51
+ py::class_<NoConstructor>(m, "NoConstructor")
52
+ .def_static("new_instance", &NoConstructor::new_instance, "Return an instance");
53
+
54
+ // test_inheritance
55
+ class Pet {
56
+ public:
57
+ Pet(const std::string &name, const std::string &species)
58
+ : m_name(name), m_species(species) {}
59
+ std::string name() const { return m_name; }
60
+ std::string species() const { return m_species; }
61
+ private:
62
+ std::string m_name;
63
+ std::string m_species;
64
+ };
65
+
66
+ class Dog : public Pet {
67
+ public:
68
+ Dog(const std::string &name) : Pet(name, "dog") {}
69
+ std::string bark() const { return "Woof!"; }
70
+ };
71
+
72
+ class Rabbit : public Pet {
73
+ public:
74
+ Rabbit(const std::string &name) : Pet(name, "parrot") {}
75
+ };
76
+
77
+ class Hamster : public Pet {
78
+ public:
79
+ Hamster(const std::string &name) : Pet(name, "rodent") {}
80
+ };
81
+
82
+ class Chimera : public Pet {
83
+ Chimera() : Pet("Kimmy", "chimera") {}
84
+ };
85
+
86
+ py::class_<Pet> pet_class(m, "Pet");
87
+ pet_class
88
+ .def(py::init<std::string, std::string>())
89
+ .def("name", &Pet::name)
90
+ .def("species", &Pet::species);
91
+
92
+ /* One way of declaring a subclass relationship: reference parent's class_ object */
93
+ py::class_<Dog>(m, "Dog", pet_class)
94
+ .def(py::init<std::string>());
95
+
96
+ /* Another way of declaring a subclass relationship: reference parent's C++ type */
97
+ py::class_<Rabbit, Pet>(m, "Rabbit")
98
+ .def(py::init<std::string>());
99
+
100
+ /* And another: list parent in class template arguments */
101
+ py::class_<Hamster, Pet>(m, "Hamster")
102
+ .def(py::init<std::string>());
103
+
104
+ /* Constructors are not inherited by default */
105
+ py::class_<Chimera, Pet>(m, "Chimera");
106
+
107
+ m.def("pet_name_species", [](const Pet &pet) { return pet.name() + " is a " + pet.species(); });
108
+ m.def("dog_bark", [](const Dog &dog) { return dog.bark(); });
109
+
110
+ // test_automatic_upcasting
111
+ struct BaseClass {
112
+ BaseClass() = default;
113
+ BaseClass(const BaseClass &) = default;
114
+ BaseClass(BaseClass &&) = default;
115
+ virtual ~BaseClass() = default;
116
+ };
117
+ struct DerivedClass1 : BaseClass { };
118
+ struct DerivedClass2 : BaseClass { };
119
+
120
+ py::class_<BaseClass>(m, "BaseClass").def(py::init<>());
121
+ py::class_<DerivedClass1>(m, "DerivedClass1").def(py::init<>());
122
+ py::class_<DerivedClass2>(m, "DerivedClass2").def(py::init<>());
123
+
124
+ m.def("return_class_1", []() -> BaseClass* { return new DerivedClass1(); });
125
+ m.def("return_class_2", []() -> BaseClass* { return new DerivedClass2(); });
126
+ m.def("return_class_n", [](int n) -> BaseClass* {
127
+ if (n == 1) return new DerivedClass1();
128
+ if (n == 2) return new DerivedClass2();
129
+ return new BaseClass();
130
+ });
131
+ m.def("return_none", []() -> BaseClass* { return nullptr; });
132
+
133
+ // test_isinstance
134
+ m.def("check_instances", [](const py::list &l) {
135
+ return py::make_tuple(
136
+ py::isinstance<py::tuple>(l[0]),
137
+ py::isinstance<py::dict>(l[1]),
138
+ py::isinstance<Pet>(l[2]),
139
+ py::isinstance<Pet>(l[3]),
140
+ py::isinstance<Dog>(l[4]),
141
+ py::isinstance<Rabbit>(l[5]),
142
+ py::isinstance<UnregisteredType>(l[6])
143
+ );
144
+ });
145
+
146
+ struct Invalid {};
147
+
148
+ // test_type
149
+ m.def("check_type", [](int category) {
150
+ // Currently not supported (via a fail at compile time)
151
+ // See https://github.com/pybind/pybind11/issues/2486
152
+ // if (category == 2)
153
+ // return py::type::of<int>();
154
+ if (category == 1)
155
+ return py::type::of<DerivedClass1>();
156
+ return py::type::of<Invalid>();
157
+ });
158
+
159
+ m.def("get_type_of", [](py::object ob) { return py::type::of(std::move(ob)); });
160
+
161
+ m.def("get_type_classic", [](py::handle h) {
162
+ return h.get_type();
163
+ });
164
+
165
+ m.def("as_type", [](const py::object &ob) { return py::type(ob); });
166
+
167
+ // test_mismatched_holder
168
+ struct MismatchBase1 { };
169
+ struct MismatchDerived1 : MismatchBase1 { };
170
+
171
+ struct MismatchBase2 { };
172
+ struct MismatchDerived2 : MismatchBase2 { };
173
+
174
+ m.def("mismatched_holder_1", []() {
175
+ auto mod = py::module_::import("__main__");
176
+ py::class_<MismatchBase1, std::shared_ptr<MismatchBase1>>(mod, "MismatchBase1");
177
+ py::class_<MismatchDerived1, MismatchBase1>(mod, "MismatchDerived1");
178
+ });
179
+ m.def("mismatched_holder_2", []() {
180
+ auto mod = py::module_::import("__main__");
181
+ py::class_<MismatchBase2>(mod, "MismatchBase2");
182
+ py::class_<MismatchDerived2, std::shared_ptr<MismatchDerived2>,
183
+ MismatchBase2>(mod, "MismatchDerived2");
184
+ });
185
+
186
+ // test_override_static
187
+ // #511: problem with inheritance + overwritten def_static
188
+ struct MyBase {
189
+ static std::unique_ptr<MyBase> make() {
190
+ return std::unique_ptr<MyBase>(new MyBase());
191
+ }
192
+ };
193
+
194
+ struct MyDerived : MyBase {
195
+ static std::unique_ptr<MyDerived> make() {
196
+ return std::unique_ptr<MyDerived>(new MyDerived());
197
+ }
198
+ };
199
+
200
+ py::class_<MyBase>(m, "MyBase")
201
+ .def_static("make", &MyBase::make);
202
+
203
+ py::class_<MyDerived, MyBase>(m, "MyDerived")
204
+ .def_static("make", &MyDerived::make)
205
+ .def_static("make2", &MyDerived::make);
206
+
207
+ // test_implicit_conversion_life_support
208
+ struct ConvertibleFromUserType {
209
+ int i;
210
+
211
+ ConvertibleFromUserType(UserType u) : i(u.value()) { }
212
+ };
213
+
214
+ py::class_<ConvertibleFromUserType>(m, "AcceptsUserType")
215
+ .def(py::init<UserType>());
216
+ py::implicitly_convertible<UserType, ConvertibleFromUserType>();
217
+
218
+ m.def("implicitly_convert_argument", [](const ConvertibleFromUserType &r) { return r.i; });
219
+ m.def("implicitly_convert_variable", [](const py::object &o) {
220
+ // `o` is `UserType` and `r` is a reference to a temporary created by implicit
221
+ // conversion. This is valid when called inside a bound function because the temp
222
+ // object is attached to the same life support system as the arguments.
223
+ const auto &r = o.cast<const ConvertibleFromUserType &>();
224
+ return r.i;
225
+ });
226
+ m.add_object("implicitly_convert_variable_fail", [&] {
227
+ auto f = [](PyObject *, PyObject *args) -> PyObject * {
228
+ auto o = py::reinterpret_borrow<py::tuple>(args)[0];
229
+ try { // It should fail here because there is no life support.
230
+ o.cast<const ConvertibleFromUserType &>();
231
+ } catch (const py::cast_error &e) {
232
+ return py::str(e.what()).release().ptr();
233
+ }
234
+ return py::str().release().ptr();
235
+ };
236
+
237
+ auto def = new PyMethodDef{"f", f, METH_VARARGS, nullptr};
238
+ py::capsule def_capsule(def, [](void *ptr) { delete reinterpret_cast<PyMethodDef *>(ptr); });
239
+ return py::reinterpret_steal<py::object>(PyCFunction_NewEx(def, def_capsule.ptr(), m.ptr()));
240
+ }());
241
+
242
+ // test_operator_new_delete
243
+ struct HasOpNewDel {
244
+ std::uint64_t i;
245
+ static void *operator new(size_t s) { py::print("A new", s); return ::operator new(s); }
246
+ static void *operator new(size_t s, void *ptr) { py::print("A placement-new", s); return ptr; }
247
+ static void operator delete(void *p) { py::print("A delete"); return ::operator delete(p); }
248
+ };
249
+ struct HasOpNewDelSize {
250
+ std::uint32_t i;
251
+ static void *operator new(size_t s) { py::print("B new", s); return ::operator new(s); }
252
+ static void *operator new(size_t s, void *ptr) { py::print("B placement-new", s); return ptr; }
253
+ static void operator delete(void *p, size_t s) { py::print("B delete", s); return ::operator delete(p); }
254
+ };
255
+ struct AliasedHasOpNewDelSize {
256
+ std::uint64_t i;
257
+ static void *operator new(size_t s) { py::print("C new", s); return ::operator new(s); }
258
+ static void *operator new(size_t s, void *ptr) { py::print("C placement-new", s); return ptr; }
259
+ static void operator delete(void *p, size_t s) { py::print("C delete", s); return ::operator delete(p); }
260
+ virtual ~AliasedHasOpNewDelSize() = default;
261
+ AliasedHasOpNewDelSize() = default;
262
+ AliasedHasOpNewDelSize(const AliasedHasOpNewDelSize&) = delete;
263
+ };
264
+ struct PyAliasedHasOpNewDelSize : AliasedHasOpNewDelSize {
265
+ PyAliasedHasOpNewDelSize() = default;
266
+ PyAliasedHasOpNewDelSize(int) { }
267
+ std::uint64_t j;
268
+ };
269
+ struct HasOpNewDelBoth {
270
+ std::uint32_t i[8];
271
+ static void *operator new(size_t s) { py::print("D new", s); return ::operator new(s); }
272
+ static void *operator new(size_t s, void *ptr) { py::print("D placement-new", s); return ptr; }
273
+ static void operator delete(void *p) { py::print("D delete"); return ::operator delete(p); }
274
+ static void operator delete(void *p, size_t s) { py::print("D wrong delete", s); return ::operator delete(p); }
275
+ };
276
+ py::class_<HasOpNewDel>(m, "HasOpNewDel").def(py::init<>());
277
+ py::class_<HasOpNewDelSize>(m, "HasOpNewDelSize").def(py::init<>());
278
+ py::class_<HasOpNewDelBoth>(m, "HasOpNewDelBoth").def(py::init<>());
279
+ py::class_<AliasedHasOpNewDelSize, PyAliasedHasOpNewDelSize> aliased(m, "AliasedHasOpNewDelSize");
280
+ aliased.def(py::init<>());
281
+ aliased.attr("size_noalias") = py::int_(sizeof(AliasedHasOpNewDelSize));
282
+ aliased.attr("size_alias") = py::int_(sizeof(PyAliasedHasOpNewDelSize));
283
+
284
+ // This test is actually part of test_local_bindings (test_duplicate_local), but we need a
285
+ // definition in a different compilation unit within the same module:
286
+ bind_local<LocalExternal, 17>(m, "LocalExternal", py::module_local());
287
+
288
+ // test_bind_protected_functions
289
+ class ProtectedA {
290
+ protected:
291
+ int foo() const { return value; }
292
+
293
+ private:
294
+ int value = 42;
295
+ };
296
+
297
+ class PublicistA : public ProtectedA {
298
+ public:
299
+ using ProtectedA::foo;
300
+ };
301
+
302
+ py::class_<ProtectedA>(m, "ProtectedA")
303
+ .def(py::init<>())
304
+ #if !defined(_MSC_VER) || _MSC_VER >= 1910
305
+ .def("foo", &PublicistA::foo);
306
+ #else
307
+ .def("foo", static_cast<int (ProtectedA::*)() const>(&PublicistA::foo));
308
+ #endif
309
+
310
+ class ProtectedB {
311
+ public:
312
+ virtual ~ProtectedB() = default;
313
+ ProtectedB() = default;
314
+ ProtectedB(const ProtectedB &) = delete;
315
+
316
+ protected:
317
+ virtual int foo() const { return value; }
318
+
319
+ private:
320
+ int value = 42;
321
+ };
322
+
323
+ class TrampolineB : public ProtectedB {
324
+ public:
325
+ int foo() const override { PYBIND11_OVERRIDE(int, ProtectedB, foo, ); }
326
+ };
327
+
328
+ class PublicistB : public ProtectedB {
329
+ public:
330
+ // [workaround(intel)] = default does not work here
331
+ // Removing or defaulting this destructor results in linking errors with the Intel compiler
332
+ // (in Debug builds only, tested with icpc (ICC) 2021.1 Beta 20200827)
333
+ ~PublicistB() override {}; // NOLINT(modernize-use-equals-default)
334
+ using ProtectedB::foo;
335
+ };
336
+
337
+ py::class_<ProtectedB, TrampolineB>(m, "ProtectedB")
338
+ .def(py::init<>())
339
+ #if !defined(_MSC_VER) || _MSC_VER >= 1910
340
+ .def("foo", &PublicistB::foo);
341
+ #else
342
+ .def("foo", static_cast<int (ProtectedB::*)() const>(&PublicistB::foo));
343
+ #endif
344
+
345
+ // test_brace_initialization
346
+ struct BraceInitialization {
347
+ int field1;
348
+ std::string field2;
349
+ };
350
+
351
+ py::class_<BraceInitialization>(m, "BraceInitialization")
352
+ .def(py::init<int, const std::string &>())
353
+ .def_readwrite("field1", &BraceInitialization::field1)
354
+ .def_readwrite("field2", &BraceInitialization::field2);
355
+ // We *don't* want to construct using braces when the given constructor argument maps to a
356
+ // constructor, because brace initialization could go to the wrong place (in particular when
357
+ // there is also an `initializer_list<T>`-accept constructor):
358
+ py::class_<NoBraceInitialization>(m, "NoBraceInitialization")
359
+ .def(py::init<std::vector<int>>())
360
+ .def_readonly("vec", &NoBraceInitialization::vec);
361
+
362
+ // test_reentrant_implicit_conversion_failure
363
+ // #1035: issue with runaway reentrant implicit conversion
364
+ struct BogusImplicitConversion {
365
+ BogusImplicitConversion(const BogusImplicitConversion &) = default;
366
+ };
367
+
368
+ py::class_<BogusImplicitConversion>(m, "BogusImplicitConversion")
369
+ .def(py::init<const BogusImplicitConversion &>());
370
+
371
+ py::implicitly_convertible<int, BogusImplicitConversion>();
372
+
373
+ // test_qualname
374
+ // #1166: nested class docstring doesn't show nested name
375
+ // Also related: tests that __qualname__ is set properly
376
+ struct NestBase {};
377
+ struct Nested {};
378
+ py::class_<NestBase> base(m, "NestBase");
379
+ base.def(py::init<>());
380
+ py::class_<Nested>(base, "Nested")
381
+ .def(py::init<>())
382
+ .def("fn", [](Nested &, int, NestBase &, Nested &) {})
383
+ .def("fa", [](Nested &, int, NestBase &, Nested &) {},
384
+ "a"_a, "b"_a, "c"_a);
385
+ base.def("g", [](NestBase &, Nested &) {});
386
+ base.def("h", []() { return NestBase(); });
387
+
388
+ // test_error_after_conversion
389
+ // The second-pass path through dispatcher() previously didn't
390
+ // remember which overload was used, and would crash trying to
391
+ // generate a useful error message
392
+
393
+ struct NotRegistered {};
394
+ struct StringWrapper { std::string str; };
395
+ m.def("test_error_after_conversions", [](int) {});
396
+ m.def("test_error_after_conversions",
397
+ [](const StringWrapper &) -> NotRegistered { return {}; });
398
+ py::class_<StringWrapper>(m, "StringWrapper").def(py::init<std::string>());
399
+ py::implicitly_convertible<std::string, StringWrapper>();
400
+
401
+ #if defined(PYBIND11_CPP17)
402
+ struct alignas(1024) Aligned {
403
+ std::uintptr_t ptr() const { return (uintptr_t) this; }
404
+ };
405
+ py::class_<Aligned>(m, "Aligned")
406
+ .def(py::init<>())
407
+ .def("ptr", &Aligned::ptr);
408
+ #endif
409
+
410
+ // test_final
411
+ struct IsFinal final {};
412
+ py::class_<IsFinal>(m, "IsFinal", py::is_final());
413
+
414
+ // test_non_final_final
415
+ struct IsNonFinalFinal {};
416
+ py::class_<IsNonFinalFinal>(m, "IsNonFinalFinal", py::is_final());
417
+
418
+ // test_exception_rvalue_abort
419
+ struct PyPrintDestructor {
420
+ PyPrintDestructor() = default;
421
+ ~PyPrintDestructor() {
422
+ py::print("Print from destructor");
423
+ }
424
+ void throw_something() { throw std::runtime_error("error"); }
425
+ };
426
+ py::class_<PyPrintDestructor>(m, "PyPrintDestructor")
427
+ .def(py::init<>())
428
+ .def("throw_something", &PyPrintDestructor::throw_something);
429
+
430
+ // test_multiple_instances_with_same_pointer
431
+ struct SamePointer {};
432
+ static SamePointer samePointer;
433
+ py::class_<SamePointer, std::unique_ptr<SamePointer, py::nodelete>>(m, "SamePointer")
434
+ .def(py::init([]() { return &samePointer; }));
435
+
436
+ struct Empty {};
437
+ py::class_<Empty>(m, "Empty")
438
+ .def(py::init<>());
439
+
440
+ // test_base_and_derived_nested_scope
441
+ struct BaseWithNested {
442
+ struct Nested {};
443
+ };
444
+
445
+ struct DerivedWithNested : BaseWithNested {
446
+ struct Nested {};
447
+ };
448
+
449
+ py::class_<BaseWithNested> baseWithNested_class(m, "BaseWithNested");
450
+ py::class_<DerivedWithNested, BaseWithNested> derivedWithNested_class(m, "DerivedWithNested");
451
+ py::class_<BaseWithNested::Nested>(baseWithNested_class, "Nested")
452
+ .def_static("get_name", []() { return "BaseWithNested::Nested"; });
453
+ py::class_<DerivedWithNested::Nested>(derivedWithNested_class, "Nested")
454
+ .def_static("get_name", []() { return "DerivedWithNested::Nested"; });
455
+
456
+ // test_register_duplicate_class
457
+ struct Duplicate {};
458
+ struct OtherDuplicate {};
459
+ struct DuplicateNested {};
460
+ struct OtherDuplicateNested {};
461
+
462
+ m.def("register_duplicate_class_name", [](const py::module_ &m) {
463
+ py::class_<Duplicate>(m, "Duplicate");
464
+ py::class_<OtherDuplicate>(m, "Duplicate");
465
+ });
466
+ m.def("register_duplicate_class_type", [](const py::module_ &m) {
467
+ py::class_<OtherDuplicate>(m, "OtherDuplicate");
468
+ py::class_<OtherDuplicate>(m, "YetAnotherDuplicate");
469
+ });
470
+ m.def("register_duplicate_nested_class_name", [](const py::object &gt) {
471
+ py::class_<DuplicateNested>(gt, "DuplicateNested");
472
+ py::class_<OtherDuplicateNested>(gt, "DuplicateNested");
473
+ });
474
+ m.def("register_duplicate_nested_class_type", [](const py::object &gt) {
475
+ py::class_<OtherDuplicateNested>(gt, "OtherDuplicateNested");
476
+ py::class_<OtherDuplicateNested>(gt, "YetAnotherDuplicateNested");
477
+ });
478
+ }
479
+
480
+ template <int N> class BreaksBase { public:
481
+ virtual ~BreaksBase() = default;
482
+ BreaksBase() = default;
483
+ BreaksBase(const BreaksBase&) = delete;
484
+ };
485
+ template <int N> class BreaksTramp : public BreaksBase<N> {};
486
+ // These should all compile just fine:
487
+ using DoesntBreak1 = py::class_<BreaksBase<1>, std::unique_ptr<BreaksBase<1>>, BreaksTramp<1>>;
488
+ using DoesntBreak2 = py::class_<BreaksBase<2>, BreaksTramp<2>, std::unique_ptr<BreaksBase<2>>>;
489
+ using DoesntBreak3 = py::class_<BreaksBase<3>, std::unique_ptr<BreaksBase<3>>>;
490
+ using DoesntBreak4 = py::class_<BreaksBase<4>, BreaksTramp<4>>;
491
+ using DoesntBreak5 = py::class_<BreaksBase<5>>;
492
+ using DoesntBreak6 = py::class_<BreaksBase<6>, std::shared_ptr<BreaksBase<6>>, BreaksTramp<6>>;
493
+ using DoesntBreak7 = py::class_<BreaksBase<7>, BreaksTramp<7>, std::shared_ptr<BreaksBase<7>>>;
494
+ using DoesntBreak8 = py::class_<BreaksBase<8>, std::shared_ptr<BreaksBase<8>>>;
495
+ #define CHECK_BASE(N) static_assert(std::is_same<typename DoesntBreak##N::type, BreaksBase<N>>::value, \
496
+ "DoesntBreak" #N " has wrong type!")
497
+ CHECK_BASE(1); CHECK_BASE(2); CHECK_BASE(3); CHECK_BASE(4); CHECK_BASE(5); CHECK_BASE(6); CHECK_BASE(7); CHECK_BASE(8);
498
+ #define CHECK_ALIAS(N) static_assert(DoesntBreak##N::has_alias && std::is_same<typename DoesntBreak##N::type_alias, BreaksTramp<N>>::value, \
499
+ "DoesntBreak" #N " has wrong type_alias!")
500
+ #define CHECK_NOALIAS(N) static_assert(!DoesntBreak##N::has_alias && std::is_void<typename DoesntBreak##N::type_alias>::value, \
501
+ "DoesntBreak" #N " has type alias, but shouldn't!")
502
+ CHECK_ALIAS(1); CHECK_ALIAS(2); CHECK_NOALIAS(3); CHECK_ALIAS(4); CHECK_NOALIAS(5); CHECK_ALIAS(6); CHECK_ALIAS(7); CHECK_NOALIAS(8);
503
+ #define CHECK_HOLDER(N, TYPE) static_assert(std::is_same<typename DoesntBreak##N::holder_type, std::TYPE##_ptr<BreaksBase<N>>>::value, \
504
+ "DoesntBreak" #N " has wrong holder_type!")
505
+ CHECK_HOLDER(1, unique); CHECK_HOLDER(2, unique); CHECK_HOLDER(3, unique); CHECK_HOLDER(4, unique); CHECK_HOLDER(5, unique);
506
+ CHECK_HOLDER(6, shared); CHECK_HOLDER(7, shared); CHECK_HOLDER(8, shared);
507
+
508
+ // There's no nice way to test that these fail because they fail to compile; leave them here,
509
+ // though, so that they can be manually tested by uncommenting them (and seeing that compilation
510
+ // failures occurs).
511
+
512
+ // We have to actually look into the type: the typedef alone isn't enough to instantiate the type:
513
+ #define CHECK_BROKEN(N) static_assert(std::is_same<typename Breaks##N::type, BreaksBase<-N>>::value, \
514
+ "Breaks1 has wrong type!");
515
+
516
+ //// Two holder classes:
517
+ //typedef py::class_<BreaksBase<-1>, std::unique_ptr<BreaksBase<-1>>, std::unique_ptr<BreaksBase<-1>>> Breaks1;
518
+ //CHECK_BROKEN(1);
519
+ //// Two aliases:
520
+ //typedef py::class_<BreaksBase<-2>, BreaksTramp<-2>, BreaksTramp<-2>> Breaks2;
521
+ //CHECK_BROKEN(2);
522
+ //// Holder + 2 aliases
523
+ //typedef py::class_<BreaksBase<-3>, std::unique_ptr<BreaksBase<-3>>, BreaksTramp<-3>, BreaksTramp<-3>> Breaks3;
524
+ //CHECK_BROKEN(3);
525
+ //// Alias + 2 holders
526
+ //typedef py::class_<BreaksBase<-4>, std::unique_ptr<BreaksBase<-4>>, BreaksTramp<-4>, std::shared_ptr<BreaksBase<-4>>> Breaks4;
527
+ //CHECK_BROKEN(4);
528
+ //// Invalid option (not a subclass or holder)
529
+ //typedef py::class_<BreaksBase<-5>, BreaksTramp<-4>> Breaks5;
530
+ //CHECK_BROKEN(5);
531
+ //// Invalid option: multiple inheritance not supported:
532
+ //template <> struct BreaksBase<-8> : BreaksBase<-6>, BreaksBase<-7> {};
533
+ //typedef py::class_<BreaksBase<-8>, BreaksBase<-6>, BreaksBase<-7>> Breaks8;
534
+ //CHECK_BROKEN(8);
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_class.py ADDED
@@ -0,0 +1,466 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ import pytest
3
+
4
+ import env # noqa: F401
5
+
6
+ from pybind11_tests import class_ as m
7
+ from pybind11_tests import UserType, ConstructorStats
8
+
9
+
10
+ def test_repr():
11
+ # In Python 3.3+, repr() accesses __qualname__
12
+ assert "pybind11_type" in repr(type(UserType))
13
+ assert "UserType" in repr(UserType)
14
+
15
+
16
+ def test_instance(msg):
17
+ with pytest.raises(TypeError) as excinfo:
18
+ m.NoConstructor()
19
+ assert msg(excinfo.value) == "m.class_.NoConstructor: No constructor defined!"
20
+
21
+ instance = m.NoConstructor.new_instance()
22
+
23
+ cstats = ConstructorStats.get(m.NoConstructor)
24
+ assert cstats.alive() == 1
25
+ del instance
26
+ assert cstats.alive() == 0
27
+
28
+
29
+ def test_type():
30
+ assert m.check_type(1) == m.DerivedClass1
31
+ with pytest.raises(RuntimeError) as execinfo:
32
+ m.check_type(0)
33
+
34
+ assert "pybind11::detail::get_type_info: unable to find type info" in str(
35
+ execinfo.value
36
+ )
37
+ assert "Invalid" in str(execinfo.value)
38
+
39
+ # Currently not supported
40
+ # See https://github.com/pybind/pybind11/issues/2486
41
+ # assert m.check_type(2) == int
42
+
43
+
44
+ def test_type_of_py():
45
+ assert m.get_type_of(1) == int
46
+ assert m.get_type_of(m.DerivedClass1()) == m.DerivedClass1
47
+ assert m.get_type_of(int) == type
48
+
49
+
50
+ def test_type_of_classic():
51
+ assert m.get_type_classic(1) == int
52
+ assert m.get_type_classic(m.DerivedClass1()) == m.DerivedClass1
53
+ assert m.get_type_classic(int) == type
54
+
55
+
56
+ def test_type_of_py_nodelete():
57
+ # If the above test deleted the class, this will segfault
58
+ assert m.get_type_of(m.DerivedClass1()) == m.DerivedClass1
59
+
60
+
61
+ def test_as_type_py():
62
+ assert m.as_type(int) == int
63
+
64
+ with pytest.raises(TypeError):
65
+ assert m.as_type(1) == int
66
+
67
+ with pytest.raises(TypeError):
68
+ assert m.as_type(m.DerivedClass1()) == m.DerivedClass1
69
+
70
+
71
+ def test_docstrings(doc):
72
+ assert doc(UserType) == "A `py::class_` type for testing"
73
+ assert UserType.__name__ == "UserType"
74
+ assert UserType.__module__ == "pybind11_tests"
75
+ assert UserType.get_value.__name__ == "get_value"
76
+ assert UserType.get_value.__module__ == "pybind11_tests"
77
+
78
+ assert (
79
+ doc(UserType.get_value)
80
+ == """
81
+ get_value(self: m.UserType) -> int
82
+
83
+ Get value using a method
84
+ """
85
+ )
86
+ assert doc(UserType.value) == "Get/set value using a property"
87
+
88
+ assert (
89
+ doc(m.NoConstructor.new_instance)
90
+ == """
91
+ new_instance() -> m.class_.NoConstructor
92
+
93
+ Return an instance
94
+ """
95
+ )
96
+
97
+
98
+ def test_qualname(doc):
99
+ """Tests that a properly qualified name is set in __qualname__ (even in pre-3.3, where we
100
+ backport the attribute) and that generated docstrings properly use it and the module name"""
101
+ assert m.NestBase.__qualname__ == "NestBase"
102
+ assert m.NestBase.Nested.__qualname__ == "NestBase.Nested"
103
+
104
+ assert (
105
+ doc(m.NestBase.__init__)
106
+ == """
107
+ __init__(self: m.class_.NestBase) -> None
108
+ """
109
+ )
110
+ assert (
111
+ doc(m.NestBase.g)
112
+ == """
113
+ g(self: m.class_.NestBase, arg0: m.class_.NestBase.Nested) -> None
114
+ """
115
+ )
116
+ assert (
117
+ doc(m.NestBase.Nested.__init__)
118
+ == """
119
+ __init__(self: m.class_.NestBase.Nested) -> None
120
+ """
121
+ )
122
+ assert (
123
+ doc(m.NestBase.Nested.fn)
124
+ == """
125
+ fn(self: m.class_.NestBase.Nested, arg0: int, arg1: m.class_.NestBase, arg2: m.class_.NestBase.Nested) -> None
126
+ """ # noqa: E501 line too long
127
+ )
128
+ assert (
129
+ doc(m.NestBase.Nested.fa)
130
+ == """
131
+ fa(self: m.class_.NestBase.Nested, a: int, b: m.class_.NestBase, c: m.class_.NestBase.Nested) -> None
132
+ """ # noqa: E501 line too long
133
+ )
134
+ assert m.NestBase.__module__ == "pybind11_tests.class_"
135
+ assert m.NestBase.Nested.__module__ == "pybind11_tests.class_"
136
+
137
+
138
+ def test_inheritance(msg):
139
+ roger = m.Rabbit("Rabbit")
140
+ assert roger.name() + " is a " + roger.species() == "Rabbit is a parrot"
141
+ assert m.pet_name_species(roger) == "Rabbit is a parrot"
142
+
143
+ polly = m.Pet("Polly", "parrot")
144
+ assert polly.name() + " is a " + polly.species() == "Polly is a parrot"
145
+ assert m.pet_name_species(polly) == "Polly is a parrot"
146
+
147
+ molly = m.Dog("Molly")
148
+ assert molly.name() + " is a " + molly.species() == "Molly is a dog"
149
+ assert m.pet_name_species(molly) == "Molly is a dog"
150
+
151
+ fred = m.Hamster("Fred")
152
+ assert fred.name() + " is a " + fred.species() == "Fred is a rodent"
153
+
154
+ assert m.dog_bark(molly) == "Woof!"
155
+
156
+ with pytest.raises(TypeError) as excinfo:
157
+ m.dog_bark(polly)
158
+ assert (
159
+ msg(excinfo.value)
160
+ == """
161
+ dog_bark(): incompatible function arguments. The following argument types are supported:
162
+ 1. (arg0: m.class_.Dog) -> str
163
+
164
+ Invoked with: <m.class_.Pet object at 0>
165
+ """
166
+ )
167
+
168
+ with pytest.raises(TypeError) as excinfo:
169
+ m.Chimera("lion", "goat")
170
+ assert "No constructor defined!" in str(excinfo.value)
171
+
172
+
173
+ def test_inheritance_init(msg):
174
+
175
+ # Single base
176
+ class Python(m.Pet):
177
+ def __init__(self):
178
+ pass
179
+
180
+ with pytest.raises(TypeError) as exc_info:
181
+ Python()
182
+ expected = "m.class_.Pet.__init__() must be called when overriding __init__"
183
+ assert msg(exc_info.value) == expected
184
+
185
+ # Multiple bases
186
+ class RabbitHamster(m.Rabbit, m.Hamster):
187
+ def __init__(self):
188
+ m.Rabbit.__init__(self, "RabbitHamster")
189
+
190
+ with pytest.raises(TypeError) as exc_info:
191
+ RabbitHamster()
192
+ expected = "m.class_.Hamster.__init__() must be called when overriding __init__"
193
+ assert msg(exc_info.value) == expected
194
+
195
+
196
+ def test_automatic_upcasting():
197
+ assert type(m.return_class_1()).__name__ == "DerivedClass1"
198
+ assert type(m.return_class_2()).__name__ == "DerivedClass2"
199
+ assert type(m.return_none()).__name__ == "NoneType"
200
+ # Repeat these a few times in a random order to ensure no invalid caching is applied
201
+ assert type(m.return_class_n(1)).__name__ == "DerivedClass1"
202
+ assert type(m.return_class_n(2)).__name__ == "DerivedClass2"
203
+ assert type(m.return_class_n(0)).__name__ == "BaseClass"
204
+ assert type(m.return_class_n(2)).__name__ == "DerivedClass2"
205
+ assert type(m.return_class_n(2)).__name__ == "DerivedClass2"
206
+ assert type(m.return_class_n(0)).__name__ == "BaseClass"
207
+ assert type(m.return_class_n(1)).__name__ == "DerivedClass1"
208
+
209
+
210
+ def test_isinstance():
211
+ objects = [tuple(), dict(), m.Pet("Polly", "parrot")] + [m.Dog("Molly")] * 4
212
+ expected = (True, True, True, True, True, False, False)
213
+ assert m.check_instances(objects) == expected
214
+
215
+
216
+ def test_mismatched_holder():
217
+ import re
218
+
219
+ with pytest.raises(RuntimeError) as excinfo:
220
+ m.mismatched_holder_1()
221
+ assert re.match(
222
+ 'generic_type: type ".*MismatchDerived1" does not have a non-default '
223
+ 'holder type while its base ".*MismatchBase1" does',
224
+ str(excinfo.value),
225
+ )
226
+
227
+ with pytest.raises(RuntimeError) as excinfo:
228
+ m.mismatched_holder_2()
229
+ assert re.match(
230
+ 'generic_type: type ".*MismatchDerived2" has a non-default holder type '
231
+ 'while its base ".*MismatchBase2" does not',
232
+ str(excinfo.value),
233
+ )
234
+
235
+
236
+ def test_override_static():
237
+ """#511: problem with inheritance + overwritten def_static"""
238
+ b = m.MyBase.make()
239
+ d1 = m.MyDerived.make2()
240
+ d2 = m.MyDerived.make()
241
+
242
+ assert isinstance(b, m.MyBase)
243
+ assert isinstance(d1, m.MyDerived)
244
+ assert isinstance(d2, m.MyDerived)
245
+
246
+
247
+ def test_implicit_conversion_life_support():
248
+ """Ensure the lifetime of temporary objects created for implicit conversions"""
249
+ assert m.implicitly_convert_argument(UserType(5)) == 5
250
+ assert m.implicitly_convert_variable(UserType(5)) == 5
251
+
252
+ assert "outside a bound function" in m.implicitly_convert_variable_fail(UserType(5))
253
+
254
+
255
+ def test_operator_new_delete(capture):
256
+ """Tests that class-specific operator new/delete functions are invoked"""
257
+
258
+ class SubAliased(m.AliasedHasOpNewDelSize):
259
+ pass
260
+
261
+ with capture:
262
+ a = m.HasOpNewDel()
263
+ b = m.HasOpNewDelSize()
264
+ d = m.HasOpNewDelBoth()
265
+ assert (
266
+ capture
267
+ == """
268
+ A new 8
269
+ B new 4
270
+ D new 32
271
+ """
272
+ )
273
+ sz_alias = str(m.AliasedHasOpNewDelSize.size_alias)
274
+ sz_noalias = str(m.AliasedHasOpNewDelSize.size_noalias)
275
+ with capture:
276
+ c = m.AliasedHasOpNewDelSize()
277
+ c2 = SubAliased()
278
+ assert capture == ("C new " + sz_noalias + "\n" + "C new " + sz_alias + "\n")
279
+
280
+ with capture:
281
+ del a
282
+ pytest.gc_collect()
283
+ del b
284
+ pytest.gc_collect()
285
+ del d
286
+ pytest.gc_collect()
287
+ assert (
288
+ capture
289
+ == """
290
+ A delete
291
+ B delete 4
292
+ D delete
293
+ """
294
+ )
295
+
296
+ with capture:
297
+ del c
298
+ pytest.gc_collect()
299
+ del c2
300
+ pytest.gc_collect()
301
+ assert capture == ("C delete " + sz_noalias + "\n" + "C delete " + sz_alias + "\n")
302
+
303
+
304
+ def test_bind_protected_functions():
305
+ """Expose protected member functions to Python using a helper class"""
306
+ a = m.ProtectedA()
307
+ assert a.foo() == 42
308
+
309
+ b = m.ProtectedB()
310
+ assert b.foo() == 42
311
+
312
+ class C(m.ProtectedB):
313
+ def __init__(self):
314
+ m.ProtectedB.__init__(self)
315
+
316
+ def foo(self):
317
+ return 0
318
+
319
+ c = C()
320
+ assert c.foo() == 0
321
+
322
+
323
+ def test_brace_initialization():
324
+ """Tests that simple POD classes can be constructed using C++11 brace initialization"""
325
+ a = m.BraceInitialization(123, "test")
326
+ assert a.field1 == 123
327
+ assert a.field2 == "test"
328
+
329
+ # Tests that a non-simple class doesn't get brace initialization (if the
330
+ # class defines an initializer_list constructor, in particular, it would
331
+ # win over the expected constructor).
332
+ b = m.NoBraceInitialization([123, 456])
333
+ assert b.vec == [123, 456]
334
+
335
+
336
+ @pytest.mark.xfail("env.PYPY")
337
+ def test_class_refcount():
338
+ """Instances must correctly increase/decrease the reference count of their types (#1029)"""
339
+ from sys import getrefcount
340
+
341
+ class PyDog(m.Dog):
342
+ pass
343
+
344
+ for cls in m.Dog, PyDog:
345
+ refcount_1 = getrefcount(cls)
346
+ molly = [cls("Molly") for _ in range(10)]
347
+ refcount_2 = getrefcount(cls)
348
+
349
+ del molly
350
+ pytest.gc_collect()
351
+ refcount_3 = getrefcount(cls)
352
+
353
+ assert refcount_1 == refcount_3
354
+ assert refcount_2 > refcount_1
355
+
356
+
357
+ def test_reentrant_implicit_conversion_failure(msg):
358
+ # ensure that there is no runaway reentrant implicit conversion (#1035)
359
+ with pytest.raises(TypeError) as excinfo:
360
+ m.BogusImplicitConversion(0)
361
+ assert (
362
+ msg(excinfo.value)
363
+ == """
364
+ __init__(): incompatible constructor arguments. The following argument types are supported:
365
+ 1. m.class_.BogusImplicitConversion(arg0: m.class_.BogusImplicitConversion)
366
+
367
+ Invoked with: 0
368
+ """
369
+ )
370
+
371
+
372
+ def test_error_after_conversions():
373
+ with pytest.raises(TypeError) as exc_info:
374
+ m.test_error_after_conversions("hello")
375
+ assert str(exc_info.value).startswith(
376
+ "Unable to convert function return value to a Python type!"
377
+ )
378
+
379
+
380
+ def test_aligned():
381
+ if hasattr(m, "Aligned"):
382
+ p = m.Aligned().ptr()
383
+ assert p % 1024 == 0
384
+
385
+
386
+ # https://foss.heptapod.net/pypy/pypy/-/issues/2742
387
+ @pytest.mark.xfail("env.PYPY")
388
+ def test_final():
389
+ with pytest.raises(TypeError) as exc_info:
390
+
391
+ class PyFinalChild(m.IsFinal):
392
+ pass
393
+
394
+ assert str(exc_info.value).endswith("is not an acceptable base type")
395
+
396
+
397
+ # https://foss.heptapod.net/pypy/pypy/-/issues/2742
398
+ @pytest.mark.xfail("env.PYPY")
399
+ def test_non_final_final():
400
+ with pytest.raises(TypeError) as exc_info:
401
+
402
+ class PyNonFinalFinalChild(m.IsNonFinalFinal):
403
+ pass
404
+
405
+ assert str(exc_info.value).endswith("is not an acceptable base type")
406
+
407
+
408
+ # https://github.com/pybind/pybind11/issues/1878
409
+ def test_exception_rvalue_abort():
410
+ with pytest.raises(RuntimeError):
411
+ m.PyPrintDestructor().throw_something()
412
+
413
+
414
+ # https://github.com/pybind/pybind11/issues/1568
415
+ def test_multiple_instances_with_same_pointer(capture):
416
+ n = 100
417
+ instances = [m.SamePointer() for _ in range(n)]
418
+ for i in range(n):
419
+ # We need to reuse the same allocated memory for with a different type,
420
+ # to ensure the bug in `deregister_instance_impl` is detected. Otherwise
421
+ # `Py_TYPE(self) == Py_TYPE(it->second)` will still succeed, even though
422
+ # the `instance` is already deleted.
423
+ instances[i] = m.Empty()
424
+ # No assert: if this does not trigger the error
425
+ # pybind11_fail("pybind11_object_dealloc(): Tried to deallocate unregistered instance!");
426
+ # and just completes without crashing, we're good.
427
+
428
+
429
+ # https://github.com/pybind/pybind11/issues/1624
430
+ def test_base_and_derived_nested_scope():
431
+ assert issubclass(m.DerivedWithNested, m.BaseWithNested)
432
+ assert m.BaseWithNested.Nested != m.DerivedWithNested.Nested
433
+ assert m.BaseWithNested.Nested.get_name() == "BaseWithNested::Nested"
434
+ assert m.DerivedWithNested.Nested.get_name() == "DerivedWithNested::Nested"
435
+
436
+
437
+ def test_register_duplicate_class():
438
+ import types
439
+
440
+ module_scope = types.ModuleType("module_scope")
441
+ with pytest.raises(RuntimeError) as exc_info:
442
+ m.register_duplicate_class_name(module_scope)
443
+ expected = (
444
+ 'generic_type: cannot initialize type "Duplicate": '
445
+ "an object with that name is already defined"
446
+ )
447
+ assert str(exc_info.value) == expected
448
+ with pytest.raises(RuntimeError) as exc_info:
449
+ m.register_duplicate_class_type(module_scope)
450
+ expected = 'generic_type: type "YetAnotherDuplicate" is already registered!'
451
+ assert str(exc_info.value) == expected
452
+
453
+ class ClassScope:
454
+ pass
455
+
456
+ with pytest.raises(RuntimeError) as exc_info:
457
+ m.register_duplicate_nested_class_name(ClassScope)
458
+ expected = (
459
+ 'generic_type: cannot initialize type "DuplicateNested": '
460
+ "an object with that name is already defined"
461
+ )
462
+ assert str(exc_info.value) == expected
463
+ with pytest.raises(RuntimeError) as exc_info:
464
+ m.register_duplicate_nested_class_type(ClassScope)
465
+ expected = 'generic_type: type "YetAnotherDuplicateNested" is already registered!'
466
+ assert str(exc_info.value) == expected
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_cmake_build/CMakeLists.txt ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Built-in in CMake 3.5+
2
+ include(CMakeParseArguments)
3
+
4
+ add_custom_target(test_cmake_build)
5
+
6
+ function(pybind11_add_build_test name)
7
+ cmake_parse_arguments(ARG "INSTALL" "" "" ${ARGN})
8
+
9
+ set(build_options "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}")
10
+
11
+ if(PYBIND11_FINDPYTHON)
12
+ list(APPEND build_options "-DPYBIND11_FINDPYTHON=${PYBIND11_FINDPYTHON}")
13
+
14
+ if(DEFINED Python_ROOT_DIR)
15
+ list(APPEND build_options "-DPython_ROOT_DIR=${Python_ROOT_DIR}")
16
+ endif()
17
+
18
+ list(APPEND build_options "-DPython_EXECUTABLE=${Python_EXECUTABLE}")
19
+ else()
20
+ list(APPEND build_options "-DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}")
21
+ endif()
22
+
23
+ if(DEFINED CMAKE_CXX_STANDARD)
24
+ list(APPEND build_options "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}")
25
+ endif()
26
+
27
+ if(NOT ARG_INSTALL)
28
+ list(APPEND build_options "-Dpybind11_SOURCE_DIR=${pybind11_SOURCE_DIR}")
29
+ else()
30
+ list(APPEND build_options "-DCMAKE_PREFIX_PATH=${pybind11_BINARY_DIR}/mock_install")
31
+ endif()
32
+
33
+ add_custom_target(
34
+ test_build_${name}
35
+ ${CMAKE_CTEST_COMMAND}
36
+ --build-and-test
37
+ "${CMAKE_CURRENT_SOURCE_DIR}/${name}"
38
+ "${CMAKE_CURRENT_BINARY_DIR}/${name}"
39
+ --build-config
40
+ Release
41
+ --build-noclean
42
+ --build-generator
43
+ ${CMAKE_GENERATOR}
44
+ $<$<BOOL:${CMAKE_GENERATOR_PLATFORM}>:--build-generator-platform>
45
+ ${CMAKE_GENERATOR_PLATFORM}
46
+ --build-makeprogram
47
+ ${CMAKE_MAKE_PROGRAM}
48
+ --build-target
49
+ check_${name}
50
+ --build-options
51
+ ${build_options})
52
+ if(ARG_INSTALL)
53
+ add_dependencies(test_build_${name} mock_install)
54
+ endif()
55
+ add_dependencies(test_cmake_build test_build_${name})
56
+ endfunction()
57
+
58
+ possibly_uninitialized(PYTHON_MODULE_EXTENSION Python_INTERPRETER_ID)
59
+
60
+ pybind11_add_build_test(subdirectory_function)
61
+ pybind11_add_build_test(subdirectory_target)
62
+ if("${PYTHON_MODULE_EXTENSION}" MATCHES "pypy" OR "${Python_INTERPRETER_ID}" STREQUAL "PyPy")
63
+ message(STATUS "Skipping embed test on PyPy")
64
+ else()
65
+ pybind11_add_build_test(subdirectory_embed)
66
+ endif()
67
+
68
+ if(PYBIND11_INSTALL)
69
+ add_custom_target(
70
+ mock_install ${CMAKE_COMMAND} "-DCMAKE_INSTALL_PREFIX=${pybind11_BINARY_DIR}/mock_install" -P
71
+ "${pybind11_BINARY_DIR}/cmake_install.cmake")
72
+
73
+ pybind11_add_build_test(installed_function INSTALL)
74
+ pybind11_add_build_test(installed_target INSTALL)
75
+ if(NOT ("${PYTHON_MODULE_EXTENSION}" MATCHES "pypy" OR "${Python_INTERPRETER_ID}" STREQUAL "PyPy"
76
+ ))
77
+ pybind11_add_build_test(installed_embed INSTALL)
78
+ endif()
79
+ endif()
80
+
81
+ add_dependencies(check test_cmake_build)
82
+
83
+ add_subdirectory(subdirectory_target EXCLUDE_FROM_ALL)
84
+ add_subdirectory(subdirectory_embed EXCLUDE_FROM_ALL)
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_cmake_build/embed.cpp ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <pybind11/embed.h>
2
+ namespace py = pybind11;
3
+
4
+ PYBIND11_EMBEDDED_MODULE(test_cmake_build, m) {
5
+ m.def("add", [](int i, int j) { return i + j; });
6
+ }
7
+
8
+ int main(int argc, char *argv[]) {
9
+ if (argc != 2)
10
+ throw std::runtime_error("Expected test.py file as the first argument");
11
+ auto test_py_file = argv[1];
12
+
13
+ py::scoped_interpreter guard{};
14
+
15
+ auto m = py::module_::import("test_cmake_build");
16
+ if (m.attr("add")(1, 2).cast<int>() != 3)
17
+ throw std::runtime_error("embed.cpp failed");
18
+
19
+ py::module_::import("sys").attr("argv") = py::make_tuple("test.py", "embed.cpp");
20
+ py::eval_file(test_py_file, py::globals());
21
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_cmake_build/installed_embed/CMakeLists.txt ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ cmake_minimum_required(VERSION 3.4)
2
+
3
+ # The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with
4
+ # some versions of VS that have a patched CMake 3.11. This forces us to emulate
5
+ # the behavior using the following workaround:
6
+ if(${CMAKE_VERSION} VERSION_LESS 3.18)
7
+ cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
8
+ else()
9
+ cmake_policy(VERSION 3.18)
10
+ endif()
11
+
12
+ project(test_installed_embed CXX)
13
+
14
+ find_package(pybind11 CONFIG REQUIRED)
15
+ message(STATUS "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}")
16
+
17
+ add_executable(test_installed_embed ../embed.cpp)
18
+ target_link_libraries(test_installed_embed PRIVATE pybind11::embed)
19
+ set_target_properties(test_installed_embed PROPERTIES OUTPUT_NAME test_cmake_build)
20
+
21
+ # Do not treat includes from IMPORTED target as SYSTEM (Python headers in pybind11::embed).
22
+ # This may be needed to resolve header conflicts, e.g. between Python release and debug headers.
23
+ set_target_properties(test_installed_embed PROPERTIES NO_SYSTEM_FROM_IMPORTED ON)
24
+
25
+ add_custom_target(check_installed_embed $<TARGET_FILE:test_installed_embed>
26
+ ${PROJECT_SOURCE_DIR}/../test.py)
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_cmake_build/installed_function/CMakeLists.txt ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ cmake_minimum_required(VERSION 3.4)
2
+ project(test_installed_module CXX)
3
+
4
+ # The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with
5
+ # some versions of VS that have a patched CMake 3.11. This forces us to emulate
6
+ # the behavior using the following workaround:
7
+ if(${CMAKE_VERSION} VERSION_LESS 3.18)
8
+ cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
9
+ else()
10
+ cmake_policy(VERSION 3.18)
11
+ endif()
12
+
13
+ project(test_installed_function CXX)
14
+
15
+ find_package(pybind11 CONFIG REQUIRED)
16
+ message(
17
+ STATUS "Found pybind11 v${pybind11_VERSION} ${pybind11_VERSION_TYPE}: ${pybind11_INCLUDE_DIRS}")
18
+
19
+ pybind11_add_module(test_installed_function SHARED NO_EXTRAS ../main.cpp)
20
+ set_target_properties(test_installed_function PROPERTIES OUTPUT_NAME test_cmake_build)
21
+
22
+ if(DEFINED Python_EXECUTABLE)
23
+ set(_Python_EXECUTABLE "${Python_EXECUTABLE}")
24
+ elseif(DEFINED PYTHON_EXECUTABLE)
25
+ set(_Python_EXECUTABLE "${PYTHON_EXECUTABLE}")
26
+ else()
27
+ message(FATAL_ERROR "No Python executable defined (should not be possible at this stage)")
28
+ endif()
29
+
30
+ add_custom_target(
31
+ check_installed_function
32
+ ${CMAKE_COMMAND}
33
+ -E
34
+ env
35
+ PYTHONPATH=$<TARGET_FILE_DIR:test_installed_function>
36
+ ${_Python_EXECUTABLE}
37
+ ${PROJECT_SOURCE_DIR}/../test.py
38
+ ${PROJECT_NAME})
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_cmake_build/installed_target/CMakeLists.txt ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ cmake_minimum_required(VERSION 3.4)
2
+
3
+ # The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with
4
+ # some versions of VS that have a patched CMake 3.11. This forces us to emulate
5
+ # the behavior using the following workaround:
6
+ if(${CMAKE_VERSION} VERSION_LESS 3.18)
7
+ cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
8
+ else()
9
+ cmake_policy(VERSION 3.18)
10
+ endif()
11
+
12
+ project(test_installed_target CXX)
13
+
14
+ find_package(pybind11 CONFIG REQUIRED)
15
+ message(STATUS "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}")
16
+
17
+ add_library(test_installed_target MODULE ../main.cpp)
18
+
19
+ target_link_libraries(test_installed_target PRIVATE pybind11::module)
20
+ set_target_properties(test_installed_target PROPERTIES OUTPUT_NAME test_cmake_build)
21
+
22
+ # Make sure result is, for example, test_installed_target.so, not libtest_installed_target.dylib
23
+ pybind11_extension(test_installed_target)
24
+
25
+ # Do not treat includes from IMPORTED target as SYSTEM (Python headers in pybind11::module).
26
+ # This may be needed to resolve header conflicts, e.g. between Python release and debug headers.
27
+ set_target_properties(test_installed_target PROPERTIES NO_SYSTEM_FROM_IMPORTED ON)
28
+
29
+ if(DEFINED Python_EXECUTABLE)
30
+ set(_Python_EXECUTABLE "${Python_EXECUTABLE}")
31
+ elseif(DEFINED PYTHON_EXECUTABLE)
32
+ set(_Python_EXECUTABLE "${PYTHON_EXECUTABLE}")
33
+ else()
34
+ message(FATAL_ERROR "No Python executable defined (should not be possible at this stage)")
35
+ endif()
36
+
37
+ add_custom_target(
38
+ check_installed_target
39
+ ${CMAKE_COMMAND}
40
+ -E
41
+ env
42
+ PYTHONPATH=$<TARGET_FILE_DIR:test_installed_target>
43
+ ${_Python_EXECUTABLE}
44
+ ${PROJECT_SOURCE_DIR}/../test.py
45
+ ${PROJECT_NAME})
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_cmake_build/main.cpp ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ #include <pybind11/pybind11.h>
2
+ namespace py = pybind11;
3
+
4
+ PYBIND11_MODULE(test_cmake_build, m) {
5
+ m.def("add", [](int i, int j) { return i + j; });
6
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_cmake_build/subdirectory_embed/CMakeLists.txt ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ cmake_minimum_required(VERSION 3.4)
2
+
3
+ # The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with
4
+ # some versions of VS that have a patched CMake 3.11. This forces us to emulate
5
+ # the behavior using the following workaround:
6
+ if(${CMAKE_VERSION} VERSION_LESS 3.18)
7
+ cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
8
+ else()
9
+ cmake_policy(VERSION 3.18)
10
+ endif()
11
+
12
+ project(test_subdirectory_embed CXX)
13
+
14
+ set(PYBIND11_INSTALL
15
+ ON
16
+ CACHE BOOL "")
17
+ set(PYBIND11_EXPORT_NAME test_export)
18
+
19
+ add_subdirectory("${pybind11_SOURCE_DIR}" pybind11)
20
+
21
+ # Test basic target functionality
22
+ add_executable(test_subdirectory_embed ../embed.cpp)
23
+ target_link_libraries(test_subdirectory_embed PRIVATE pybind11::embed)
24
+ set_target_properties(test_subdirectory_embed PROPERTIES OUTPUT_NAME test_cmake_build)
25
+
26
+ add_custom_target(check_subdirectory_embed $<TARGET_FILE:test_subdirectory_embed>
27
+ "${PROJECT_SOURCE_DIR}/../test.py")
28
+
29
+ # Test custom export group -- PYBIND11_EXPORT_NAME
30
+ add_library(test_embed_lib ../embed.cpp)
31
+ target_link_libraries(test_embed_lib PRIVATE pybind11::embed)
32
+
33
+ install(
34
+ TARGETS test_embed_lib
35
+ EXPORT test_export
36
+ ARCHIVE DESTINATION bin
37
+ LIBRARY DESTINATION lib
38
+ RUNTIME DESTINATION lib)
39
+ install(EXPORT test_export DESTINATION lib/cmake/test_export/test_export-Targets.cmake)
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_cmake_build/subdirectory_function/CMakeLists.txt ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ cmake_minimum_required(VERSION 3.4)
2
+
3
+ # The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with
4
+ # some versions of VS that have a patched CMake 3.11. This forces us to emulate
5
+ # the behavior using the following workaround:
6
+ if(${CMAKE_VERSION} VERSION_LESS 3.18)
7
+ cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
8
+ else()
9
+ cmake_policy(VERSION 3.18)
10
+ endif()
11
+
12
+ project(test_subdirectory_function CXX)
13
+
14
+ add_subdirectory("${pybind11_SOURCE_DIR}" pybind11)
15
+ pybind11_add_module(test_subdirectory_function ../main.cpp)
16
+ set_target_properties(test_subdirectory_function PROPERTIES OUTPUT_NAME test_cmake_build)
17
+
18
+ if(DEFINED Python_EXECUTABLE)
19
+ set(_Python_EXECUTABLE "${Python_EXECUTABLE}")
20
+ elseif(DEFINED PYTHON_EXECUTABLE)
21
+ set(_Python_EXECUTABLE "${PYTHON_EXECUTABLE}")
22
+ else()
23
+ message(FATAL_ERROR "No Python executable defined (should not be possible at this stage)")
24
+ endif()
25
+
26
+ add_custom_target(
27
+ check_subdirectory_function
28
+ ${CMAKE_COMMAND}
29
+ -E
30
+ env
31
+ PYTHONPATH=$<TARGET_FILE_DIR:test_subdirectory_function>
32
+ ${_Python_EXECUTABLE}
33
+ ${PROJECT_SOURCE_DIR}/../test.py
34
+ ${PROJECT_NAME})
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_cmake_build/subdirectory_target/CMakeLists.txt ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ cmake_minimum_required(VERSION 3.4)
2
+
3
+ # The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with
4
+ # some versions of VS that have a patched CMake 3.11. This forces us to emulate
5
+ # the behavior using the following workaround:
6
+ if(${CMAKE_VERSION} VERSION_LESS 3.18)
7
+ cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
8
+ else()
9
+ cmake_policy(VERSION 3.18)
10
+ endif()
11
+
12
+ project(test_subdirectory_target CXX)
13
+
14
+ add_subdirectory("${pybind11_SOURCE_DIR}" pybind11)
15
+
16
+ add_library(test_subdirectory_target MODULE ../main.cpp)
17
+ set_target_properties(test_subdirectory_target PROPERTIES OUTPUT_NAME test_cmake_build)
18
+
19
+ target_link_libraries(test_subdirectory_target PRIVATE pybind11::module)
20
+
21
+ # Make sure result is, for example, test_installed_target.so, not libtest_installed_target.dylib
22
+ pybind11_extension(test_subdirectory_target)
23
+
24
+ if(DEFINED Python_EXECUTABLE)
25
+ set(_Python_EXECUTABLE "${Python_EXECUTABLE}")
26
+ elseif(DEFINED PYTHON_EXECUTABLE)
27
+ set(_Python_EXECUTABLE "${PYTHON_EXECUTABLE}")
28
+ else()
29
+ message(FATAL_ERROR "No Python executable defined (should not be possible at this stage)")
30
+ endif()
31
+
32
+ add_custom_target(
33
+ check_subdirectory_target
34
+ ${CMAKE_COMMAND}
35
+ -E
36
+ env
37
+ PYTHONPATH=$<TARGET_FILE_DIR:test_subdirectory_target>
38
+ ${_Python_EXECUTABLE}
39
+ ${PROJECT_SOURCE_DIR}/../test.py
40
+ ${PROJECT_NAME})
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_cmake_build/test.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ import sys
3
+ import test_cmake_build
4
+
5
+ assert test_cmake_build.add(1, 2) == 3
6
+ print("{} imports, runs, and adds: 1 + 2 = 3".format(sys.argv[1]))
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_constants_and_functions.cpp ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ tests/test_constants_and_functions.cpp -- global constants and functions, enumerations, raw
3
+ byte strings
4
+
5
+ Copyright (c) 2016 Wenzel Jakob <[email protected]>
6
+
7
+ All rights reserved. Use of this source code is governed by a
8
+ BSD-style license that can be found in the LICENSE file.
9
+ */
10
+
11
+ #include "pybind11_tests.h"
12
+
13
+ enum MyEnum { EFirstEntry = 1, ESecondEntry };
14
+
15
+ std::string test_function1() {
16
+ return "test_function()";
17
+ }
18
+
19
+ std::string test_function2(MyEnum k) {
20
+ return "test_function(enum=" + std::to_string(k) + ")";
21
+ }
22
+
23
+ std::string test_function3(int i) {
24
+ return "test_function(" + std::to_string(i) + ")";
25
+ }
26
+
27
+ py::str test_function4() { return "test_function()"; }
28
+ py::str test_function4(char *) { return "test_function(char *)"; }
29
+ py::str test_function4(int, float) { return "test_function(int, float)"; }
30
+ py::str test_function4(float, int) { return "test_function(float, int)"; }
31
+
32
+ py::bytes return_bytes() {
33
+ const char *data = "\x01\x00\x02\x00";
34
+ return std::string(data, 4);
35
+ }
36
+
37
+ std::string print_bytes(const py::bytes &bytes) {
38
+ std::string ret = "bytes[";
39
+ const auto value = static_cast<std::string>(bytes);
40
+ for (size_t i = 0; i < value.length(); ++i) {
41
+ ret += std::to_string(static_cast<int>(value[i])) + " ";
42
+ }
43
+ ret.back() = ']';
44
+ return ret;
45
+ }
46
+
47
+ // Test that we properly handle C++17 exception specifiers (which are part of the function signature
48
+ // in C++17). These should all still work before C++17, but don't affect the function signature.
49
+ namespace test_exc_sp {
50
+ // [workaround(intel)] Unable to use noexcept instead of noexcept(true)
51
+ // Make the f1 test basically the same as the f2 test in C++17 mode for the Intel compiler as
52
+ // it fails to compile with a plain noexcept (tested with icc (ICC) 2021.1 Beta 20200827).
53
+ #if defined(__INTEL_COMPILER) && defined(PYBIND11_CPP17)
54
+ int f1(int x) noexcept(true) { return x+1; }
55
+ #else
56
+ int f1(int x) noexcept { return x+1; }
57
+ #endif
58
+ int f2(int x) noexcept(true) { return x+2; }
59
+ int f3(int x) noexcept(false) { return x+3; }
60
+ #if defined(__GNUG__) && !defined(__INTEL_COMPILER)
61
+ # pragma GCC diagnostic push
62
+ # pragma GCC diagnostic ignored "-Wdeprecated"
63
+ #endif
64
+ // NOLINTNEXTLINE(modernize-use-noexcept)
65
+ int f4(int x) throw() { return x+4; } // Deprecated equivalent to noexcept(true)
66
+ #if defined(__GNUG__) && !defined(__INTEL_COMPILER)
67
+ # pragma GCC diagnostic pop
68
+ #endif
69
+ struct C {
70
+ int m1(int x) noexcept { return x-1; }
71
+ int m2(int x) const noexcept { return x-2; }
72
+ int m3(int x) noexcept(true) { return x-3; }
73
+ int m4(int x) const noexcept(true) { return x-4; }
74
+ int m5(int x) noexcept(false) { return x-5; }
75
+ int m6(int x) const noexcept(false) { return x-6; }
76
+ #if defined(__GNUG__) && !defined(__INTEL_COMPILER)
77
+ # pragma GCC diagnostic push
78
+ # pragma GCC diagnostic ignored "-Wdeprecated"
79
+ #endif
80
+ // NOLINTNEXTLINE(modernize-use-noexcept)
81
+ int m7(int x) throw() { return x - 7; }
82
+ // NOLINTNEXTLINE(modernize-use-noexcept)
83
+ int m8(int x) const throw() { return x - 8; }
84
+ #if defined(__GNUG__) && !defined(__INTEL_COMPILER)
85
+ # pragma GCC diagnostic pop
86
+ #endif
87
+ };
88
+ } // namespace test_exc_sp
89
+
90
+
91
+ TEST_SUBMODULE(constants_and_functions, m) {
92
+ // test_constants
93
+ m.attr("some_constant") = py::int_(14);
94
+
95
+ // test_function_overloading
96
+ m.def("test_function", &test_function1);
97
+ m.def("test_function", &test_function2);
98
+ m.def("test_function", &test_function3);
99
+
100
+ #if defined(PYBIND11_OVERLOAD_CAST)
101
+ m.def("test_function", py::overload_cast<>(&test_function4));
102
+ m.def("test_function", py::overload_cast<char *>(&test_function4));
103
+ m.def("test_function", py::overload_cast<int, float>(&test_function4));
104
+ m.def("test_function", py::overload_cast<float, int>(&test_function4));
105
+ #else
106
+ m.def("test_function", static_cast<py::str (*)()>(&test_function4));
107
+ m.def("test_function", static_cast<py::str (*)(char *)>(&test_function4));
108
+ m.def("test_function", static_cast<py::str (*)(int, float)>(&test_function4));
109
+ m.def("test_function", static_cast<py::str (*)(float, int)>(&test_function4));
110
+ #endif
111
+
112
+ py::enum_<MyEnum>(m, "MyEnum")
113
+ .value("EFirstEntry", EFirstEntry)
114
+ .value("ESecondEntry", ESecondEntry)
115
+ .export_values();
116
+
117
+ // test_bytes
118
+ m.def("return_bytes", &return_bytes);
119
+ m.def("print_bytes", &print_bytes);
120
+
121
+ // test_exception_specifiers
122
+ using namespace test_exc_sp;
123
+ py::class_<C>(m, "C")
124
+ .def(py::init<>())
125
+ .def("m1", &C::m1)
126
+ .def("m2", &C::m2)
127
+ .def("m3", &C::m3)
128
+ .def("m4", &C::m4)
129
+ .def("m5", &C::m5)
130
+ .def("m6", &C::m6)
131
+ .def("m7", &C::m7)
132
+ .def("m8", &C::m8)
133
+ ;
134
+ m.def("f1", f1);
135
+ m.def("f2", f2);
136
+ #if defined(__INTEL_COMPILER)
137
+ # pragma warning push
138
+ # pragma warning disable 878 // incompatible exception specifications
139
+ #endif
140
+ m.def("f3", f3);
141
+ #if defined(__INTEL_COMPILER)
142
+ # pragma warning pop
143
+ #endif
144
+ m.def("f4", f4);
145
+
146
+ // test_function_record_leaks
147
+ struct LargeCapture {
148
+ // This should always be enough to trigger the alternative branch
149
+ // where `sizeof(capture) > sizeof(rec->data)`
150
+ uint64_t zeros[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
151
+ };
152
+ m.def("register_large_capture_with_invalid_arguments", [](py::module_ m) {
153
+ LargeCapture capture; // VS 2015's MSVC is acting up if we create the array here
154
+ m.def("should_raise", [capture](int) { return capture.zeros[9] + 33; }, py::kw_only(), py::arg());
155
+ });
156
+ m.def("register_with_raising_repr", [](py::module_ m, const py::object &default_value) {
157
+ m.def(
158
+ "should_raise",
159
+ [](int, int, const py::object &) { return 42; },
160
+ "some docstring",
161
+ py::arg_v("x", 42),
162
+ py::arg_v("y", 42, "<the answer>"),
163
+ py::arg_v("z", default_value));
164
+ });
165
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_constants_and_functions.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ import pytest
3
+
4
+ m = pytest.importorskip("pybind11_tests.constants_and_functions")
5
+
6
+
7
+ def test_constants():
8
+ assert m.some_constant == 14
9
+
10
+
11
+ def test_function_overloading():
12
+ assert m.test_function() == "test_function()"
13
+ assert m.test_function(7) == "test_function(7)"
14
+ assert m.test_function(m.MyEnum.EFirstEntry) == "test_function(enum=1)"
15
+ assert m.test_function(m.MyEnum.ESecondEntry) == "test_function(enum=2)"
16
+
17
+ assert m.test_function() == "test_function()"
18
+ assert m.test_function("abcd") == "test_function(char *)"
19
+ assert m.test_function(1, 1.0) == "test_function(int, float)"
20
+ assert m.test_function(1, 1.0) == "test_function(int, float)"
21
+ assert m.test_function(2.0, 2) == "test_function(float, int)"
22
+
23
+
24
+ def test_bytes():
25
+ assert m.print_bytes(m.return_bytes()) == "bytes[1 0 2 0]"
26
+
27
+
28
+ def test_exception_specifiers():
29
+ c = m.C()
30
+ assert c.m1(2) == 1
31
+ assert c.m2(3) == 1
32
+ assert c.m3(5) == 2
33
+ assert c.m4(7) == 3
34
+ assert c.m5(10) == 5
35
+ assert c.m6(14) == 8
36
+ assert c.m7(20) == 13
37
+ assert c.m8(29) == 21
38
+
39
+ assert m.f1(33) == 34
40
+ assert m.f2(53) == 55
41
+ assert m.f3(86) == 89
42
+ assert m.f4(140) == 144
43
+
44
+
45
+ def test_function_record_leaks():
46
+ class RaisingRepr:
47
+ def __repr__(self):
48
+ raise RuntimeError("Surprise!")
49
+
50
+ with pytest.raises(RuntimeError):
51
+ m.register_large_capture_with_invalid_arguments(m)
52
+ with pytest.raises(RuntimeError):
53
+ m.register_with_raising_repr(m, RaisingRepr())
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_copy_move.cpp ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ tests/test_copy_move_policies.cpp -- 'copy' and 'move' return value policies
3
+ and related tests
4
+
5
+ Copyright (c) 2016 Ben North <[email protected]>
6
+
7
+ All rights reserved. Use of this source code is governed by a
8
+ BSD-style license that can be found in the LICENSE file.
9
+ */
10
+
11
+ #include "pybind11_tests.h"
12
+ #include "constructor_stats.h"
13
+ #include <pybind11/stl.h>
14
+
15
+ template <typename derived>
16
+ struct empty {
17
+ static const derived& get_one() { return instance_; }
18
+ static derived instance_;
19
+ };
20
+
21
+ struct lacking_copy_ctor : public empty<lacking_copy_ctor> {
22
+ lacking_copy_ctor() = default;
23
+ lacking_copy_ctor(const lacking_copy_ctor& other) = delete;
24
+ };
25
+
26
+ template <> lacking_copy_ctor empty<lacking_copy_ctor>::instance_ = {};
27
+
28
+ struct lacking_move_ctor : public empty<lacking_move_ctor> {
29
+ lacking_move_ctor() = default;
30
+ lacking_move_ctor(const lacking_move_ctor& other) = delete;
31
+ lacking_move_ctor(lacking_move_ctor&& other) = delete;
32
+ };
33
+
34
+ template <> lacking_move_ctor empty<lacking_move_ctor>::instance_ = {};
35
+
36
+ /* Custom type caster move/copy test classes */
37
+ class MoveOnlyInt {
38
+ public:
39
+ MoveOnlyInt() { print_default_created(this); }
40
+ MoveOnlyInt(int v) : value{v} { print_created(this, value); }
41
+ MoveOnlyInt(MoveOnlyInt &&m) noexcept {
42
+ print_move_created(this, m.value);
43
+ std::swap(value, m.value);
44
+ }
45
+ MoveOnlyInt &operator=(MoveOnlyInt &&m) noexcept {
46
+ print_move_assigned(this, m.value);
47
+ std::swap(value, m.value);
48
+ return *this;
49
+ }
50
+ MoveOnlyInt(const MoveOnlyInt &) = delete;
51
+ MoveOnlyInt &operator=(const MoveOnlyInt &) = delete;
52
+ ~MoveOnlyInt() { print_destroyed(this); }
53
+
54
+ int value;
55
+ };
56
+ class MoveOrCopyInt {
57
+ public:
58
+ MoveOrCopyInt() { print_default_created(this); }
59
+ MoveOrCopyInt(int v) : value{v} { print_created(this, value); }
60
+ MoveOrCopyInt(MoveOrCopyInt &&m) noexcept {
61
+ print_move_created(this, m.value);
62
+ std::swap(value, m.value);
63
+ }
64
+ MoveOrCopyInt &operator=(MoveOrCopyInt &&m) noexcept {
65
+ print_move_assigned(this, m.value);
66
+ std::swap(value, m.value);
67
+ return *this;
68
+ }
69
+ MoveOrCopyInt(const MoveOrCopyInt &c) { print_copy_created(this, c.value); value = c.value; }
70
+ MoveOrCopyInt &operator=(const MoveOrCopyInt &c) { print_copy_assigned(this, c.value); value = c.value; return *this; }
71
+ ~MoveOrCopyInt() { print_destroyed(this); }
72
+
73
+ int value;
74
+ };
75
+ class CopyOnlyInt {
76
+ public:
77
+ CopyOnlyInt() { print_default_created(this); }
78
+ CopyOnlyInt(int v) : value{v} { print_created(this, value); }
79
+ CopyOnlyInt(const CopyOnlyInt &c) { print_copy_created(this, c.value); value = c.value; }
80
+ CopyOnlyInt &operator=(const CopyOnlyInt &c) { print_copy_assigned(this, c.value); value = c.value; return *this; }
81
+ ~CopyOnlyInt() { print_destroyed(this); }
82
+
83
+ int value;
84
+ };
85
+ PYBIND11_NAMESPACE_BEGIN(pybind11)
86
+ PYBIND11_NAMESPACE_BEGIN(detail)
87
+ template <> struct type_caster<MoveOnlyInt> {
88
+ PYBIND11_TYPE_CASTER(MoveOnlyInt, _("MoveOnlyInt"));
89
+ bool load(handle src, bool) { value = MoveOnlyInt(src.cast<int>()); return true; }
90
+ static handle cast(const MoveOnlyInt &m, return_value_policy r, handle p) { return pybind11::cast(m.value, r, p); }
91
+ };
92
+
93
+ template <> struct type_caster<MoveOrCopyInt> {
94
+ PYBIND11_TYPE_CASTER(MoveOrCopyInt, _("MoveOrCopyInt"));
95
+ bool load(handle src, bool) { value = MoveOrCopyInt(src.cast<int>()); return true; }
96
+ static handle cast(const MoveOrCopyInt &m, return_value_policy r, handle p) { return pybind11::cast(m.value, r, p); }
97
+ };
98
+
99
+ template <> struct type_caster<CopyOnlyInt> {
100
+ protected:
101
+ CopyOnlyInt value;
102
+ public:
103
+ static constexpr auto name = _("CopyOnlyInt");
104
+ bool load(handle src, bool) { value = CopyOnlyInt(src.cast<int>()); return true; }
105
+ static handle cast(const CopyOnlyInt &m, return_value_policy r, handle p) { return pybind11::cast(m.value, r, p); }
106
+ static handle cast(const CopyOnlyInt *src, return_value_policy policy, handle parent) {
107
+ if (!src) return none().release();
108
+ return cast(*src, policy, parent);
109
+ }
110
+ operator CopyOnlyInt*() { return &value; }
111
+ operator CopyOnlyInt&() { return value; }
112
+ template <typename T> using cast_op_type = pybind11::detail::cast_op_type<T>;
113
+ };
114
+ PYBIND11_NAMESPACE_END(detail)
115
+ PYBIND11_NAMESPACE_END(pybind11)
116
+
117
+ TEST_SUBMODULE(copy_move_policies, m) {
118
+ // test_lacking_copy_ctor
119
+ py::class_<lacking_copy_ctor>(m, "lacking_copy_ctor")
120
+ .def_static("get_one", &lacking_copy_ctor::get_one,
121
+ py::return_value_policy::copy);
122
+ // test_lacking_move_ctor
123
+ py::class_<lacking_move_ctor>(m, "lacking_move_ctor")
124
+ .def_static("get_one", &lacking_move_ctor::get_one,
125
+ py::return_value_policy::move);
126
+
127
+ // test_move_and_copy_casts
128
+ // NOLINTNEXTLINE(performance-unnecessary-value-param)
129
+ m.def("move_and_copy_casts", [](const py::object &o) {
130
+ int r = 0;
131
+ r += py::cast<MoveOrCopyInt>(o).value; /* moves */
132
+ r += py::cast<MoveOnlyInt>(o).value; /* moves */
133
+ r += py::cast<CopyOnlyInt>(o).value; /* copies */
134
+ auto m1(py::cast<MoveOrCopyInt>(o)); /* moves */
135
+ auto m2(py::cast<MoveOnlyInt>(o)); /* moves */
136
+ auto m3(py::cast<CopyOnlyInt>(o)); /* copies */
137
+ r += m1.value + m2.value + m3.value;
138
+
139
+ return r;
140
+ });
141
+
142
+ // test_move_and_copy_loads
143
+ m.def("move_only", [](MoveOnlyInt m) { return m.value; });
144
+ // Changing this breaks the existing test: needs careful review.
145
+ // NOLINTNEXTLINE(performance-unnecessary-value-param)
146
+ m.def("move_or_copy", [](MoveOrCopyInt m) { return m.value; });
147
+ // Changing this breaks the existing test: needs careful review.
148
+ // NOLINTNEXTLINE(performance-unnecessary-value-param)
149
+ m.def("copy_only", [](CopyOnlyInt m) { return m.value; });
150
+ m.def("move_pair", [](std::pair<MoveOnlyInt, MoveOrCopyInt> p) {
151
+ return p.first.value + p.second.value;
152
+ });
153
+ m.def("move_tuple", [](std::tuple<MoveOnlyInt, MoveOrCopyInt, MoveOnlyInt> t) {
154
+ return std::get<0>(t).value + std::get<1>(t).value + std::get<2>(t).value;
155
+ });
156
+ m.def("copy_tuple", [](std::tuple<CopyOnlyInt, CopyOnlyInt> t) {
157
+ return std::get<0>(t).value + std::get<1>(t).value;
158
+ });
159
+ m.def("move_copy_nested", [](std::pair<MoveOnlyInt, std::pair<std::tuple<MoveOrCopyInt, CopyOnlyInt, std::tuple<MoveOnlyInt>>, MoveOrCopyInt>> x) {
160
+ return x.first.value + std::get<0>(x.second.first).value + std::get<1>(x.second.first).value +
161
+ std::get<0>(std::get<2>(x.second.first)).value + x.second.second.value;
162
+ });
163
+ m.def("move_and_copy_cstats", []() {
164
+ ConstructorStats::gc();
165
+ // Reset counts to 0 so that previous tests don't affect later ones:
166
+ auto &mc = ConstructorStats::get<MoveOrCopyInt>();
167
+ mc.move_assignments = mc.move_constructions = mc.copy_assignments = mc.copy_constructions = 0;
168
+ auto &mo = ConstructorStats::get<MoveOnlyInt>();
169
+ mo.move_assignments = mo.move_constructions = mo.copy_assignments = mo.copy_constructions = 0;
170
+ auto &co = ConstructorStats::get<CopyOnlyInt>();
171
+ co.move_assignments = co.move_constructions = co.copy_assignments = co.copy_constructions = 0;
172
+ py::dict d;
173
+ d["MoveOrCopyInt"] = py::cast(mc, py::return_value_policy::reference);
174
+ d["MoveOnlyInt"] = py::cast(mo, py::return_value_policy::reference);
175
+ d["CopyOnlyInt"] = py::cast(co, py::return_value_policy::reference);
176
+ return d;
177
+ });
178
+ #ifdef PYBIND11_HAS_OPTIONAL
179
+ // test_move_and_copy_load_optional
180
+ m.attr("has_optional") = true;
181
+ m.def("move_optional", [](std::optional<MoveOnlyInt> o) {
182
+ return o->value;
183
+ });
184
+ m.def("move_or_copy_optional", [](std::optional<MoveOrCopyInt> o) {
185
+ return o->value;
186
+ });
187
+ m.def("copy_optional", [](std::optional<CopyOnlyInt> o) {
188
+ return o->value;
189
+ });
190
+ m.def("move_optional_tuple", [](std::optional<std::tuple<MoveOrCopyInt, MoveOnlyInt, CopyOnlyInt>> x) {
191
+ return std::get<0>(*x).value + std::get<1>(*x).value + std::get<2>(*x).value;
192
+ });
193
+ #else
194
+ m.attr("has_optional") = false;
195
+ #endif
196
+
197
+ // #70 compilation issue if operator new is not public - simple body added
198
+ // but not needed on most compilers; MSVC and nvcc don't like a local
199
+ // struct not having a method defined when declared, since it can not be
200
+ // added later.
201
+ struct PrivateOpNew {
202
+ int value = 1;
203
+ private:
204
+ void *operator new(size_t bytes) {
205
+ void *ptr = std::malloc(bytes);
206
+ if (ptr)
207
+ return ptr;
208
+ throw std::bad_alloc{};
209
+ }
210
+ };
211
+ py::class_<PrivateOpNew>(m, "PrivateOpNew").def_readonly("value", &PrivateOpNew::value);
212
+ m.def("private_op_new_value", []() { return PrivateOpNew(); });
213
+ m.def("private_op_new_reference", []() -> const PrivateOpNew & {
214
+ static PrivateOpNew x{};
215
+ return x;
216
+ }, py::return_value_policy::reference);
217
+
218
+ // test_move_fallback
219
+ // #389: rvp::move should fall-through to copy on non-movable objects
220
+ struct MoveIssue1 {
221
+ int v;
222
+ MoveIssue1(int v) : v{v} {}
223
+ MoveIssue1(const MoveIssue1 &c) = default;
224
+ MoveIssue1(MoveIssue1 &&) = delete;
225
+ };
226
+ py::class_<MoveIssue1>(m, "MoveIssue1").def(py::init<int>()).def_readwrite("value", &MoveIssue1::v);
227
+
228
+ struct MoveIssue2 {
229
+ int v;
230
+ MoveIssue2(int v) : v{v} {}
231
+ MoveIssue2(MoveIssue2 &&) = default;
232
+ };
233
+ py::class_<MoveIssue2>(m, "MoveIssue2").def(py::init<int>()).def_readwrite("value", &MoveIssue2::v);
234
+
235
+ // #2742: Don't expect ownership of raw pointer to `new`ed object to be transferred with `py::return_value_policy::move`
236
+ m.def("get_moveissue1", [](int i) { return std::unique_ptr<MoveIssue1>(new MoveIssue1(i)); }, py::return_value_policy::move);
237
+ m.def("get_moveissue2", [](int i) { return MoveIssue2(i); }, py::return_value_policy::move);
238
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_copy_move.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ import pytest
3
+ from pybind11_tests import copy_move_policies as m
4
+
5
+
6
+ def test_lacking_copy_ctor():
7
+ with pytest.raises(RuntimeError) as excinfo:
8
+ m.lacking_copy_ctor.get_one()
9
+ assert "is non-copyable!" in str(excinfo.value)
10
+
11
+
12
+ def test_lacking_move_ctor():
13
+ with pytest.raises(RuntimeError) as excinfo:
14
+ m.lacking_move_ctor.get_one()
15
+ assert "is neither movable nor copyable!" in str(excinfo.value)
16
+
17
+
18
+ def test_move_and_copy_casts():
19
+ """Cast some values in C++ via custom type casters and count the number of moves/copies."""
20
+
21
+ cstats = m.move_and_copy_cstats()
22
+ c_m, c_mc, c_c = (
23
+ cstats["MoveOnlyInt"],
24
+ cstats["MoveOrCopyInt"],
25
+ cstats["CopyOnlyInt"],
26
+ )
27
+
28
+ # The type move constructions/assignments below each get incremented: the move assignment comes
29
+ # from the type_caster load; the move construction happens when extracting that via a cast or
30
+ # loading into an argument.
31
+ assert m.move_and_copy_casts(3) == 18
32
+ assert c_m.copy_assignments + c_m.copy_constructions == 0
33
+ assert c_m.move_assignments == 2
34
+ assert c_m.move_constructions >= 2
35
+ assert c_mc.alive() == 0
36
+ assert c_mc.copy_assignments + c_mc.copy_constructions == 0
37
+ assert c_mc.move_assignments == 2
38
+ assert c_mc.move_constructions >= 2
39
+ assert c_c.alive() == 0
40
+ assert c_c.copy_assignments == 2
41
+ assert c_c.copy_constructions >= 2
42
+ assert c_m.alive() + c_mc.alive() + c_c.alive() == 0
43
+
44
+
45
+ def test_move_and_copy_loads():
46
+ """Call some functions that load arguments via custom type casters and count the number of
47
+ moves/copies."""
48
+
49
+ cstats = m.move_and_copy_cstats()
50
+ c_m, c_mc, c_c = (
51
+ cstats["MoveOnlyInt"],
52
+ cstats["MoveOrCopyInt"],
53
+ cstats["CopyOnlyInt"],
54
+ )
55
+
56
+ assert m.move_only(10) == 10 # 1 move, c_m
57
+ assert m.move_or_copy(11) == 11 # 1 move, c_mc
58
+ assert m.copy_only(12) == 12 # 1 copy, c_c
59
+ assert m.move_pair((13, 14)) == 27 # 1 c_m move, 1 c_mc move
60
+ assert m.move_tuple((15, 16, 17)) == 48 # 2 c_m moves, 1 c_mc move
61
+ assert m.copy_tuple((18, 19)) == 37 # 2 c_c copies
62
+ # Direct constructions: 2 c_m moves, 2 c_mc moves, 1 c_c copy
63
+ # Extra moves/copies when moving pairs/tuples: 3 c_m, 3 c_mc, 2 c_c
64
+ assert m.move_copy_nested((1, ((2, 3, (4,)), 5))) == 15
65
+
66
+ assert c_m.copy_assignments + c_m.copy_constructions == 0
67
+ assert c_m.move_assignments == 6
68
+ assert c_m.move_constructions == 9
69
+ assert c_mc.copy_assignments + c_mc.copy_constructions == 0
70
+ assert c_mc.move_assignments == 5
71
+ assert c_mc.move_constructions == 8
72
+ assert c_c.copy_assignments == 4
73
+ assert c_c.copy_constructions == 6
74
+ assert c_m.alive() + c_mc.alive() + c_c.alive() == 0
75
+
76
+
77
+ @pytest.mark.skipif(not m.has_optional, reason="no <optional>")
78
+ def test_move_and_copy_load_optional():
79
+ """Tests move/copy loads of std::optional arguments"""
80
+
81
+ cstats = m.move_and_copy_cstats()
82
+ c_m, c_mc, c_c = (
83
+ cstats["MoveOnlyInt"],
84
+ cstats["MoveOrCopyInt"],
85
+ cstats["CopyOnlyInt"],
86
+ )
87
+
88
+ # The extra move/copy constructions below come from the std::optional move (which has to move
89
+ # its arguments):
90
+ assert m.move_optional(10) == 10 # c_m: 1 move assign, 2 move construct
91
+ assert m.move_or_copy_optional(11) == 11 # c_mc: 1 move assign, 2 move construct
92
+ assert m.copy_optional(12) == 12 # c_c: 1 copy assign, 2 copy construct
93
+ # 1 move assign + move construct moves each of c_m, c_mc, 1 c_c copy
94
+ # +1 move/copy construct each from moving the tuple
95
+ # +1 move/copy construct each from moving the optional (which moves the tuple again)
96
+ assert m.move_optional_tuple((3, 4, 5)) == 12
97
+
98
+ assert c_m.copy_assignments + c_m.copy_constructions == 0
99
+ assert c_m.move_assignments == 2
100
+ assert c_m.move_constructions == 5
101
+ assert c_mc.copy_assignments + c_mc.copy_constructions == 0
102
+ assert c_mc.move_assignments == 2
103
+ assert c_mc.move_constructions == 5
104
+ assert c_c.copy_assignments == 2
105
+ assert c_c.copy_constructions == 5
106
+ assert c_m.alive() + c_mc.alive() + c_c.alive() == 0
107
+
108
+
109
+ def test_private_op_new():
110
+ """An object with a private `operator new` cannot be returned by value"""
111
+
112
+ with pytest.raises(RuntimeError) as excinfo:
113
+ m.private_op_new_value()
114
+ assert "is neither movable nor copyable" in str(excinfo.value)
115
+
116
+ assert m.private_op_new_reference().value == 1
117
+
118
+
119
+ def test_move_fallback():
120
+ """#389: rvp::move should fall-through to copy on non-movable objects"""
121
+
122
+ m1 = m.get_moveissue1(1)
123
+ assert m1.value == 1
124
+ m2 = m.get_moveissue2(2)
125
+ assert m2.value == 2
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_custom_type_casters.cpp ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ tests/test_custom_type_casters.cpp -- tests type_caster<T>
3
+
4
+ Copyright (c) 2016 Wenzel Jakob <[email protected]>
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)"; };
17
+ class ArgAlwaysConverts { };
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
+
30
+ static handle cast(const ArgInspector1 &src, return_value_policy, handle) {
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
+
45
+ static handle cast(const ArgInspector2 &src, return_value_policy, handle) {
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
+
57
+ static handle cast(const ArgAlwaysConverts &, return_value_policy, handle) {
58
+ return py::none().release();
59
+ }
60
+ };
61
+ } // namespace detail
62
+ } // namespace pybind11
63
+
64
+ // test_custom_caster_destruction
65
+ class DestructionTester {
66
+ public:
67
+ DestructionTester() { print_default_created(this); }
68
+ ~DestructionTester() { print_destroyed(this); }
69
+ DestructionTester(const DestructionTester &) { print_copy_created(this); }
70
+ DestructionTester(DestructionTester &&) noexcept { print_move_created(this); }
71
+ DestructionTester &operator=(const DestructionTester &) { print_copy_assigned(this); return *this; }
72
+ DestructionTester &operator=(DestructionTester &&) noexcept {
73
+ print_move_assigned(this);
74
+ return *this;
75
+ }
76
+ };
77
+ namespace pybind11 { namespace detail {
78
+ template <> struct type_caster<DestructionTester> {
79
+ PYBIND11_TYPE_CASTER(DestructionTester, _("DestructionTester"));
80
+ bool load(handle, bool) { return true; }
81
+
82
+ static handle cast(const DestructionTester &, return_value_policy, handle) {
83
+ return py::bool_(true).release();
84
+ }
85
+ };
86
+ } // namespace detail
87
+ } // namespace pybind11
88
+
89
+ TEST_SUBMODULE(custom_type_casters, m) {
90
+ // test_custom_type_casters
91
+
92
+ // test_noconvert_args
93
+ //
94
+ // Test converting. The ArgAlwaysConverts is just there to make the first no-conversion pass
95
+ // fail so that our call always ends up happening via the second dispatch (the one that allows
96
+ // some conversion).
97
+ class ArgInspector {
98
+ public:
99
+ ArgInspector1 f(ArgInspector1 a, ArgAlwaysConverts) { return a; }
100
+ std::string g(const ArgInspector1 &a,
101
+ const ArgInspector1 &b,
102
+ int c,
103
+ ArgInspector2 *d,
104
+ ArgAlwaysConverts) {
105
+ return a.arg + "\n" + b.arg + "\n" + std::to_string(c) + "\n" + d->arg;
106
+ }
107
+ static ArgInspector2 h(ArgInspector2 a, ArgAlwaysConverts) { return a; }
108
+ };
109
+ // [workaround(intel)] ICC 20/21 breaks with py::arg().stuff, using py::arg{}.stuff works.
110
+ py::class_<ArgInspector>(m, "ArgInspector")
111
+ .def(py::init<>())
112
+ .def("f", &ArgInspector::f, py::arg(), py::arg() = ArgAlwaysConverts())
113
+ .def("g", &ArgInspector::g, "a"_a.noconvert(), "b"_a, "c"_a.noconvert()=13, "d"_a=ArgInspector2(), py::arg() = ArgAlwaysConverts())
114
+ .def_static("h", &ArgInspector::h, py::arg{}.noconvert(), py::arg() = ArgAlwaysConverts())
115
+ ;
116
+ m.def(
117
+ "arg_inspect_func",
118
+ [](const ArgInspector2 &a, const ArgInspector1 &b, ArgAlwaysConverts) {
119
+ return a.arg + "\n" + b.arg;
120
+ },
121
+ py::arg{}.noconvert(false),
122
+ py::arg_v(nullptr, ArgInspector1()).noconvert(true),
123
+ py::arg() = ArgAlwaysConverts());
124
+
125
+ m.def("floats_preferred", [](double f) { return 0.5 * f; }, "f"_a);
126
+ m.def("floats_only", [](double f) { return 0.5 * f; }, "f"_a.noconvert());
127
+ m.def("ints_preferred", [](int i) { return i / 2; }, "i"_a);
128
+ m.def("ints_only", [](int i) { return i / 2; }, "i"_a.noconvert());
129
+
130
+ // test_custom_caster_destruction
131
+ // Test that `take_ownership` works on types with a custom type caster when given a pointer
132
+
133
+ // default policy: don't take ownership:
134
+ m.def("custom_caster_no_destroy", []() { static auto *dt = new DestructionTester(); return dt; });
135
+
136
+ m.def("custom_caster_destroy", []() { return new DestructionTester(); },
137
+ py::return_value_policy::take_ownership); // Takes ownership: destroy when finished
138
+ m.def("custom_caster_destroy_const", []() -> const DestructionTester * { return new DestructionTester(); },
139
+ py::return_value_policy::take_ownership); // Likewise (const doesn't inhibit destruction)
140
+ m.def("destruction_tester_cstats", &ConstructorStats::get<DestructionTester>, py::return_value_policy::reference);
141
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_custom_type_casters.py ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ import pytest
3
+ from pybind11_tests import custom_type_casters as m
4
+
5
+
6
+ def test_noconvert_args(msg):
7
+ a = m.ArgInspector()
8
+ assert (
9
+ msg(a.f("hi"))
10
+ == """
11
+ loading ArgInspector1 argument WITH conversion allowed. Argument value = hi
12
+ """
13
+ )
14
+ assert (
15
+ msg(a.g("this is a", "this is b"))
16
+ == """
17
+ loading ArgInspector1 argument WITHOUT conversion allowed. Argument value = this is a
18
+ loading ArgInspector1 argument WITH conversion allowed. Argument value = this is b
19
+ 13
20
+ loading ArgInspector2 argument WITH conversion allowed. Argument value = (default arg inspector 2)
21
+ """ # noqa: E501 line too long
22
+ )
23
+ assert (
24
+ msg(a.g("this is a", "this is b", 42))
25
+ == """
26
+ loading ArgInspector1 argument WITHOUT conversion allowed. Argument value = this is a
27
+ loading ArgInspector1 argument WITH conversion allowed. Argument value = this is b
28
+ 42
29
+ loading ArgInspector2 argument WITH conversion allowed. Argument value = (default arg inspector 2)
30
+ """ # noqa: E501 line too long
31
+ )
32
+ assert (
33
+ msg(a.g("this is a", "this is b", 42, "this is d"))
34
+ == """
35
+ loading ArgInspector1 argument WITHOUT conversion allowed. Argument value = this is a
36
+ loading ArgInspector1 argument WITH conversion allowed. Argument value = this is b
37
+ 42
38
+ loading ArgInspector2 argument WITH conversion allowed. Argument value = this is d
39
+ """
40
+ )
41
+ assert (
42
+ a.h("arg 1")
43
+ == "loading ArgInspector2 argument WITHOUT conversion allowed. Argument value = arg 1"
44
+ )
45
+ assert (
46
+ msg(m.arg_inspect_func("A1", "A2"))
47
+ == """
48
+ loading ArgInspector2 argument WITH conversion allowed. Argument value = A1
49
+ loading ArgInspector1 argument WITHOUT conversion allowed. Argument value = A2
50
+ """
51
+ )
52
+
53
+ assert m.floats_preferred(4) == 2.0
54
+ assert m.floats_only(4.0) == 2.0
55
+ with pytest.raises(TypeError) as excinfo:
56
+ m.floats_only(4)
57
+ assert (
58
+ msg(excinfo.value)
59
+ == """
60
+ floats_only(): incompatible function arguments. The following argument types are supported:
61
+ 1. (f: float) -> float
62
+
63
+ Invoked with: 4
64
+ """
65
+ )
66
+
67
+ assert m.ints_preferred(4) == 2
68
+ assert m.ints_preferred(True) == 0
69
+ with pytest.raises(TypeError) as excinfo:
70
+ m.ints_preferred(4.0)
71
+ assert (
72
+ msg(excinfo.value)
73
+ == """
74
+ ints_preferred(): incompatible function arguments. The following argument types are supported:
75
+ 1. (i: int) -> int
76
+
77
+ Invoked with: 4.0
78
+ """ # noqa: E501 line too long
79
+ )
80
+
81
+ assert m.ints_only(4) == 2
82
+ with pytest.raises(TypeError) as excinfo:
83
+ m.ints_only(4.0)
84
+ assert (
85
+ msg(excinfo.value)
86
+ == """
87
+ ints_only(): incompatible function arguments. The following argument types are supported:
88
+ 1. (i: int) -> int
89
+
90
+ Invoked with: 4.0
91
+ """
92
+ )
93
+
94
+
95
+ def test_custom_caster_destruction():
96
+ """Tests that returning a pointer to a type that gets converted with a custom type caster gets
97
+ destroyed when the function has py::return_value_policy::take_ownership policy applied."""
98
+
99
+ cstats = m.destruction_tester_cstats()
100
+ # This one *doesn't* have take_ownership: the pointer should be used but not destroyed:
101
+ z = m.custom_caster_no_destroy()
102
+ assert cstats.alive() == 1 and cstats.default_constructions == 1
103
+ assert z
104
+
105
+ # take_ownership applied: this constructs a new object, casts it, then destroys it:
106
+ z = m.custom_caster_destroy()
107
+ assert z
108
+ assert cstats.default_constructions == 2
109
+
110
+ # Same, but with a const pointer return (which should *not* inhibit destruction):
111
+ z = m.custom_caster_destroy_const()
112
+ assert z
113
+ assert cstats.default_constructions == 3
114
+
115
+ # Make sure we still only have the original object (from ..._no_destroy()) alive:
116
+ assert cstats.alive() == 1
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_docstring_options.cpp ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ tests/test_docstring_options.cpp -- generation of docstrings and signatures
3
+
4
+ Copyright (c) 2016 Wenzel Jakob <[email protected]>
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
+
12
+ TEST_SUBMODULE(docstring_options, m) {
13
+ // test_docstring_options
14
+ {
15
+ py::options options;
16
+ options.disable_function_signatures();
17
+
18
+ m.def("test_function1", [](int, int) {}, py::arg("a"), py::arg("b"));
19
+ m.def("test_function2", [](int, int) {}, py::arg("a"), py::arg("b"), "A custom docstring");
20
+
21
+ m.def("test_overloaded1", [](int) {}, py::arg("i"), "Overload docstring");
22
+ m.def("test_overloaded1", [](double) {}, py::arg("d"));
23
+
24
+ m.def("test_overloaded2", [](int) {}, py::arg("i"), "overload docstring 1");
25
+ m.def("test_overloaded2", [](double) {}, py::arg("d"), "overload docstring 2");
26
+
27
+ m.def("test_overloaded3", [](int) {}, py::arg("i"));
28
+ m.def("test_overloaded3", [](double) {}, py::arg("d"), "Overload docstr");
29
+
30
+ options.enable_function_signatures();
31
+
32
+ m.def("test_function3", [](int, int) {}, py::arg("a"), py::arg("b"));
33
+ m.def("test_function4", [](int, int) {}, py::arg("a"), py::arg("b"), "A custom docstring");
34
+
35
+ options.disable_function_signatures().disable_user_defined_docstrings();
36
+
37
+ m.def("test_function5", [](int, int) {}, py::arg("a"), py::arg("b"), "A custom docstring");
38
+
39
+ {
40
+ py::options nested_options;
41
+ nested_options.enable_user_defined_docstrings();
42
+ m.def("test_function6", [](int, int) {}, py::arg("a"), py::arg("b"), "A custom docstring");
43
+ }
44
+ }
45
+
46
+ m.def("test_function7", [](int, int) {}, py::arg("a"), py::arg("b"), "A custom docstring");
47
+
48
+ {
49
+ py::options options;
50
+ options.disable_user_defined_docstrings();
51
+ options.disable_function_signatures();
52
+
53
+ m.def("test_function8", []() {});
54
+ }
55
+
56
+ {
57
+ py::options options;
58
+ options.disable_user_defined_docstrings();
59
+
60
+ struct DocstringTestFoo {
61
+ int value;
62
+ void setValue(int v) { value = v; }
63
+ int getValue() const { return value; }
64
+ };
65
+ py::class_<DocstringTestFoo>(m, "DocstringTestFoo", "This is a class docstring")
66
+ .def_property("value_prop", &DocstringTestFoo::getValue, &DocstringTestFoo::setValue, "This is a property docstring")
67
+ ;
68
+ }
69
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_docstring_options.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ from pybind11_tests import docstring_options as m
3
+
4
+
5
+ def test_docstring_options():
6
+ # options.disable_function_signatures()
7
+ assert not m.test_function1.__doc__
8
+
9
+ assert m.test_function2.__doc__ == "A custom docstring"
10
+
11
+ # docstring specified on just the first overload definition:
12
+ assert m.test_overloaded1.__doc__ == "Overload docstring"
13
+
14
+ # docstring on both overloads:
15
+ assert m.test_overloaded2.__doc__ == "overload docstring 1\noverload docstring 2"
16
+
17
+ # docstring on only second overload:
18
+ assert m.test_overloaded3.__doc__ == "Overload docstr"
19
+
20
+ # options.enable_function_signatures()
21
+ assert m.test_function3.__doc__.startswith("test_function3(a: int, b: int) -> None")
22
+
23
+ assert m.test_function4.__doc__.startswith("test_function4(a: int, b: int) -> None")
24
+ assert m.test_function4.__doc__.endswith("A custom docstring\n")
25
+
26
+ # options.disable_function_signatures()
27
+ # options.disable_user_defined_docstrings()
28
+ assert not m.test_function5.__doc__
29
+
30
+ # nested options.enable_user_defined_docstrings()
31
+ assert m.test_function6.__doc__ == "A custom docstring"
32
+
33
+ # RAII destructor
34
+ assert m.test_function7.__doc__.startswith("test_function7(a: int, b: int) -> None")
35
+ assert m.test_function7.__doc__.endswith("A custom docstring\n")
36
+
37
+ # when all options are disabled, no docstring (instead of an empty one) should be generated
38
+ assert m.test_function8.__doc__ is None
39
+
40
+ # Suppression of user-defined docstrings for non-function objects
41
+ assert not m.DocstringTestFoo.__doc__
42
+ assert not m.DocstringTestFoo.value_prop.__doc__
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_eigen.cpp ADDED
@@ -0,0 +1,341 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ tests/eigen.cpp -- automatic conversion of Eigen types
3
+
4
+ Copyright (c) 2016 Wenzel Jakob <[email protected]>
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
+ #include <pybind11/eigen.h>
13
+ #include <pybind11/stl.h>
14
+
15
+ #if defined(_MSC_VER)
16
+ # pragma warning(disable: 4996) // C4996: std::unary_negation is deprecated
17
+ #endif
18
+
19
+ #include <Eigen/Cholesky>
20
+
21
+ using MatrixXdR = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
22
+
23
+
24
+
25
+ // Sets/resets a testing reference matrix to have values of 10*r + c, where r and c are the
26
+ // (1-based) row/column number.
27
+ template <typename M> void reset_ref(M &x) {
28
+ for (int i = 0; i < x.rows(); i++) for (int j = 0; j < x.cols(); j++)
29
+ x(i, j) = 11 + 10*i + j;
30
+ }
31
+
32
+ // Returns a static, column-major matrix
33
+ Eigen::MatrixXd &get_cm() {
34
+ static Eigen::MatrixXd *x;
35
+ if (!x) {
36
+ x = new Eigen::MatrixXd(3, 3);
37
+ reset_ref(*x);
38
+ }
39
+ return *x;
40
+ }
41
+ // Likewise, but row-major
42
+ MatrixXdR &get_rm() {
43
+ static MatrixXdR *x;
44
+ if (!x) {
45
+ x = new MatrixXdR(3, 3);
46
+ reset_ref(*x);
47
+ }
48
+ return *x;
49
+ }
50
+ // Resets the values of the static matrices returned by get_cm()/get_rm()
51
+ void reset_refs() {
52
+ reset_ref(get_cm());
53
+ reset_ref(get_rm());
54
+ }
55
+
56
+ // Returns element 2,1 from a matrix (used to test copy/nocopy)
57
+ double get_elem(const Eigen::Ref<const Eigen::MatrixXd> &m) { return m(2, 1); };
58
+
59
+ // Returns a matrix with 10*r + 100*c added to each matrix element (to help test that the matrix
60
+ // reference is referencing rows/columns correctly).
61
+ template <typename MatrixArgType> Eigen::MatrixXd adjust_matrix(MatrixArgType m) {
62
+ Eigen::MatrixXd ret(m);
63
+ for (int c = 0; c < m.cols(); c++)
64
+ for (int r = 0; r < m.rows(); r++)
65
+ ret(r, c) += 10*r + 100*c; // NOLINT(clang-analyzer-core.uninitialized.Assign)
66
+ return ret;
67
+ }
68
+
69
+ struct CustomOperatorNew {
70
+ CustomOperatorNew() = default;
71
+
72
+ Eigen::Matrix4d a = Eigen::Matrix4d::Zero();
73
+ Eigen::Matrix4d b = Eigen::Matrix4d::Identity();
74
+
75
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
76
+ };
77
+
78
+ TEST_SUBMODULE(eigen, m) {
79
+ using FixedMatrixR = Eigen::Matrix<float, 5, 6, Eigen::RowMajor>;
80
+ using FixedMatrixC = Eigen::Matrix<float, 5, 6>;
81
+ using DenseMatrixR = Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
82
+ using DenseMatrixC = Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic>;
83
+ using FourRowMatrixC = Eigen::Matrix<float, 4, Eigen::Dynamic>;
84
+ using FourColMatrixC = Eigen::Matrix<float, Eigen::Dynamic, 4>;
85
+ using FourRowMatrixR = Eigen::Matrix<float, 4, Eigen::Dynamic>;
86
+ using FourColMatrixR = Eigen::Matrix<float, Eigen::Dynamic, 4>;
87
+ using SparseMatrixR = Eigen::SparseMatrix<float, Eigen::RowMajor>;
88
+ using SparseMatrixC = Eigen::SparseMatrix<float>;
89
+
90
+ // various tests
91
+ m.def("double_col", [](const Eigen::VectorXf &x) -> Eigen::VectorXf { return 2.0f * x; });
92
+ m.def("double_row", [](const Eigen::RowVectorXf &x) -> Eigen::RowVectorXf { return 2.0f * x; });
93
+ m.def("double_complex", [](const Eigen::VectorXcf &x) -> Eigen::VectorXcf { return 2.0f * x; });
94
+ m.def("double_threec", [](py::EigenDRef<Eigen::Vector3f> x) { x *= 2; });
95
+ m.def("double_threer", [](py::EigenDRef<Eigen::RowVector3f> x) { x *= 2; });
96
+ m.def("double_mat_cm", [](const Eigen::MatrixXf &x) -> Eigen::MatrixXf { return 2.0f * x; });
97
+ m.def("double_mat_rm", [](const DenseMatrixR &x) -> DenseMatrixR { return 2.0f * x; });
98
+
99
+ // test_eigen_ref_to_python
100
+ // Different ways of passing via Eigen::Ref; the first and second are the Eigen-recommended
101
+ m.def("cholesky1",
102
+ [](const Eigen::Ref<MatrixXdR> &x) -> Eigen::MatrixXd { return x.llt().matrixL(); });
103
+ m.def("cholesky2", [](const Eigen::Ref<const MatrixXdR> &x) -> Eigen::MatrixXd { return x.llt().matrixL(); });
104
+ m.def("cholesky3", [](const Eigen::Ref<MatrixXdR> &x) -> Eigen::MatrixXd { return x.llt().matrixL(); });
105
+ m.def("cholesky4", [](const Eigen::Ref<const MatrixXdR> &x) -> Eigen::MatrixXd {
106
+ return x.llt().matrixL();
107
+ });
108
+
109
+ // test_eigen_ref_mutators
110
+ // Mutators: these add some value to the given element using Eigen, but Eigen should be mapping into
111
+ // the numpy array data and so the result should show up there. There are three versions: one that
112
+ // works on a contiguous-row matrix (numpy's default), one for a contiguous-column matrix, and one
113
+ // for any matrix.
114
+ auto add_rm = [](Eigen::Ref<MatrixXdR> x, int r, int c, double v) { x(r,c) += v; };
115
+ auto add_cm = [](Eigen::Ref<Eigen::MatrixXd> x, int r, int c, double v) { x(r,c) += v; };
116
+
117
+ // Mutators (Eigen maps into numpy variables):
118
+ m.def("add_rm", add_rm); // Only takes row-contiguous
119
+ m.def("add_cm", add_cm); // Only takes column-contiguous
120
+ // Overloaded versions that will accept either row or column contiguous:
121
+ m.def("add1", add_rm);
122
+ m.def("add1", add_cm);
123
+ m.def("add2", add_cm);
124
+ m.def("add2", add_rm);
125
+ // This one accepts a matrix of any stride:
126
+ m.def("add_any", [](py::EigenDRef<Eigen::MatrixXd> x, int r, int c, double v) { x(r,c) += v; });
127
+
128
+ // Return mutable references (numpy maps into eigen variables)
129
+ m.def("get_cm_ref", []() { return Eigen::Ref<Eigen::MatrixXd>(get_cm()); });
130
+ m.def("get_rm_ref", []() { return Eigen::Ref<MatrixXdR>(get_rm()); });
131
+ // The same references, but non-mutable (numpy maps into eigen variables, but is !writeable)
132
+ m.def("get_cm_const_ref", []() { return Eigen::Ref<const Eigen::MatrixXd>(get_cm()); });
133
+ m.def("get_rm_const_ref", []() { return Eigen::Ref<const MatrixXdR>(get_rm()); });
134
+
135
+ m.def("reset_refs", reset_refs); // Restores get_{cm,rm}_ref to original values
136
+
137
+ // Increments and returns ref to (same) matrix
138
+ m.def("incr_matrix", [](Eigen::Ref<Eigen::MatrixXd> m, double v) {
139
+ m += Eigen::MatrixXd::Constant(m.rows(), m.cols(), v);
140
+ return m;
141
+ }, py::return_value_policy::reference);
142
+
143
+ // Same, but accepts a matrix of any strides
144
+ m.def("incr_matrix_any", [](py::EigenDRef<Eigen::MatrixXd> m, double v) {
145
+ m += Eigen::MatrixXd::Constant(m.rows(), m.cols(), v);
146
+ return m;
147
+ }, py::return_value_policy::reference);
148
+
149
+ // Returns an eigen slice of even rows
150
+ m.def("even_rows", [](py::EigenDRef<Eigen::MatrixXd> m) {
151
+ return py::EigenDMap<Eigen::MatrixXd>(
152
+ m.data(), (m.rows() + 1) / 2, m.cols(),
153
+ py::EigenDStride(m.outerStride(), 2 * m.innerStride()));
154
+ }, py::return_value_policy::reference);
155
+
156
+ // Returns an eigen slice of even columns
157
+ m.def("even_cols", [](py::EigenDRef<Eigen::MatrixXd> m) {
158
+ return py::EigenDMap<Eigen::MatrixXd>(
159
+ m.data(), m.rows(), (m.cols() + 1) / 2,
160
+ py::EigenDStride(2 * m.outerStride(), m.innerStride()));
161
+ }, py::return_value_policy::reference);
162
+
163
+ // Returns diagonals: a vector-like object with an inner stride != 1
164
+ m.def("diagonal", [](const Eigen::Ref<const Eigen::MatrixXd> &x) { return x.diagonal(); });
165
+ m.def("diagonal_1", [](const Eigen::Ref<const Eigen::MatrixXd> &x) { return x.diagonal<1>(); });
166
+ m.def("diagonal_n", [](const Eigen::Ref<const Eigen::MatrixXd> &x, int index) { return x.diagonal(index); });
167
+
168
+ // Return a block of a matrix (gives non-standard strides)
169
+ m.def("block", [](const Eigen::Ref<const Eigen::MatrixXd> &x, int start_row, int start_col, int block_rows, int block_cols) {
170
+ return x.block(start_row, start_col, block_rows, block_cols);
171
+ });
172
+
173
+ // test_eigen_return_references, test_eigen_keepalive
174
+ // return value referencing/copying tests:
175
+ class ReturnTester {
176
+ Eigen::MatrixXd mat = create();
177
+ public:
178
+ ReturnTester() { print_created(this); }
179
+ ~ReturnTester() { print_destroyed(this); }
180
+ static Eigen::MatrixXd create() { return Eigen::MatrixXd::Ones(10, 10); }
181
+ static const Eigen::MatrixXd createConst() { return Eigen::MatrixXd::Ones(10, 10); }
182
+ Eigen::MatrixXd &get() { return mat; }
183
+ Eigen::MatrixXd *getPtr() { return &mat; }
184
+ const Eigen::MatrixXd &view() { return mat; }
185
+ const Eigen::MatrixXd *viewPtr() { return &mat; }
186
+ Eigen::Ref<Eigen::MatrixXd> ref() { return mat; }
187
+ Eigen::Ref<const Eigen::MatrixXd> refConst() { return mat; }
188
+ Eigen::Block<Eigen::MatrixXd> block(int r, int c, int nrow, int ncol) { return mat.block(r, c, nrow, ncol); }
189
+ Eigen::Block<const Eigen::MatrixXd> blockConst(int r, int c, int nrow, int ncol) const { return mat.block(r, c, nrow, ncol); }
190
+ py::EigenDMap<Eigen::Matrix2d> corners() { return py::EigenDMap<Eigen::Matrix2d>(mat.data(),
191
+ py::EigenDStride(mat.outerStride() * (mat.outerSize()-1), mat.innerStride() * (mat.innerSize()-1))); }
192
+ py::EigenDMap<const Eigen::Matrix2d> cornersConst() const { return py::EigenDMap<const Eigen::Matrix2d>(mat.data(),
193
+ py::EigenDStride(mat.outerStride() * (mat.outerSize()-1), mat.innerStride() * (mat.innerSize()-1))); }
194
+ };
195
+ using rvp = py::return_value_policy;
196
+ py::class_<ReturnTester>(m, "ReturnTester")
197
+ .def(py::init<>())
198
+ .def_static("create", &ReturnTester::create)
199
+ .def_static("create_const", &ReturnTester::createConst)
200
+ .def("get", &ReturnTester::get, rvp::reference_internal)
201
+ .def("get_ptr", &ReturnTester::getPtr, rvp::reference_internal)
202
+ .def("view", &ReturnTester::view, rvp::reference_internal)
203
+ .def("view_ptr", &ReturnTester::view, rvp::reference_internal)
204
+ .def("copy_get", &ReturnTester::get) // Default rvp: copy
205
+ .def("copy_view", &ReturnTester::view) // "
206
+ .def("ref", &ReturnTester::ref) // Default for Ref is to reference
207
+ .def("ref_const", &ReturnTester::refConst) // Likewise, but const
208
+ .def("ref_safe", &ReturnTester::ref, rvp::reference_internal)
209
+ .def("ref_const_safe", &ReturnTester::refConst, rvp::reference_internal)
210
+ .def("copy_ref", &ReturnTester::ref, rvp::copy)
211
+ .def("copy_ref_const", &ReturnTester::refConst, rvp::copy)
212
+ .def("block", &ReturnTester::block)
213
+ .def("block_safe", &ReturnTester::block, rvp::reference_internal)
214
+ .def("block_const", &ReturnTester::blockConst, rvp::reference_internal)
215
+ .def("copy_block", &ReturnTester::block, rvp::copy)
216
+ .def("corners", &ReturnTester::corners, rvp::reference_internal)
217
+ .def("corners_const", &ReturnTester::cornersConst, rvp::reference_internal)
218
+ ;
219
+
220
+ // test_special_matrix_objects
221
+ // Returns a DiagonalMatrix with diagonal (1,2,3,...)
222
+ m.def("incr_diag", [](int k) {
223
+ Eigen::DiagonalMatrix<int, Eigen::Dynamic> m(k);
224
+ for (int i = 0; i < k; i++) m.diagonal()[i] = i+1;
225
+ return m;
226
+ });
227
+
228
+ // Returns a SelfAdjointView referencing the lower triangle of m
229
+ m.def("symmetric_lower", [](const Eigen::MatrixXi &m) {
230
+ return m.selfadjointView<Eigen::Lower>();
231
+ });
232
+ // Returns a SelfAdjointView referencing the lower triangle of m
233
+ m.def("symmetric_upper", [](const Eigen::MatrixXi &m) {
234
+ return m.selfadjointView<Eigen::Upper>();
235
+ });
236
+
237
+ // Test matrix for various functions below.
238
+ Eigen::MatrixXf mat(5, 6);
239
+ mat << 0, 3, 0, 0, 0, 11,
240
+ 22, 0, 0, 0, 17, 11,
241
+ 7, 5, 0, 1, 0, 11,
242
+ 0, 0, 0, 0, 0, 11,
243
+ 0, 0, 14, 0, 8, 11;
244
+
245
+ // test_fixed, and various other tests
246
+ m.def("fixed_r", [mat]() -> FixedMatrixR { return FixedMatrixR(mat); });
247
+ m.def("fixed_r_const", [mat]() -> const FixedMatrixR { return FixedMatrixR(mat); });
248
+ m.def("fixed_c", [mat]() -> FixedMatrixC { return FixedMatrixC(mat); });
249
+ m.def("fixed_copy_r", [](const FixedMatrixR &m) -> FixedMatrixR { return m; });
250
+ m.def("fixed_copy_c", [](const FixedMatrixC &m) -> FixedMatrixC { return m; });
251
+ // test_mutator_descriptors
252
+ m.def("fixed_mutator_r", [](const Eigen::Ref<FixedMatrixR> &) {});
253
+ m.def("fixed_mutator_c", [](const Eigen::Ref<FixedMatrixC> &) {});
254
+ m.def("fixed_mutator_a", [](const py::EigenDRef<FixedMatrixC> &) {});
255
+ // test_dense
256
+ m.def("dense_r", [mat]() -> DenseMatrixR { return DenseMatrixR(mat); });
257
+ m.def("dense_c", [mat]() -> DenseMatrixC { return DenseMatrixC(mat); });
258
+ m.def("dense_copy_r", [](const DenseMatrixR &m) -> DenseMatrixR { return m; });
259
+ m.def("dense_copy_c", [](const DenseMatrixC &m) -> DenseMatrixC { return m; });
260
+ // test_sparse, test_sparse_signature
261
+ m.def("sparse_r", [mat]() -> SparseMatrixR {
262
+ // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
263
+ return Eigen::SparseView<Eigen::MatrixXf>(mat);
264
+ });
265
+ m.def("sparse_c", [mat]() -> SparseMatrixC { return Eigen::SparseView<Eigen::MatrixXf>(mat); });
266
+ m.def("sparse_copy_r", [](const SparseMatrixR &m) -> SparseMatrixR { return m; });
267
+ m.def("sparse_copy_c", [](const SparseMatrixC &m) -> SparseMatrixC { return m; });
268
+ // test_partially_fixed
269
+ m.def("partial_copy_four_rm_r", [](const FourRowMatrixR &m) -> FourRowMatrixR { return m; });
270
+ m.def("partial_copy_four_rm_c", [](const FourColMatrixR &m) -> FourColMatrixR { return m; });
271
+ m.def("partial_copy_four_cm_r", [](const FourRowMatrixC &m) -> FourRowMatrixC { return m; });
272
+ m.def("partial_copy_four_cm_c", [](const FourColMatrixC &m) -> FourColMatrixC { return m; });
273
+
274
+ // test_cpp_casting
275
+ // Test that we can cast a numpy object to a Eigen::MatrixXd explicitly
276
+ m.def("cpp_copy", [](py::handle m) { return m.cast<Eigen::MatrixXd>()(1, 0); });
277
+ m.def("cpp_ref_c", [](py::handle m) { return m.cast<Eigen::Ref<Eigen::MatrixXd>>()(1, 0); });
278
+ m.def("cpp_ref_r", [](py::handle m) { return m.cast<Eigen::Ref<MatrixXdR>>()(1, 0); });
279
+ m.def("cpp_ref_any", [](py::handle m) { return m.cast<py::EigenDRef<Eigen::MatrixXd>>()(1, 0); });
280
+
281
+ // [workaround(intel)] ICC 20/21 breaks with py::arg().stuff, using py::arg{}.stuff works.
282
+
283
+ // test_nocopy_wrapper
284
+ // Test that we can prevent copying into an argument that would normally copy: First a version
285
+ // that would allow copying (if types or strides don't match) for comparison:
286
+ m.def("get_elem", &get_elem);
287
+ // Now this alternative that calls the tells pybind to fail rather than copy:
288
+ m.def(
289
+ "get_elem_nocopy",
290
+ [](const Eigen::Ref<const Eigen::MatrixXd> &m) -> double { return get_elem(m); },
291
+ py::arg{}.noconvert());
292
+ // Also test a row-major-only no-copy const ref:
293
+ m.def("get_elem_rm_nocopy", [](Eigen::Ref<const Eigen::Matrix<long, -1, -1, Eigen::RowMajor>> &m) -> long { return m(2, 1); },
294
+ py::arg{}.noconvert());
295
+
296
+ // test_issue738
297
+ // Issue #738: 1xN or Nx1 2D matrices were neither accepted nor properly copied with an
298
+ // incompatible stride value on the length-1 dimension--but that should be allowed (without
299
+ // requiring a copy!) because the stride value can be safely ignored on a size-1 dimension.
300
+ m.def("iss738_f1", &adjust_matrix<const Eigen::Ref<const Eigen::MatrixXd> &>, py::arg{}.noconvert());
301
+ m.def("iss738_f2", &adjust_matrix<const Eigen::Ref<const Eigen::Matrix<double, -1, -1, Eigen::RowMajor>> &>, py::arg{}.noconvert());
302
+
303
+ // test_issue1105
304
+ // Issue #1105: when converting from a numpy two-dimensional (Nx1) or (1xN) value into a dense
305
+ // eigen Vector or RowVector, the argument would fail to load because the numpy copy would
306
+ // fail: numpy won't broadcast a Nx1 into a 1-dimensional vector.
307
+ m.def("iss1105_col", [](const Eigen::VectorXd &) { return true; });
308
+ m.def("iss1105_row", [](const Eigen::RowVectorXd &) { return true; });
309
+
310
+ // test_named_arguments
311
+ // Make sure named arguments are working properly:
312
+ m.def(
313
+ "matrix_multiply",
314
+ [](const py::EigenDRef<const Eigen::MatrixXd> &A,
315
+ const py::EigenDRef<const Eigen::MatrixXd> &B) -> Eigen::MatrixXd {
316
+ if (A.cols() != B.rows())
317
+ throw std::domain_error("Nonconformable matrices!");
318
+ return A * B;
319
+ },
320
+ py::arg("A"),
321
+ py::arg("B"));
322
+
323
+ // test_custom_operator_new
324
+ py::class_<CustomOperatorNew>(m, "CustomOperatorNew")
325
+ .def(py::init<>())
326
+ .def_readonly("a", &CustomOperatorNew::a)
327
+ .def_readonly("b", &CustomOperatorNew::b);
328
+
329
+ // test_eigen_ref_life_support
330
+ // In case of a failure (the caster's temp array does not live long enough), creating
331
+ // a new array (np.ones(10)) increases the chances that the temp array will be garbage
332
+ // collected and/or that its memory will be overridden with different values.
333
+ m.def("get_elem_direct", [](const Eigen::Ref<const Eigen::VectorXd> &v) {
334
+ py::module_::import("numpy").attr("ones")(10);
335
+ return v(5);
336
+ });
337
+ m.def("get_elem_indirect", [](std::vector<Eigen::Ref<const Eigen::VectorXd>> v) {
338
+ py::module_::import("numpy").attr("ones")(10);
339
+ return v[0](5);
340
+ });
341
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_eigen.py ADDED
@@ -0,0 +1,770 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ import pytest
3
+ from pybind11_tests import ConstructorStats
4
+
5
+ np = pytest.importorskip("numpy")
6
+ m = pytest.importorskip("pybind11_tests.eigen")
7
+
8
+
9
+ ref = np.array(
10
+ [
11
+ [0.0, 3, 0, 0, 0, 11],
12
+ [22, 0, 0, 0, 17, 11],
13
+ [7, 5, 0, 1, 0, 11],
14
+ [0, 0, 0, 0, 0, 11],
15
+ [0, 0, 14, 0, 8, 11],
16
+ ]
17
+ )
18
+
19
+
20
+ def assert_equal_ref(mat):
21
+ np.testing.assert_array_equal(mat, ref)
22
+
23
+
24
+ def assert_sparse_equal_ref(sparse_mat):
25
+ assert_equal_ref(sparse_mat.toarray())
26
+
27
+
28
+ def test_fixed():
29
+ assert_equal_ref(m.fixed_c())
30
+ assert_equal_ref(m.fixed_r())
31
+ assert_equal_ref(m.fixed_copy_r(m.fixed_r()))
32
+ assert_equal_ref(m.fixed_copy_c(m.fixed_c()))
33
+ assert_equal_ref(m.fixed_copy_r(m.fixed_c()))
34
+ assert_equal_ref(m.fixed_copy_c(m.fixed_r()))
35
+
36
+
37
+ def test_dense():
38
+ assert_equal_ref(m.dense_r())
39
+ assert_equal_ref(m.dense_c())
40
+ assert_equal_ref(m.dense_copy_r(m.dense_r()))
41
+ assert_equal_ref(m.dense_copy_c(m.dense_c()))
42
+ assert_equal_ref(m.dense_copy_r(m.dense_c()))
43
+ assert_equal_ref(m.dense_copy_c(m.dense_r()))
44
+
45
+
46
+ def test_partially_fixed():
47
+ ref2 = np.array([[0.0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]])
48
+ np.testing.assert_array_equal(m.partial_copy_four_rm_r(ref2), ref2)
49
+ np.testing.assert_array_equal(m.partial_copy_four_rm_c(ref2), ref2)
50
+ np.testing.assert_array_equal(m.partial_copy_four_rm_r(ref2[:, 1]), ref2[:, [1]])
51
+ np.testing.assert_array_equal(m.partial_copy_four_rm_c(ref2[0, :]), ref2[[0], :])
52
+ np.testing.assert_array_equal(
53
+ m.partial_copy_four_rm_r(ref2[:, (0, 2)]), ref2[:, (0, 2)]
54
+ )
55
+ np.testing.assert_array_equal(
56
+ m.partial_copy_four_rm_c(ref2[(3, 1, 2), :]), ref2[(3, 1, 2), :]
57
+ )
58
+
59
+ np.testing.assert_array_equal(m.partial_copy_four_cm_r(ref2), ref2)
60
+ np.testing.assert_array_equal(m.partial_copy_four_cm_c(ref2), ref2)
61
+ np.testing.assert_array_equal(m.partial_copy_four_cm_r(ref2[:, 1]), ref2[:, [1]])
62
+ np.testing.assert_array_equal(m.partial_copy_four_cm_c(ref2[0, :]), ref2[[0], :])
63
+ np.testing.assert_array_equal(
64
+ m.partial_copy_four_cm_r(ref2[:, (0, 2)]), ref2[:, (0, 2)]
65
+ )
66
+ np.testing.assert_array_equal(
67
+ m.partial_copy_four_cm_c(ref2[(3, 1, 2), :]), ref2[(3, 1, 2), :]
68
+ )
69
+
70
+ # TypeError should be raise for a shape mismatch
71
+ functions = [
72
+ m.partial_copy_four_rm_r,
73
+ m.partial_copy_four_rm_c,
74
+ m.partial_copy_four_cm_r,
75
+ m.partial_copy_four_cm_c,
76
+ ]
77
+ matrix_with_wrong_shape = [[1, 2], [3, 4]]
78
+ for f in functions:
79
+ with pytest.raises(TypeError) as excinfo:
80
+ f(matrix_with_wrong_shape)
81
+ assert "incompatible function arguments" in str(excinfo.value)
82
+
83
+
84
+ def test_mutator_descriptors():
85
+ zr = np.arange(30, dtype="float32").reshape(5, 6) # row-major
86
+ zc = zr.reshape(6, 5).transpose() # column-major
87
+
88
+ m.fixed_mutator_r(zr)
89
+ m.fixed_mutator_c(zc)
90
+ m.fixed_mutator_a(zr)
91
+ m.fixed_mutator_a(zc)
92
+ with pytest.raises(TypeError) as excinfo:
93
+ m.fixed_mutator_r(zc)
94
+ assert (
95
+ "(arg0: numpy.ndarray[numpy.float32[5, 6],"
96
+ " flags.writeable, flags.c_contiguous]) -> None" in str(excinfo.value)
97
+ )
98
+ with pytest.raises(TypeError) as excinfo:
99
+ m.fixed_mutator_c(zr)
100
+ assert (
101
+ "(arg0: numpy.ndarray[numpy.float32[5, 6],"
102
+ " flags.writeable, flags.f_contiguous]) -> None" in str(excinfo.value)
103
+ )
104
+ with pytest.raises(TypeError) as excinfo:
105
+ m.fixed_mutator_a(np.array([[1, 2], [3, 4]], dtype="float32"))
106
+ assert "(arg0: numpy.ndarray[numpy.float32[5, 6], flags.writeable]) -> None" in str(
107
+ excinfo.value
108
+ )
109
+ zr.flags.writeable = False
110
+ with pytest.raises(TypeError):
111
+ m.fixed_mutator_r(zr)
112
+ with pytest.raises(TypeError):
113
+ m.fixed_mutator_a(zr)
114
+
115
+
116
+ def test_cpp_casting():
117
+ assert m.cpp_copy(m.fixed_r()) == 22.0
118
+ assert m.cpp_copy(m.fixed_c()) == 22.0
119
+ z = np.array([[5.0, 6], [7, 8]])
120
+ assert m.cpp_copy(z) == 7.0
121
+ assert m.cpp_copy(m.get_cm_ref()) == 21.0
122
+ assert m.cpp_copy(m.get_rm_ref()) == 21.0
123
+ assert m.cpp_ref_c(m.get_cm_ref()) == 21.0
124
+ assert m.cpp_ref_r(m.get_rm_ref()) == 21.0
125
+ with pytest.raises(RuntimeError) as excinfo:
126
+ # Can't reference m.fixed_c: it contains floats, m.cpp_ref_any wants doubles
127
+ m.cpp_ref_any(m.fixed_c())
128
+ assert "Unable to cast Python instance" in str(excinfo.value)
129
+ with pytest.raises(RuntimeError) as excinfo:
130
+ # Can't reference m.fixed_r: it contains floats, m.cpp_ref_any wants doubles
131
+ m.cpp_ref_any(m.fixed_r())
132
+ assert "Unable to cast Python instance" in str(excinfo.value)
133
+ assert m.cpp_ref_any(m.ReturnTester.create()) == 1.0
134
+
135
+ assert m.cpp_ref_any(m.get_cm_ref()) == 21.0
136
+ assert m.cpp_ref_any(m.get_cm_ref()) == 21.0
137
+
138
+
139
+ def test_pass_readonly_array():
140
+ z = np.full((5, 6), 42.0)
141
+ z.flags.writeable = False
142
+ np.testing.assert_array_equal(z, m.fixed_copy_r(z))
143
+ np.testing.assert_array_equal(m.fixed_r_const(), m.fixed_r())
144
+ assert not m.fixed_r_const().flags.writeable
145
+ np.testing.assert_array_equal(m.fixed_copy_r(m.fixed_r_const()), m.fixed_r_const())
146
+
147
+
148
+ def test_nonunit_stride_from_python():
149
+ counting_mat = np.arange(9.0, dtype=np.float32).reshape((3, 3))
150
+ second_row = counting_mat[1, :]
151
+ second_col = counting_mat[:, 1]
152
+ np.testing.assert_array_equal(m.double_row(second_row), 2.0 * second_row)
153
+ np.testing.assert_array_equal(m.double_col(second_row), 2.0 * second_row)
154
+ np.testing.assert_array_equal(m.double_complex(second_row), 2.0 * second_row)
155
+ np.testing.assert_array_equal(m.double_row(second_col), 2.0 * second_col)
156
+ np.testing.assert_array_equal(m.double_col(second_col), 2.0 * second_col)
157
+ np.testing.assert_array_equal(m.double_complex(second_col), 2.0 * second_col)
158
+
159
+ counting_3d = np.arange(27.0, dtype=np.float32).reshape((3, 3, 3))
160
+ slices = [counting_3d[0, :, :], counting_3d[:, 0, :], counting_3d[:, :, 0]]
161
+ for ref_mat in slices:
162
+ np.testing.assert_array_equal(m.double_mat_cm(ref_mat), 2.0 * ref_mat)
163
+ np.testing.assert_array_equal(m.double_mat_rm(ref_mat), 2.0 * ref_mat)
164
+
165
+ # Mutator:
166
+ m.double_threer(second_row)
167
+ m.double_threec(second_col)
168
+ np.testing.assert_array_equal(counting_mat, [[0.0, 2, 2], [6, 16, 10], [6, 14, 8]])
169
+
170
+
171
+ def test_negative_stride_from_python(msg):
172
+ """Eigen doesn't support (as of yet) negative strides. When a function takes an Eigen matrix by
173
+ copy or const reference, we can pass a numpy array that has negative strides. Otherwise, an
174
+ exception will be thrown as Eigen will not be able to map the numpy array."""
175
+
176
+ counting_mat = np.arange(9.0, dtype=np.float32).reshape((3, 3))
177
+ counting_mat = counting_mat[::-1, ::-1]
178
+ second_row = counting_mat[1, :]
179
+ second_col = counting_mat[:, 1]
180
+ np.testing.assert_array_equal(m.double_row(second_row), 2.0 * second_row)
181
+ np.testing.assert_array_equal(m.double_col(second_row), 2.0 * second_row)
182
+ np.testing.assert_array_equal(m.double_complex(second_row), 2.0 * second_row)
183
+ np.testing.assert_array_equal(m.double_row(second_col), 2.0 * second_col)
184
+ np.testing.assert_array_equal(m.double_col(second_col), 2.0 * second_col)
185
+ np.testing.assert_array_equal(m.double_complex(second_col), 2.0 * second_col)
186
+
187
+ counting_3d = np.arange(27.0, dtype=np.float32).reshape((3, 3, 3))
188
+ counting_3d = counting_3d[::-1, ::-1, ::-1]
189
+ slices = [counting_3d[0, :, :], counting_3d[:, 0, :], counting_3d[:, :, 0]]
190
+ for ref_mat in slices:
191
+ np.testing.assert_array_equal(m.double_mat_cm(ref_mat), 2.0 * ref_mat)
192
+ np.testing.assert_array_equal(m.double_mat_rm(ref_mat), 2.0 * ref_mat)
193
+
194
+ # Mutator:
195
+ with pytest.raises(TypeError) as excinfo:
196
+ m.double_threer(second_row)
197
+ assert (
198
+ msg(excinfo.value)
199
+ == """
200
+ double_threer(): incompatible function arguments. The following argument types are supported:
201
+ 1. (arg0: numpy.ndarray[numpy.float32[1, 3], flags.writeable]) -> None
202
+
203
+ Invoked with: """ # noqa: E501 line too long
204
+ + repr(np.array([5.0, 4.0, 3.0], dtype="float32"))
205
+ )
206
+
207
+ with pytest.raises(TypeError) as excinfo:
208
+ m.double_threec(second_col)
209
+ assert (
210
+ msg(excinfo.value)
211
+ == """
212
+ double_threec(): incompatible function arguments. The following argument types are supported:
213
+ 1. (arg0: numpy.ndarray[numpy.float32[3, 1], flags.writeable]) -> None
214
+
215
+ Invoked with: """ # noqa: E501 line too long
216
+ + repr(np.array([7.0, 4.0, 1.0], dtype="float32"))
217
+ )
218
+
219
+
220
+ def test_nonunit_stride_to_python():
221
+ assert np.all(m.diagonal(ref) == ref.diagonal())
222
+ assert np.all(m.diagonal_1(ref) == ref.diagonal(1))
223
+ for i in range(-5, 7):
224
+ assert np.all(
225
+ m.diagonal_n(ref, i) == ref.diagonal(i)
226
+ ), "m.diagonal_n({})".format(i)
227
+
228
+ assert np.all(m.block(ref, 2, 1, 3, 3) == ref[2:5, 1:4])
229
+ assert np.all(m.block(ref, 1, 4, 4, 2) == ref[1:, 4:])
230
+ assert np.all(m.block(ref, 1, 4, 3, 2) == ref[1:4, 4:])
231
+
232
+
233
+ def test_eigen_ref_to_python():
234
+ chols = [m.cholesky1, m.cholesky2, m.cholesky3, m.cholesky4]
235
+ for i, chol in enumerate(chols, start=1):
236
+ mymat = chol(np.array([[1.0, 2, 4], [2, 13, 23], [4, 23, 77]]))
237
+ assert np.all(
238
+ mymat == np.array([[1, 0, 0], [2, 3, 0], [4, 5, 6]])
239
+ ), "cholesky{}".format(i)
240
+
241
+
242
+ def assign_both(a1, a2, r, c, v):
243
+ a1[r, c] = v
244
+ a2[r, c] = v
245
+
246
+
247
+ def array_copy_but_one(a, r, c, v):
248
+ z = np.array(a, copy=True)
249
+ z[r, c] = v
250
+ return z
251
+
252
+
253
+ def test_eigen_return_references():
254
+ """Tests various ways of returning references and non-referencing copies"""
255
+
256
+ master = np.ones((10, 10))
257
+ a = m.ReturnTester()
258
+ a_get1 = a.get()
259
+ assert not a_get1.flags.owndata and a_get1.flags.writeable
260
+ assign_both(a_get1, master, 3, 3, 5)
261
+ a_get2 = a.get_ptr()
262
+ assert not a_get2.flags.owndata and a_get2.flags.writeable
263
+ assign_both(a_get1, master, 2, 3, 6)
264
+
265
+ a_view1 = a.view()
266
+ assert not a_view1.flags.owndata and not a_view1.flags.writeable
267
+ with pytest.raises(ValueError):
268
+ a_view1[2, 3] = 4
269
+ a_view2 = a.view_ptr()
270
+ assert not a_view2.flags.owndata and not a_view2.flags.writeable
271
+ with pytest.raises(ValueError):
272
+ a_view2[2, 3] = 4
273
+
274
+ a_copy1 = a.copy_get()
275
+ assert a_copy1.flags.owndata and a_copy1.flags.writeable
276
+ np.testing.assert_array_equal(a_copy1, master)
277
+ a_copy1[7, 7] = -44 # Shouldn't affect anything else
278
+ c1want = array_copy_but_one(master, 7, 7, -44)
279
+ a_copy2 = a.copy_view()
280
+ assert a_copy2.flags.owndata and a_copy2.flags.writeable
281
+ np.testing.assert_array_equal(a_copy2, master)
282
+ a_copy2[4, 4] = -22 # Shouldn't affect anything else
283
+ c2want = array_copy_but_one(master, 4, 4, -22)
284
+
285
+ a_ref1 = a.ref()
286
+ assert not a_ref1.flags.owndata and a_ref1.flags.writeable
287
+ assign_both(a_ref1, master, 1, 1, 15)
288
+ a_ref2 = a.ref_const()
289
+ assert not a_ref2.flags.owndata and not a_ref2.flags.writeable
290
+ with pytest.raises(ValueError):
291
+ a_ref2[5, 5] = 33
292
+ a_ref3 = a.ref_safe()
293
+ assert not a_ref3.flags.owndata and a_ref3.flags.writeable
294
+ assign_both(a_ref3, master, 0, 7, 99)
295
+ a_ref4 = a.ref_const_safe()
296
+ assert not a_ref4.flags.owndata and not a_ref4.flags.writeable
297
+ with pytest.raises(ValueError):
298
+ a_ref4[7, 0] = 987654321
299
+
300
+ a_copy3 = a.copy_ref()
301
+ assert a_copy3.flags.owndata and a_copy3.flags.writeable
302
+ np.testing.assert_array_equal(a_copy3, master)
303
+ a_copy3[8, 1] = 11
304
+ c3want = array_copy_but_one(master, 8, 1, 11)
305
+ a_copy4 = a.copy_ref_const()
306
+ assert a_copy4.flags.owndata and a_copy4.flags.writeable
307
+ np.testing.assert_array_equal(a_copy4, master)
308
+ a_copy4[8, 4] = 88
309
+ c4want = array_copy_but_one(master, 8, 4, 88)
310
+
311
+ a_block1 = a.block(3, 3, 2, 2)
312
+ assert not a_block1.flags.owndata and a_block1.flags.writeable
313
+ a_block1[0, 0] = 55
314
+ master[3, 3] = 55
315
+ a_block2 = a.block_safe(2, 2, 3, 2)
316
+ assert not a_block2.flags.owndata and a_block2.flags.writeable
317
+ a_block2[2, 1] = -123
318
+ master[4, 3] = -123
319
+ a_block3 = a.block_const(6, 7, 4, 3)
320
+ assert not a_block3.flags.owndata and not a_block3.flags.writeable
321
+ with pytest.raises(ValueError):
322
+ a_block3[2, 2] = -44444
323
+
324
+ a_copy5 = a.copy_block(2, 2, 2, 3)
325
+ assert a_copy5.flags.owndata and a_copy5.flags.writeable
326
+ np.testing.assert_array_equal(a_copy5, master[2:4, 2:5])
327
+ a_copy5[1, 1] = 777
328
+ c5want = array_copy_but_one(master[2:4, 2:5], 1, 1, 777)
329
+
330
+ a_corn1 = a.corners()
331
+ assert not a_corn1.flags.owndata and a_corn1.flags.writeable
332
+ a_corn1 *= 50
333
+ a_corn1[1, 1] = 999
334
+ master[0, 0] = 50
335
+ master[0, 9] = 50
336
+ master[9, 0] = 50
337
+ master[9, 9] = 999
338
+ a_corn2 = a.corners_const()
339
+ assert not a_corn2.flags.owndata and not a_corn2.flags.writeable
340
+ with pytest.raises(ValueError):
341
+ a_corn2[1, 0] = 51
342
+
343
+ # All of the changes made all the way along should be visible everywhere
344
+ # now (except for the copies, of course)
345
+ np.testing.assert_array_equal(a_get1, master)
346
+ np.testing.assert_array_equal(a_get2, master)
347
+ np.testing.assert_array_equal(a_view1, master)
348
+ np.testing.assert_array_equal(a_view2, master)
349
+ np.testing.assert_array_equal(a_ref1, master)
350
+ np.testing.assert_array_equal(a_ref2, master)
351
+ np.testing.assert_array_equal(a_ref3, master)
352
+ np.testing.assert_array_equal(a_ref4, master)
353
+ np.testing.assert_array_equal(a_block1, master[3:5, 3:5])
354
+ np.testing.assert_array_equal(a_block2, master[2:5, 2:4])
355
+ np.testing.assert_array_equal(a_block3, master[6:10, 7:10])
356
+ np.testing.assert_array_equal(
357
+ a_corn1, master[0 :: master.shape[0] - 1, 0 :: master.shape[1] - 1]
358
+ )
359
+ np.testing.assert_array_equal(
360
+ a_corn2, master[0 :: master.shape[0] - 1, 0 :: master.shape[1] - 1]
361
+ )
362
+
363
+ np.testing.assert_array_equal(a_copy1, c1want)
364
+ np.testing.assert_array_equal(a_copy2, c2want)
365
+ np.testing.assert_array_equal(a_copy3, c3want)
366
+ np.testing.assert_array_equal(a_copy4, c4want)
367
+ np.testing.assert_array_equal(a_copy5, c5want)
368
+
369
+
370
+ def assert_keeps_alive(cl, method, *args):
371
+ cstats = ConstructorStats.get(cl)
372
+ start_with = cstats.alive()
373
+ a = cl()
374
+ assert cstats.alive() == start_with + 1
375
+ z = method(a, *args)
376
+ assert cstats.alive() == start_with + 1
377
+ del a
378
+ # Here's the keep alive in action:
379
+ assert cstats.alive() == start_with + 1
380
+ del z
381
+ # Keep alive should have expired:
382
+ assert cstats.alive() == start_with
383
+
384
+
385
+ def test_eigen_keepalive():
386
+ a = m.ReturnTester()
387
+ cstats = ConstructorStats.get(m.ReturnTester)
388
+ assert cstats.alive() == 1
389
+ unsafe = [a.ref(), a.ref_const(), a.block(1, 2, 3, 4)]
390
+ copies = [
391
+ a.copy_get(),
392
+ a.copy_view(),
393
+ a.copy_ref(),
394
+ a.copy_ref_const(),
395
+ a.copy_block(4, 3, 2, 1),
396
+ ]
397
+ del a
398
+ assert cstats.alive() == 0
399
+ del unsafe
400
+ del copies
401
+
402
+ for meth in [
403
+ m.ReturnTester.get,
404
+ m.ReturnTester.get_ptr,
405
+ m.ReturnTester.view,
406
+ m.ReturnTester.view_ptr,
407
+ m.ReturnTester.ref_safe,
408
+ m.ReturnTester.ref_const_safe,
409
+ m.ReturnTester.corners,
410
+ m.ReturnTester.corners_const,
411
+ ]:
412
+ assert_keeps_alive(m.ReturnTester, meth)
413
+
414
+ for meth in [m.ReturnTester.block_safe, m.ReturnTester.block_const]:
415
+ assert_keeps_alive(m.ReturnTester, meth, 4, 3, 2, 1)
416
+
417
+
418
+ def test_eigen_ref_mutators():
419
+ """Tests Eigen's ability to mutate numpy values"""
420
+
421
+ orig = np.array([[1.0, 2, 3], [4, 5, 6], [7, 8, 9]])
422
+ zr = np.array(orig)
423
+ zc = np.array(orig, order="F")
424
+ m.add_rm(zr, 1, 0, 100)
425
+ assert np.all(zr == np.array([[1.0, 2, 3], [104, 5, 6], [7, 8, 9]]))
426
+ m.add_cm(zc, 1, 0, 200)
427
+ assert np.all(zc == np.array([[1.0, 2, 3], [204, 5, 6], [7, 8, 9]]))
428
+
429
+ m.add_any(zr, 1, 0, 20)
430
+ assert np.all(zr == np.array([[1.0, 2, 3], [124, 5, 6], [7, 8, 9]]))
431
+ m.add_any(zc, 1, 0, 10)
432
+ assert np.all(zc == np.array([[1.0, 2, 3], [214, 5, 6], [7, 8, 9]]))
433
+
434
+ # Can't reference a col-major array with a row-major Ref, and vice versa:
435
+ with pytest.raises(TypeError):
436
+ m.add_rm(zc, 1, 0, 1)
437
+ with pytest.raises(TypeError):
438
+ m.add_cm(zr, 1, 0, 1)
439
+
440
+ # Overloads:
441
+ m.add1(zr, 1, 0, -100)
442
+ m.add2(zr, 1, 0, -20)
443
+ assert np.all(zr == orig)
444
+ m.add1(zc, 1, 0, -200)
445
+ m.add2(zc, 1, 0, -10)
446
+ assert np.all(zc == orig)
447
+
448
+ # a non-contiguous slice (this won't work on either the row- or
449
+ # column-contiguous refs, but should work for the any)
450
+ cornersr = zr[0::2, 0::2]
451
+ cornersc = zc[0::2, 0::2]
452
+
453
+ assert np.all(cornersr == np.array([[1.0, 3], [7, 9]]))
454
+ assert np.all(cornersc == np.array([[1.0, 3], [7, 9]]))
455
+
456
+ with pytest.raises(TypeError):
457
+ m.add_rm(cornersr, 0, 1, 25)
458
+ with pytest.raises(TypeError):
459
+ m.add_cm(cornersr, 0, 1, 25)
460
+ with pytest.raises(TypeError):
461
+ m.add_rm(cornersc, 0, 1, 25)
462
+ with pytest.raises(TypeError):
463
+ m.add_cm(cornersc, 0, 1, 25)
464
+ m.add_any(cornersr, 0, 1, 25)
465
+ m.add_any(cornersc, 0, 1, 44)
466
+ assert np.all(zr == np.array([[1.0, 2, 28], [4, 5, 6], [7, 8, 9]]))
467
+ assert np.all(zc == np.array([[1.0, 2, 47], [4, 5, 6], [7, 8, 9]]))
468
+
469
+ # You shouldn't be allowed to pass a non-writeable array to a mutating Eigen method:
470
+ zro = zr[0:4, 0:4]
471
+ zro.flags.writeable = False
472
+ with pytest.raises(TypeError):
473
+ m.add_rm(zro, 0, 0, 0)
474
+ with pytest.raises(TypeError):
475
+ m.add_any(zro, 0, 0, 0)
476
+ with pytest.raises(TypeError):
477
+ m.add1(zro, 0, 0, 0)
478
+ with pytest.raises(TypeError):
479
+ m.add2(zro, 0, 0, 0)
480
+
481
+ # integer array shouldn't be passable to a double-matrix-accepting mutating func:
482
+ zi = np.array([[1, 2], [3, 4]])
483
+ with pytest.raises(TypeError):
484
+ m.add_rm(zi)
485
+
486
+
487
+ def test_numpy_ref_mutators():
488
+ """Tests numpy mutating Eigen matrices (for returned Eigen::Ref<...>s)"""
489
+
490
+ m.reset_refs() # In case another test already changed it
491
+
492
+ zc = m.get_cm_ref()
493
+ zcro = m.get_cm_const_ref()
494
+ zr = m.get_rm_ref()
495
+ zrro = m.get_rm_const_ref()
496
+
497
+ assert [zc[1, 2], zcro[1, 2], zr[1, 2], zrro[1, 2]] == [23] * 4
498
+
499
+ assert not zc.flags.owndata and zc.flags.writeable
500
+ assert not zr.flags.owndata and zr.flags.writeable
501
+ assert not zcro.flags.owndata and not zcro.flags.writeable
502
+ assert not zrro.flags.owndata and not zrro.flags.writeable
503
+
504
+ zc[1, 2] = 99
505
+ expect = np.array([[11.0, 12, 13], [21, 22, 99], [31, 32, 33]])
506
+ # We should have just changed zc, of course, but also zcro and the original eigen matrix
507
+ assert np.all(zc == expect)
508
+ assert np.all(zcro == expect)
509
+ assert np.all(m.get_cm_ref() == expect)
510
+
511
+ zr[1, 2] = 99
512
+ assert np.all(zr == expect)
513
+ assert np.all(zrro == expect)
514
+ assert np.all(m.get_rm_ref() == expect)
515
+
516
+ # Make sure the readonly ones are numpy-readonly:
517
+ with pytest.raises(ValueError):
518
+ zcro[1, 2] = 6
519
+ with pytest.raises(ValueError):
520
+ zrro[1, 2] = 6
521
+
522
+ # We should be able to explicitly copy like this (and since we're copying,
523
+ # the const should drop away)
524
+ y1 = np.array(m.get_cm_const_ref())
525
+
526
+ assert y1.flags.owndata and y1.flags.writeable
527
+ # We should get copies of the eigen data, which was modified above:
528
+ assert y1[1, 2] == 99
529
+ y1[1, 2] += 12
530
+ assert y1[1, 2] == 111
531
+ assert zc[1, 2] == 99 # Make sure we aren't referencing the original
532
+
533
+
534
+ def test_both_ref_mutators():
535
+ """Tests a complex chain of nested eigen/numpy references"""
536
+
537
+ m.reset_refs() # In case another test already changed it
538
+
539
+ z = m.get_cm_ref() # numpy -> eigen
540
+ z[0, 2] -= 3
541
+ z2 = m.incr_matrix(z, 1) # numpy -> eigen -> numpy -> eigen
542
+ z2[1, 1] += 6
543
+ z3 = m.incr_matrix(z, 2) # (numpy -> eigen)^3
544
+ z3[2, 2] += -5
545
+ z4 = m.incr_matrix(z, 3) # (numpy -> eigen)^4
546
+ z4[1, 1] -= 1
547
+ z5 = m.incr_matrix(z, 4) # (numpy -> eigen)^5
548
+ z5[0, 0] = 0
549
+ assert np.all(z == z2)
550
+ assert np.all(z == z3)
551
+ assert np.all(z == z4)
552
+ assert np.all(z == z5)
553
+ expect = np.array([[0.0, 22, 20], [31, 37, 33], [41, 42, 38]])
554
+ assert np.all(z == expect)
555
+
556
+ y = np.array(range(100), dtype="float64").reshape(10, 10)
557
+ y2 = m.incr_matrix_any(y, 10) # np -> eigen -> np
558
+ y3 = m.incr_matrix_any(
559
+ y2[0::2, 0::2], -33
560
+ ) # np -> eigen -> np slice -> np -> eigen -> np
561
+ y4 = m.even_rows(y3) # numpy -> eigen slice -> (... y3)
562
+ y5 = m.even_cols(y4) # numpy -> eigen slice -> (... y4)
563
+ y6 = m.incr_matrix_any(y5, 1000) # numpy -> eigen -> (... y5)
564
+
565
+ # Apply same mutations using just numpy:
566
+ yexpect = np.array(range(100), dtype="float64").reshape(10, 10)
567
+ yexpect += 10
568
+ yexpect[0::2, 0::2] -= 33
569
+ yexpect[0::4, 0::4] += 1000
570
+ assert np.all(y6 == yexpect[0::4, 0::4])
571
+ assert np.all(y5 == yexpect[0::4, 0::4])
572
+ assert np.all(y4 == yexpect[0::4, 0::2])
573
+ assert np.all(y3 == yexpect[0::2, 0::2])
574
+ assert np.all(y2 == yexpect)
575
+ assert np.all(y == yexpect)
576
+
577
+
578
+ def test_nocopy_wrapper():
579
+ # get_elem requires a column-contiguous matrix reference, but should be
580
+ # callable with other types of matrix (via copying):
581
+ int_matrix_colmajor = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], order="F")
582
+ dbl_matrix_colmajor = np.array(
583
+ int_matrix_colmajor, dtype="double", order="F", copy=True
584
+ )
585
+ int_matrix_rowmajor = np.array(int_matrix_colmajor, order="C", copy=True)
586
+ dbl_matrix_rowmajor = np.array(
587
+ int_matrix_rowmajor, dtype="double", order="C", copy=True
588
+ )
589
+
590
+ # All should be callable via get_elem:
591
+ assert m.get_elem(int_matrix_colmajor) == 8
592
+ assert m.get_elem(dbl_matrix_colmajor) == 8
593
+ assert m.get_elem(int_matrix_rowmajor) == 8
594
+ assert m.get_elem(dbl_matrix_rowmajor) == 8
595
+
596
+ # All but the second should fail with m.get_elem_nocopy:
597
+ with pytest.raises(TypeError) as excinfo:
598
+ m.get_elem_nocopy(int_matrix_colmajor)
599
+ assert "get_elem_nocopy(): incompatible function arguments." in str(
600
+ excinfo.value
601
+ ) and ", flags.f_contiguous" in str(excinfo.value)
602
+ assert m.get_elem_nocopy(dbl_matrix_colmajor) == 8
603
+ with pytest.raises(TypeError) as excinfo:
604
+ m.get_elem_nocopy(int_matrix_rowmajor)
605
+ assert "get_elem_nocopy(): incompatible function arguments." in str(
606
+ excinfo.value
607
+ ) and ", flags.f_contiguous" in str(excinfo.value)
608
+ with pytest.raises(TypeError) as excinfo:
609
+ m.get_elem_nocopy(dbl_matrix_rowmajor)
610
+ assert "get_elem_nocopy(): incompatible function arguments." in str(
611
+ excinfo.value
612
+ ) and ", flags.f_contiguous" in str(excinfo.value)
613
+
614
+ # For the row-major test, we take a long matrix in row-major, so only the third is allowed:
615
+ with pytest.raises(TypeError) as excinfo:
616
+ m.get_elem_rm_nocopy(int_matrix_colmajor)
617
+ assert "get_elem_rm_nocopy(): incompatible function arguments." in str(
618
+ excinfo.value
619
+ ) and ", flags.c_contiguous" in str(excinfo.value)
620
+ with pytest.raises(TypeError) as excinfo:
621
+ m.get_elem_rm_nocopy(dbl_matrix_colmajor)
622
+ assert "get_elem_rm_nocopy(): incompatible function arguments." in str(
623
+ excinfo.value
624
+ ) and ", flags.c_contiguous" in str(excinfo.value)
625
+ assert m.get_elem_rm_nocopy(int_matrix_rowmajor) == 8
626
+ with pytest.raises(TypeError) as excinfo:
627
+ m.get_elem_rm_nocopy(dbl_matrix_rowmajor)
628
+ assert "get_elem_rm_nocopy(): incompatible function arguments." in str(
629
+ excinfo.value
630
+ ) and ", flags.c_contiguous" in str(excinfo.value)
631
+
632
+
633
+ def test_eigen_ref_life_support():
634
+ """Ensure the lifetime of temporary arrays created by the `Ref` caster
635
+
636
+ The `Ref` caster sometimes creates a copy which needs to stay alive. This needs to
637
+ happen both for directs casts (just the array) or indirectly (e.g. list of arrays).
638
+ """
639
+
640
+ a = np.full(shape=10, fill_value=8, dtype=np.int8)
641
+ assert m.get_elem_direct(a) == 8
642
+
643
+ list_of_a = [a]
644
+ assert m.get_elem_indirect(list_of_a) == 8
645
+
646
+
647
+ def test_special_matrix_objects():
648
+ assert np.all(m.incr_diag(7) == np.diag([1.0, 2, 3, 4, 5, 6, 7]))
649
+
650
+ asymm = np.array([[1.0, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])
651
+ symm_lower = np.array(asymm)
652
+ symm_upper = np.array(asymm)
653
+ for i in range(4):
654
+ for j in range(i + 1, 4):
655
+ symm_lower[i, j] = symm_lower[j, i]
656
+ symm_upper[j, i] = symm_upper[i, j]
657
+
658
+ assert np.all(m.symmetric_lower(asymm) == symm_lower)
659
+ assert np.all(m.symmetric_upper(asymm) == symm_upper)
660
+
661
+
662
+ def test_dense_signature(doc):
663
+ assert (
664
+ doc(m.double_col)
665
+ == """
666
+ double_col(arg0: numpy.ndarray[numpy.float32[m, 1]]) -> numpy.ndarray[numpy.float32[m, 1]]
667
+ """
668
+ )
669
+ assert (
670
+ doc(m.double_row)
671
+ == """
672
+ double_row(arg0: numpy.ndarray[numpy.float32[1, n]]) -> numpy.ndarray[numpy.float32[1, n]]
673
+ """
674
+ )
675
+ assert doc(m.double_complex) == (
676
+ """
677
+ double_complex(arg0: numpy.ndarray[numpy.complex64[m, 1]])"""
678
+ """ -> numpy.ndarray[numpy.complex64[m, 1]]
679
+ """
680
+ )
681
+ assert doc(m.double_mat_rm) == (
682
+ """
683
+ double_mat_rm(arg0: numpy.ndarray[numpy.float32[m, n]])"""
684
+ """ -> numpy.ndarray[numpy.float32[m, n]]
685
+ """
686
+ )
687
+
688
+
689
+ def test_named_arguments():
690
+ a = np.array([[1.0, 2], [3, 4], [5, 6]])
691
+ b = np.ones((2, 1))
692
+
693
+ assert np.all(m.matrix_multiply(a, b) == np.array([[3.0], [7], [11]]))
694
+ assert np.all(m.matrix_multiply(A=a, B=b) == np.array([[3.0], [7], [11]]))
695
+ assert np.all(m.matrix_multiply(B=b, A=a) == np.array([[3.0], [7], [11]]))
696
+
697
+ with pytest.raises(ValueError) as excinfo:
698
+ m.matrix_multiply(b, a)
699
+ assert str(excinfo.value) == "Nonconformable matrices!"
700
+
701
+ with pytest.raises(ValueError) as excinfo:
702
+ m.matrix_multiply(A=b, B=a)
703
+ assert str(excinfo.value) == "Nonconformable matrices!"
704
+
705
+ with pytest.raises(ValueError) as excinfo:
706
+ m.matrix_multiply(B=a, A=b)
707
+ assert str(excinfo.value) == "Nonconformable matrices!"
708
+
709
+
710
+ def test_sparse():
711
+ pytest.importorskip("scipy")
712
+ assert_sparse_equal_ref(m.sparse_r())
713
+ assert_sparse_equal_ref(m.sparse_c())
714
+ assert_sparse_equal_ref(m.sparse_copy_r(m.sparse_r()))
715
+ assert_sparse_equal_ref(m.sparse_copy_c(m.sparse_c()))
716
+ assert_sparse_equal_ref(m.sparse_copy_r(m.sparse_c()))
717
+ assert_sparse_equal_ref(m.sparse_copy_c(m.sparse_r()))
718
+
719
+
720
+ def test_sparse_signature(doc):
721
+ pytest.importorskip("scipy")
722
+ assert (
723
+ doc(m.sparse_copy_r)
724
+ == """
725
+ sparse_copy_r(arg0: scipy.sparse.csr_matrix[numpy.float32]) -> scipy.sparse.csr_matrix[numpy.float32]
726
+ """ # noqa: E501 line too long
727
+ )
728
+ assert (
729
+ doc(m.sparse_copy_c)
730
+ == """
731
+ sparse_copy_c(arg0: scipy.sparse.csc_matrix[numpy.float32]) -> scipy.sparse.csc_matrix[numpy.float32]
732
+ """ # noqa: E501 line too long
733
+ )
734
+
735
+
736
+ def test_issue738():
737
+ """Ignore strides on a length-1 dimension (even if they would be incompatible length > 1)"""
738
+ assert np.all(m.iss738_f1(np.array([[1.0, 2, 3]])) == np.array([[1.0, 102, 203]]))
739
+ assert np.all(
740
+ m.iss738_f1(np.array([[1.0], [2], [3]])) == np.array([[1.0], [12], [23]])
741
+ )
742
+
743
+ assert np.all(m.iss738_f2(np.array([[1.0, 2, 3]])) == np.array([[1.0, 102, 203]]))
744
+ assert np.all(
745
+ m.iss738_f2(np.array([[1.0], [2], [3]])) == np.array([[1.0], [12], [23]])
746
+ )
747
+
748
+
749
+ def test_issue1105():
750
+ """Issue 1105: 1xN or Nx1 input arrays weren't accepted for eigen
751
+ compile-time row vectors or column vector"""
752
+ assert m.iss1105_row(np.ones((1, 7)))
753
+ assert m.iss1105_col(np.ones((7, 1)))
754
+
755
+ # These should still fail (incompatible dimensions):
756
+ with pytest.raises(TypeError) as excinfo:
757
+ m.iss1105_row(np.ones((7, 1)))
758
+ assert "incompatible function arguments" in str(excinfo.value)
759
+ with pytest.raises(TypeError) as excinfo:
760
+ m.iss1105_col(np.ones((1, 7)))
761
+ assert "incompatible function arguments" in str(excinfo.value)
762
+
763
+
764
+ def test_custom_operator_new():
765
+ """Using Eigen types as member variables requires a class-specific
766
+ operator new with proper alignment"""
767
+
768
+ o = m.CustomOperatorNew()
769
+ np.testing.assert_allclose(o.a, 0.0)
770
+ np.testing.assert_allclose(o.b.diagonal(), 1.0)
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_embed/CMakeLists.txt ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ possibly_uninitialized(PYTHON_MODULE_EXTENSION Python_INTERPRETER_ID)
2
+
3
+ if("${PYTHON_MODULE_EXTENSION}" MATCHES "pypy" OR "${Python_INTERPRETER_ID}" STREQUAL "PyPy")
4
+ message(STATUS "Skipping embed test on PyPy")
5
+ add_custom_target(cpptest) # Dummy target on PyPy. Embedding is not supported.
6
+ set(_suppress_unused_variable_warning "${DOWNLOAD_CATCH}")
7
+ return()
8
+ endif()
9
+
10
+ find_package(Catch 2.13.2)
11
+
12
+ if(CATCH_FOUND)
13
+ message(STATUS "Building interpreter tests using Catch v${CATCH_VERSION}")
14
+ else()
15
+ message(STATUS "Catch not detected. Interpreter tests will be skipped. Install Catch headers"
16
+ " manually or use `cmake -DDOWNLOAD_CATCH=ON` to fetch them automatically.")
17
+ return()
18
+ endif()
19
+
20
+ find_package(Threads REQUIRED)
21
+
22
+ add_executable(test_embed catch.cpp test_interpreter.cpp)
23
+ pybind11_enable_warnings(test_embed)
24
+
25
+ target_link_libraries(test_embed PRIVATE pybind11::embed Catch2::Catch2 Threads::Threads)
26
+
27
+ if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
28
+ file(COPY test_interpreter.py DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
29
+ endif()
30
+
31
+ add_custom_target(
32
+ cpptest
33
+ COMMAND "$<TARGET_FILE:test_embed>"
34
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
35
+
36
+ pybind11_add_module(external_module THIN_LTO external_module.cpp)
37
+ set_target_properties(external_module PROPERTIES LIBRARY_OUTPUT_DIRECTORY
38
+ "${CMAKE_CURRENT_BINARY_DIR}")
39
+ foreach(config ${CMAKE_CONFIGURATION_TYPES})
40
+ string(TOUPPER ${config} config)
41
+ set_target_properties(external_module PROPERTIES LIBRARY_OUTPUT_DIRECTORY_${config}
42
+ "${CMAKE_CURRENT_BINARY_DIR}")
43
+ endforeach()
44
+ add_dependencies(cpptest external_module)
45
+
46
+ add_dependencies(check cpptest)
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_embed/catch.cpp ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // The Catch implementation is compiled here. This is a standalone
2
+ // translation unit to avoid recompiling it for every test change.
3
+
4
+ #include <pybind11/embed.h>
5
+
6
+ #ifdef _MSC_VER
7
+ // Silence MSVC C++17 deprecation warning from Catch regarding std::uncaught_exceptions (up to catch
8
+ // 2.0.1; this should be fixed in the next catch release after 2.0.1).
9
+ # pragma warning(disable: 4996)
10
+ #endif
11
+
12
+ #define CATCH_CONFIG_RUNNER
13
+ #include <catch.hpp>
14
+
15
+ namespace py = pybind11;
16
+
17
+ int main(int argc, char *argv[]) {
18
+ py::scoped_interpreter guard{};
19
+ auto result = Catch::Session().run(argc, argv);
20
+
21
+ return result < 0xff ? result : 0xff;
22
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_embed/external_module.cpp ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <pybind11/pybind11.h>
2
+
3
+ namespace py = pybind11;
4
+
5
+ /* Simple test module/test class to check that the referenced internals data of external pybind11
6
+ * modules aren't preserved over a finalize/initialize.
7
+ */
8
+
9
+ PYBIND11_MODULE(external_module, m) {
10
+ class A {
11
+ public:
12
+ A(int value) : v{value} {};
13
+ int v;
14
+ };
15
+
16
+ py::class_<A>(m, "A")
17
+ .def(py::init<int>())
18
+ .def_readwrite("value", &A::v);
19
+
20
+ m.def("internals_at", []() {
21
+ return reinterpret_cast<uintptr_t>(&py::detail::get_internals());
22
+ });
23
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_embed/test_interpreter.cpp ADDED
@@ -0,0 +1,285 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <pybind11/embed.h>
2
+
3
+ #ifdef _MSC_VER
4
+ // Silence MSVC C++17 deprecation warning from Catch regarding std::uncaught_exceptions (up to catch
5
+ // 2.0.1; this should be fixed in the next catch release after 2.0.1).
6
+ # pragma warning(disable: 4996)
7
+ #endif
8
+
9
+ #include <catch.hpp>
10
+
11
+ #include <fstream>
12
+ #include <functional>
13
+ #include <thread>
14
+ #include <utility>
15
+
16
+ namespace py = pybind11;
17
+ using namespace py::literals;
18
+
19
+ class Widget {
20
+ public:
21
+ Widget(std::string message) : message(std::move(message)) {}
22
+ virtual ~Widget() = default;
23
+
24
+ std::string the_message() const { return message; }
25
+ virtual int the_answer() const = 0;
26
+
27
+ private:
28
+ std::string message;
29
+ };
30
+
31
+ class PyWidget final : public Widget {
32
+ using Widget::Widget;
33
+
34
+ int the_answer() const override { PYBIND11_OVERRIDE_PURE(int, Widget, the_answer); }
35
+ };
36
+
37
+ PYBIND11_EMBEDDED_MODULE(widget_module, m) {
38
+ py::class_<Widget, PyWidget>(m, "Widget")
39
+ .def(py::init<std::string>())
40
+ .def_property_readonly("the_message", &Widget::the_message);
41
+
42
+ m.def("add", [](int i, int j) { return i + j; });
43
+ }
44
+
45
+ PYBIND11_EMBEDDED_MODULE(throw_exception, ) {
46
+ throw std::runtime_error("C++ Error");
47
+ }
48
+
49
+ PYBIND11_EMBEDDED_MODULE(throw_error_already_set, ) {
50
+ auto d = py::dict();
51
+ d["missing"].cast<py::object>();
52
+ }
53
+
54
+ TEST_CASE("Pass classes and data between modules defined in C++ and Python") {
55
+ auto module_ = py::module_::import("test_interpreter");
56
+ REQUIRE(py::hasattr(module_, "DerivedWidget"));
57
+
58
+ auto locals = py::dict("hello"_a="Hello, World!", "x"_a=5, **module_.attr("__dict__"));
59
+ py::exec(R"(
60
+ widget = DerivedWidget("{} - {}".format(hello, x))
61
+ message = widget.the_message
62
+ )", py::globals(), locals);
63
+ REQUIRE(locals["message"].cast<std::string>() == "Hello, World! - 5");
64
+
65
+ auto py_widget = module_.attr("DerivedWidget")("The question");
66
+ auto message = py_widget.attr("the_message");
67
+ REQUIRE(message.cast<std::string>() == "The question");
68
+
69
+ const auto &cpp_widget = py_widget.cast<const Widget &>();
70
+ REQUIRE(cpp_widget.the_answer() == 42);
71
+ }
72
+
73
+ TEST_CASE("Import error handling") {
74
+ REQUIRE_NOTHROW(py::module_::import("widget_module"));
75
+ REQUIRE_THROWS_WITH(py::module_::import("throw_exception"),
76
+ "ImportError: C++ Error");
77
+ REQUIRE_THROWS_WITH(py::module_::import("throw_error_already_set"),
78
+ Catch::Contains("ImportError: KeyError"));
79
+ }
80
+
81
+ TEST_CASE("There can be only one interpreter") {
82
+ static_assert(std::is_move_constructible<py::scoped_interpreter>::value, "");
83
+ static_assert(!std::is_move_assignable<py::scoped_interpreter>::value, "");
84
+ static_assert(!std::is_copy_constructible<py::scoped_interpreter>::value, "");
85
+ static_assert(!std::is_copy_assignable<py::scoped_interpreter>::value, "");
86
+
87
+ REQUIRE_THROWS_WITH(py::initialize_interpreter(), "The interpreter is already running");
88
+ REQUIRE_THROWS_WITH(py::scoped_interpreter(), "The interpreter is already running");
89
+
90
+ py::finalize_interpreter();
91
+ REQUIRE_NOTHROW(py::scoped_interpreter());
92
+ {
93
+ auto pyi1 = py::scoped_interpreter();
94
+ auto pyi2 = std::move(pyi1);
95
+ }
96
+ py::initialize_interpreter();
97
+ }
98
+
99
+ bool has_pybind11_internals_builtin() {
100
+ auto builtins = py::handle(PyEval_GetBuiltins());
101
+ return builtins.contains(PYBIND11_INTERNALS_ID);
102
+ };
103
+
104
+ bool has_pybind11_internals_static() {
105
+ auto **&ipp = py::detail::get_internals_pp();
106
+ return (ipp != nullptr) && (*ipp != nullptr);
107
+ }
108
+
109
+ TEST_CASE("Restart the interpreter") {
110
+ // Verify pre-restart state.
111
+ REQUIRE(py::module_::import("widget_module").attr("add")(1, 2).cast<int>() == 3);
112
+ REQUIRE(has_pybind11_internals_builtin());
113
+ REQUIRE(has_pybind11_internals_static());
114
+ REQUIRE(py::module_::import("external_module").attr("A")(123).attr("value").cast<int>() == 123);
115
+
116
+ // local and foreign module internals should point to the same internals:
117
+ REQUIRE(reinterpret_cast<uintptr_t>(*py::detail::get_internals_pp()) ==
118
+ py::module_::import("external_module").attr("internals_at")().cast<uintptr_t>());
119
+
120
+ // Restart the interpreter.
121
+ py::finalize_interpreter();
122
+ REQUIRE(Py_IsInitialized() == 0);
123
+
124
+ py::initialize_interpreter();
125
+ REQUIRE(Py_IsInitialized() == 1);
126
+
127
+ // Internals are deleted after a restart.
128
+ REQUIRE_FALSE(has_pybind11_internals_builtin());
129
+ REQUIRE_FALSE(has_pybind11_internals_static());
130
+ pybind11::detail::get_internals();
131
+ REQUIRE(has_pybind11_internals_builtin());
132
+ REQUIRE(has_pybind11_internals_static());
133
+ REQUIRE(reinterpret_cast<uintptr_t>(*py::detail::get_internals_pp()) ==
134
+ py::module_::import("external_module").attr("internals_at")().cast<uintptr_t>());
135
+
136
+ // Make sure that an interpreter with no get_internals() created until finalize still gets the
137
+ // internals destroyed
138
+ py::finalize_interpreter();
139
+ py::initialize_interpreter();
140
+ bool ran = false;
141
+ py::module_::import("__main__").attr("internals_destroy_test") =
142
+ py::capsule(&ran, [](void *ran) { py::detail::get_internals(); *static_cast<bool *>(ran) = true; });
143
+ REQUIRE_FALSE(has_pybind11_internals_builtin());
144
+ REQUIRE_FALSE(has_pybind11_internals_static());
145
+ REQUIRE_FALSE(ran);
146
+ py::finalize_interpreter();
147
+ REQUIRE(ran);
148
+ py::initialize_interpreter();
149
+ REQUIRE_FALSE(has_pybind11_internals_builtin());
150
+ REQUIRE_FALSE(has_pybind11_internals_static());
151
+
152
+ // C++ modules can be reloaded.
153
+ auto cpp_module = py::module_::import("widget_module");
154
+ REQUIRE(cpp_module.attr("add")(1, 2).cast<int>() == 3);
155
+
156
+ // C++ type information is reloaded and can be used in python modules.
157
+ auto py_module = py::module_::import("test_interpreter");
158
+ auto py_widget = py_module.attr("DerivedWidget")("Hello after restart");
159
+ REQUIRE(py_widget.attr("the_message").cast<std::string>() == "Hello after restart");
160
+ }
161
+
162
+ TEST_CASE("Subinterpreter") {
163
+ // Add tags to the modules in the main interpreter and test the basics.
164
+ py::module_::import("__main__").attr("main_tag") = "main interpreter";
165
+ {
166
+ auto m = py::module_::import("widget_module");
167
+ m.attr("extension_module_tag") = "added to module in main interpreter";
168
+
169
+ REQUIRE(m.attr("add")(1, 2).cast<int>() == 3);
170
+ }
171
+ REQUIRE(has_pybind11_internals_builtin());
172
+ REQUIRE(has_pybind11_internals_static());
173
+
174
+ /// Create and switch to a subinterpreter.
175
+ auto main_tstate = PyThreadState_Get();
176
+ auto sub_tstate = Py_NewInterpreter();
177
+
178
+ // Subinterpreters get their own copy of builtins. detail::get_internals() still
179
+ // works by returning from the static variable, i.e. all interpreters share a single
180
+ // global pybind11::internals;
181
+ REQUIRE_FALSE(has_pybind11_internals_builtin());
182
+ REQUIRE(has_pybind11_internals_static());
183
+
184
+ // Modules tags should be gone.
185
+ REQUIRE_FALSE(py::hasattr(py::module_::import("__main__"), "tag"));
186
+ {
187
+ auto m = py::module_::import("widget_module");
188
+ REQUIRE_FALSE(py::hasattr(m, "extension_module_tag"));
189
+
190
+ // Function bindings should still work.
191
+ REQUIRE(m.attr("add")(1, 2).cast<int>() == 3);
192
+ }
193
+
194
+ // Restore main interpreter.
195
+ Py_EndInterpreter(sub_tstate);
196
+ PyThreadState_Swap(main_tstate);
197
+
198
+ REQUIRE(py::hasattr(py::module_::import("__main__"), "main_tag"));
199
+ REQUIRE(py::hasattr(py::module_::import("widget_module"), "extension_module_tag"));
200
+ }
201
+
202
+ TEST_CASE("Execution frame") {
203
+ // When the interpreter is embedded, there is no execution frame, but `py::exec`
204
+ // should still function by using reasonable globals: `__main__.__dict__`.
205
+ py::exec("var = dict(number=42)");
206
+ REQUIRE(py::globals()["var"]["number"].cast<int>() == 42);
207
+ }
208
+
209
+ TEST_CASE("Threads") {
210
+ // Restart interpreter to ensure threads are not initialized
211
+ py::finalize_interpreter();
212
+ py::initialize_interpreter();
213
+ REQUIRE_FALSE(has_pybind11_internals_static());
214
+
215
+ constexpr auto num_threads = 10;
216
+ auto locals = py::dict("count"_a=0);
217
+
218
+ {
219
+ py::gil_scoped_release gil_release{};
220
+ REQUIRE(has_pybind11_internals_static());
221
+
222
+ auto threads = std::vector<std::thread>();
223
+ for (auto i = 0; i < num_threads; ++i) {
224
+ threads.emplace_back([&]() {
225
+ py::gil_scoped_acquire gil{};
226
+ locals["count"] = locals["count"].cast<int>() + 1;
227
+ });
228
+ }
229
+
230
+ for (auto &thread : threads) {
231
+ thread.join();
232
+ }
233
+ }
234
+
235
+ REQUIRE(locals["count"].cast<int>() == num_threads);
236
+ }
237
+
238
+ // Scope exit utility https://stackoverflow.com/a/36644501/7255855
239
+ struct scope_exit {
240
+ std::function<void()> f_;
241
+ explicit scope_exit(std::function<void()> f) noexcept : f_(std::move(f)) {}
242
+ ~scope_exit() { if (f_) f_(); }
243
+ };
244
+
245
+ TEST_CASE("Reload module from file") {
246
+ // Disable generation of cached bytecode (.pyc files) for this test, otherwise
247
+ // Python might pick up an old version from the cache instead of the new versions
248
+ // of the .py files generated below
249
+ auto sys = py::module_::import("sys");
250
+ bool dont_write_bytecode = sys.attr("dont_write_bytecode").cast<bool>();
251
+ sys.attr("dont_write_bytecode") = true;
252
+ // Reset the value at scope exit
253
+ scope_exit reset_dont_write_bytecode([&]() {
254
+ sys.attr("dont_write_bytecode") = dont_write_bytecode;
255
+ });
256
+
257
+ std::string module_name = "test_module_reload";
258
+ std::string module_file = module_name + ".py";
259
+
260
+ // Create the module .py file
261
+ std::ofstream test_module(module_file);
262
+ test_module << "def test():\n";
263
+ test_module << " return 1\n";
264
+ test_module.close();
265
+ // Delete the file at scope exit
266
+ scope_exit delete_module_file([&]() {
267
+ std::remove(module_file.c_str());
268
+ });
269
+
270
+ // Import the module from file
271
+ auto module_ = py::module_::import(module_name.c_str());
272
+ int result = module_.attr("test")().cast<int>();
273
+ REQUIRE(result == 1);
274
+
275
+ // Update the module .py file with a small change
276
+ test_module.open(module_file);
277
+ test_module << "def test():\n";
278
+ test_module << " return 2\n";
279
+ test_module.close();
280
+
281
+ // Reload the module
282
+ module_.reload();
283
+ result = module_.attr("test")().cast<int>();
284
+ REQUIRE(result == 2);
285
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_embed/test_interpreter.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ from widget_module import Widget
3
+
4
+
5
+ class DerivedWidget(Widget):
6
+ def __init__(self, message):
7
+ super(DerivedWidget, self).__init__(message)
8
+
9
+ def the_answer(self):
10
+ return 42
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_enum.cpp ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ tests/test_enums.cpp -- enumerations
3
+
4
+ Copyright (c) 2016 Wenzel Jakob <[email protected]>
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
+
12
+ TEST_SUBMODULE(enums, m) {
13
+ // test_unscoped_enum
14
+ enum UnscopedEnum {
15
+ EOne = 1,
16
+ ETwo,
17
+ EThree
18
+ };
19
+ py::enum_<UnscopedEnum>(m, "UnscopedEnum", py::arithmetic(), "An unscoped enumeration")
20
+ .value("EOne", EOne, "Docstring for EOne")
21
+ .value("ETwo", ETwo, "Docstring for ETwo")
22
+ .value("EThree", EThree, "Docstring for EThree")
23
+ .export_values();
24
+
25
+ // test_scoped_enum
26
+ enum class ScopedEnum {
27
+ Two = 2,
28
+ Three
29
+ };
30
+ py::enum_<ScopedEnum>(m, "ScopedEnum", py::arithmetic())
31
+ .value("Two", ScopedEnum::Two)
32
+ .value("Three", ScopedEnum::Three);
33
+
34
+ m.def("test_scoped_enum", [](ScopedEnum z) {
35
+ return "ScopedEnum::" + std::string(z == ScopedEnum::Two ? "Two" : "Three");
36
+ });
37
+
38
+ // test_binary_operators
39
+ enum Flags {
40
+ Read = 4,
41
+ Write = 2,
42
+ Execute = 1
43
+ };
44
+ py::enum_<Flags>(m, "Flags", py::arithmetic())
45
+ .value("Read", Flags::Read)
46
+ .value("Write", Flags::Write)
47
+ .value("Execute", Flags::Execute)
48
+ .export_values();
49
+
50
+ // test_implicit_conversion
51
+ class ClassWithUnscopedEnum {
52
+ public:
53
+ enum EMode {
54
+ EFirstMode = 1,
55
+ ESecondMode
56
+ };
57
+
58
+ static EMode test_function(EMode mode) {
59
+ return mode;
60
+ }
61
+ };
62
+ py::class_<ClassWithUnscopedEnum> exenum_class(m, "ClassWithUnscopedEnum");
63
+ exenum_class.def_static("test_function", &ClassWithUnscopedEnum::test_function);
64
+ py::enum_<ClassWithUnscopedEnum::EMode>(exenum_class, "EMode")
65
+ .value("EFirstMode", ClassWithUnscopedEnum::EFirstMode)
66
+ .value("ESecondMode", ClassWithUnscopedEnum::ESecondMode)
67
+ .export_values();
68
+
69
+ // test_enum_to_int
70
+ m.def("test_enum_to_int", [](int) { });
71
+ m.def("test_enum_to_uint", [](uint32_t) { });
72
+ m.def("test_enum_to_long_long", [](long long) { });
73
+
74
+ // test_duplicate_enum_name
75
+ enum SimpleEnum
76
+ {
77
+ ONE, TWO, THREE
78
+ };
79
+
80
+ m.def("register_bad_enum", [m]() {
81
+ py::enum_<SimpleEnum>(m, "SimpleEnum")
82
+ .value("ONE", SimpleEnum::ONE) //NOTE: all value function calls are called with the same first parameter value
83
+ .value("ONE", SimpleEnum::TWO)
84
+ .value("ONE", SimpleEnum::THREE)
85
+ .export_values();
86
+ });
87
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_enum.py ADDED
@@ -0,0 +1,236 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ import pytest
3
+ from pybind11_tests import enums as m
4
+
5
+
6
+ def test_unscoped_enum():
7
+ assert str(m.UnscopedEnum.EOne) == "UnscopedEnum.EOne"
8
+ assert str(m.UnscopedEnum.ETwo) == "UnscopedEnum.ETwo"
9
+ assert str(m.EOne) == "UnscopedEnum.EOne"
10
+ assert repr(m.UnscopedEnum.EOne) == "<UnscopedEnum.EOne: 1>"
11
+ assert repr(m.UnscopedEnum.ETwo) == "<UnscopedEnum.ETwo: 2>"
12
+ assert repr(m.EOne) == "<UnscopedEnum.EOne: 1>"
13
+
14
+ # name property
15
+ assert m.UnscopedEnum.EOne.name == "EOne"
16
+ assert m.UnscopedEnum.EOne.value == 1
17
+ assert m.UnscopedEnum.ETwo.name == "ETwo"
18
+ assert m.UnscopedEnum.ETwo.value == 2
19
+ assert m.EOne is m.UnscopedEnum.EOne
20
+ # name, value readonly
21
+ with pytest.raises(AttributeError):
22
+ m.UnscopedEnum.EOne.name = ""
23
+ with pytest.raises(AttributeError):
24
+ m.UnscopedEnum.EOne.value = 10
25
+ # name, value returns a copy
26
+ # TODO: Neither the name nor value tests actually check against aliasing.
27
+ # Use a mutable type that has reference semantics.
28
+ nonaliased_name = m.UnscopedEnum.EOne.name
29
+ nonaliased_name = "bar" # noqa: F841
30
+ assert m.UnscopedEnum.EOne.name == "EOne"
31
+ nonaliased_value = m.UnscopedEnum.EOne.value
32
+ nonaliased_value = 10 # noqa: F841
33
+ assert m.UnscopedEnum.EOne.value == 1
34
+
35
+ # __members__ property
36
+ assert m.UnscopedEnum.__members__ == {
37
+ "EOne": m.UnscopedEnum.EOne,
38
+ "ETwo": m.UnscopedEnum.ETwo,
39
+ "EThree": m.UnscopedEnum.EThree,
40
+ }
41
+ # __members__ readonly
42
+ with pytest.raises(AttributeError):
43
+ m.UnscopedEnum.__members__ = {}
44
+ # __members__ returns a copy
45
+ nonaliased_members = m.UnscopedEnum.__members__
46
+ nonaliased_members["bar"] = "baz"
47
+ assert m.UnscopedEnum.__members__ == {
48
+ "EOne": m.UnscopedEnum.EOne,
49
+ "ETwo": m.UnscopedEnum.ETwo,
50
+ "EThree": m.UnscopedEnum.EThree,
51
+ }
52
+
53
+ for docstring_line in """An unscoped enumeration
54
+
55
+ Members:
56
+
57
+ EOne : Docstring for EOne
58
+
59
+ ETwo : Docstring for ETwo
60
+
61
+ EThree : Docstring for EThree""".split(
62
+ "\n"
63
+ ):
64
+ assert docstring_line in m.UnscopedEnum.__doc__
65
+
66
+ # Unscoped enums will accept ==/!= int comparisons
67
+ y = m.UnscopedEnum.ETwo
68
+ assert y == 2
69
+ assert 2 == y
70
+ assert y != 3
71
+ assert 3 != y
72
+ # Compare with None
73
+ assert y != None # noqa: E711
74
+ assert not (y == None) # noqa: E711
75
+ # Compare with an object
76
+ assert y != object()
77
+ assert not (y == object())
78
+ # Compare with string
79
+ assert y != "2"
80
+ assert "2" != y
81
+ assert not ("2" == y)
82
+ assert not (y == "2")
83
+
84
+ with pytest.raises(TypeError):
85
+ y < object() # noqa: B015
86
+
87
+ with pytest.raises(TypeError):
88
+ y <= object() # noqa: B015
89
+
90
+ with pytest.raises(TypeError):
91
+ y > object() # noqa: B015
92
+
93
+ with pytest.raises(TypeError):
94
+ y >= object() # noqa: B015
95
+
96
+ with pytest.raises(TypeError):
97
+ y | object() # noqa: B015
98
+
99
+ with pytest.raises(TypeError):
100
+ y & object() # noqa: B015
101
+
102
+ with pytest.raises(TypeError):
103
+ y ^ object() # noqa: B015
104
+
105
+ assert int(m.UnscopedEnum.ETwo) == 2
106
+ assert str(m.UnscopedEnum(2)) == "UnscopedEnum.ETwo"
107
+
108
+ # order
109
+ assert m.UnscopedEnum.EOne < m.UnscopedEnum.ETwo
110
+ assert m.UnscopedEnum.EOne < 2
111
+ assert m.UnscopedEnum.ETwo > m.UnscopedEnum.EOne
112
+ assert m.UnscopedEnum.ETwo > 1
113
+ assert m.UnscopedEnum.ETwo <= 2
114
+ assert m.UnscopedEnum.ETwo >= 2
115
+ assert m.UnscopedEnum.EOne <= m.UnscopedEnum.ETwo
116
+ assert m.UnscopedEnum.EOne <= 2
117
+ assert m.UnscopedEnum.ETwo >= m.UnscopedEnum.EOne
118
+ assert m.UnscopedEnum.ETwo >= 1
119
+ assert not (m.UnscopedEnum.ETwo < m.UnscopedEnum.EOne)
120
+ assert not (2 < m.UnscopedEnum.EOne)
121
+
122
+ # arithmetic
123
+ assert m.UnscopedEnum.EOne & m.UnscopedEnum.EThree == m.UnscopedEnum.EOne
124
+ assert m.UnscopedEnum.EOne | m.UnscopedEnum.ETwo == m.UnscopedEnum.EThree
125
+ assert m.UnscopedEnum.EOne ^ m.UnscopedEnum.EThree == m.UnscopedEnum.ETwo
126
+
127
+
128
+ def test_scoped_enum():
129
+ assert m.test_scoped_enum(m.ScopedEnum.Three) == "ScopedEnum::Three"
130
+ z = m.ScopedEnum.Two
131
+ assert m.test_scoped_enum(z) == "ScopedEnum::Two"
132
+
133
+ # Scoped enums will *NOT* accept ==/!= int comparisons (Will always return False)
134
+ assert not z == 3
135
+ assert not 3 == z
136
+ assert z != 3
137
+ assert 3 != z
138
+ # Compare with None
139
+ assert z != None # noqa: E711
140
+ assert not (z == None) # noqa: E711
141
+ # Compare with an object
142
+ assert z != object()
143
+ assert not (z == object())
144
+ # Scoped enums will *NOT* accept >, <, >= and <= int comparisons (Will throw exceptions)
145
+ with pytest.raises(TypeError):
146
+ z > 3 # noqa: B015
147
+ with pytest.raises(TypeError):
148
+ z < 3 # noqa: B015
149
+ with pytest.raises(TypeError):
150
+ z >= 3 # noqa: B015
151
+ with pytest.raises(TypeError):
152
+ z <= 3 # noqa: B015
153
+
154
+ # order
155
+ assert m.ScopedEnum.Two < m.ScopedEnum.Three
156
+ assert m.ScopedEnum.Three > m.ScopedEnum.Two
157
+ assert m.ScopedEnum.Two <= m.ScopedEnum.Three
158
+ assert m.ScopedEnum.Two <= m.ScopedEnum.Two
159
+ assert m.ScopedEnum.Two >= m.ScopedEnum.Two
160
+ assert m.ScopedEnum.Three >= m.ScopedEnum.Two
161
+
162
+
163
+ def test_implicit_conversion():
164
+ assert str(m.ClassWithUnscopedEnum.EMode.EFirstMode) == "EMode.EFirstMode"
165
+ assert str(m.ClassWithUnscopedEnum.EFirstMode) == "EMode.EFirstMode"
166
+ assert repr(m.ClassWithUnscopedEnum.EMode.EFirstMode) == "<EMode.EFirstMode: 1>"
167
+ assert repr(m.ClassWithUnscopedEnum.EFirstMode) == "<EMode.EFirstMode: 1>"
168
+
169
+ f = m.ClassWithUnscopedEnum.test_function
170
+ first = m.ClassWithUnscopedEnum.EFirstMode
171
+ second = m.ClassWithUnscopedEnum.ESecondMode
172
+
173
+ assert f(first) == 1
174
+
175
+ assert f(first) == f(first)
176
+ assert not f(first) != f(first)
177
+
178
+ assert f(first) != f(second)
179
+ assert not f(first) == f(second)
180
+
181
+ assert f(first) == int(f(first))
182
+ assert not f(first) != int(f(first))
183
+
184
+ assert f(first) != int(f(second))
185
+ assert not f(first) == int(f(second))
186
+
187
+ # noinspection PyDictCreation
188
+ x = {f(first): 1, f(second): 2}
189
+ x[f(first)] = 3
190
+ x[f(second)] = 4
191
+ # Hashing test
192
+ assert repr(x) == "{<EMode.EFirstMode: 1>: 3, <EMode.ESecondMode: 2>: 4}"
193
+
194
+
195
+ def test_binary_operators():
196
+ assert int(m.Flags.Read) == 4
197
+ assert int(m.Flags.Write) == 2
198
+ assert int(m.Flags.Execute) == 1
199
+ assert int(m.Flags.Read | m.Flags.Write | m.Flags.Execute) == 7
200
+ assert int(m.Flags.Read | m.Flags.Write) == 6
201
+ assert int(m.Flags.Read | m.Flags.Execute) == 5
202
+ assert int(m.Flags.Write | m.Flags.Execute) == 3
203
+ assert int(m.Flags.Write | 1) == 3
204
+ assert ~m.Flags.Write == -3
205
+
206
+ state = m.Flags.Read | m.Flags.Write
207
+ assert (state & m.Flags.Read) != 0
208
+ assert (state & m.Flags.Write) != 0
209
+ assert (state & m.Flags.Execute) == 0
210
+ assert (state & 1) == 0
211
+
212
+ state2 = ~state
213
+ assert state2 == -7
214
+ assert int(state ^ state2) == -1
215
+
216
+
217
+ def test_enum_to_int():
218
+ m.test_enum_to_int(m.Flags.Read)
219
+ m.test_enum_to_int(m.ClassWithUnscopedEnum.EMode.EFirstMode)
220
+ m.test_enum_to_uint(m.Flags.Read)
221
+ m.test_enum_to_uint(m.ClassWithUnscopedEnum.EMode.EFirstMode)
222
+ m.test_enum_to_long_long(m.Flags.Read)
223
+ m.test_enum_to_long_long(m.ClassWithUnscopedEnum.EMode.EFirstMode)
224
+
225
+
226
+ def test_duplicate_enum_name():
227
+ with pytest.raises(ValueError) as excinfo:
228
+ m.register_bad_enum()
229
+ assert str(excinfo.value) == 'SimpleEnum: element "ONE" already exists!'
230
+
231
+
232
+ def test_docstring_signatures():
233
+ for enum_type in [m.ScopedEnum, m.UnscopedEnum]:
234
+ for attr in enum_type.__dict__.values():
235
+ # Issue #2623/PR #2637: Add argument names to enum_ methods
236
+ assert "arg0" not in (attr.__doc__ or "")
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_eval.cpp ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ tests/test_eval.cpp -- Usage of eval() and eval_file()
3
+
4
+ Copyright (c) 2016 Klemens D. Morgenstern
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
+
11
+ #include <pybind11/eval.h>
12
+
13
+ #include "pybind11_tests.h"
14
+ #include <utility>
15
+
16
+ TEST_SUBMODULE(eval_, m) {
17
+ // test_evals
18
+
19
+ auto global = py::dict(py::module_::import("__main__").attr("__dict__"));
20
+
21
+ m.def("test_eval_statements", [global]() {
22
+ auto local = py::dict();
23
+ local["call_test"] = py::cpp_function([&]() -> int {
24
+ return 42;
25
+ });
26
+
27
+ // Regular string literal
28
+ py::exec(
29
+ "message = 'Hello World!'\n"
30
+ "x = call_test()",
31
+ global, local
32
+ );
33
+
34
+ // Multi-line raw string literal
35
+ py::exec(R"(
36
+ if x == 42:
37
+ print(message)
38
+ else:
39
+ raise RuntimeError
40
+ )", global, local
41
+ );
42
+ auto x = local["x"].cast<int>();
43
+
44
+ return x == 42;
45
+ });
46
+
47
+ m.def("test_eval", [global]() {
48
+ auto local = py::dict();
49
+ local["x"] = py::int_(42);
50
+ auto x = py::eval("x", global, local);
51
+ return x.cast<int>() == 42;
52
+ });
53
+
54
+ m.def("test_eval_single_statement", []() {
55
+ auto local = py::dict();
56
+ local["call_test"] = py::cpp_function([&]() -> int {
57
+ return 42;
58
+ });
59
+
60
+ auto result = py::eval<py::eval_single_statement>("x = call_test()", py::dict(), local);
61
+ auto x = local["x"].cast<int>();
62
+ return result.is_none() && x == 42;
63
+ });
64
+
65
+ m.def("test_eval_file", [global](py::str filename) {
66
+ auto local = py::dict();
67
+ local["y"] = py::int_(43);
68
+
69
+ int val_out = 0;
70
+ local["call_test2"] = py::cpp_function([&](int value) { val_out = value; });
71
+
72
+ auto result = py::eval_file(std::move(filename), global, local);
73
+ return val_out == 43 && result.is_none();
74
+ });
75
+
76
+ m.def("test_eval_failure", []() {
77
+ try {
78
+ py::eval("nonsense code ...");
79
+ } catch (py::error_already_set &) {
80
+ return true;
81
+ }
82
+ return false;
83
+ });
84
+
85
+ m.def("test_eval_file_failure", []() {
86
+ try {
87
+ py::eval_file("non-existing file");
88
+ } catch (std::exception &) {
89
+ return true;
90
+ }
91
+ return false;
92
+ });
93
+
94
+ // test_eval_empty_globals
95
+ m.def("eval_empty_globals", [](py::object global) {
96
+ if (global.is_none())
97
+ global = py::dict();
98
+ auto int_class = py::eval("isinstance(42, int)", global);
99
+ return global;
100
+ });
101
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_eval.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ import os
3
+
4
+ import pytest
5
+
6
+ import env # noqa: F401
7
+
8
+ from pybind11_tests import eval_ as m
9
+
10
+
11
+ def test_evals(capture):
12
+ with capture:
13
+ assert m.test_eval_statements()
14
+ assert capture == "Hello World!"
15
+
16
+ assert m.test_eval()
17
+ assert m.test_eval_single_statement()
18
+
19
+ assert m.test_eval_failure()
20
+
21
+
22
+ @pytest.mark.xfail("env.PYPY and not env.PY2", raises=RuntimeError)
23
+ def test_eval_file():
24
+ filename = os.path.join(os.path.dirname(__file__), "test_eval_call.py")
25
+ assert m.test_eval_file(filename)
26
+
27
+ assert m.test_eval_file_failure()
28
+
29
+
30
+ def test_eval_empty_globals():
31
+ assert "__builtins__" in m.eval_empty_globals(None)
32
+
33
+ g = {}
34
+ assert "__builtins__" in m.eval_empty_globals(g)
35
+ assert "__builtins__" in g
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_eval_call.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ # This file is called from 'test_eval.py'
3
+
4
+ if "call_test2" in locals():
5
+ call_test2(y) # noqa: F821 undefined name
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_exceptions.cpp ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ tests/test_custom-exceptions.cpp -- exception translation
3
+
4
+ Copyright (c) 2016 Pim Schellart <[email protected]>
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 "test_exceptions.h"
11
+
12
+ #include "pybind11_tests.h"
13
+ #include <utility>
14
+
15
+ // A type that should be raised as an exception in Python
16
+ class MyException : public std::exception {
17
+ public:
18
+ explicit MyException(const char * m) : message{m} {}
19
+ const char * what() const noexcept override {return message.c_str();}
20
+ private:
21
+ std::string message = "";
22
+ };
23
+
24
+ // A type that should be translated to a standard Python exception
25
+ class MyException2 : public std::exception {
26
+ public:
27
+ explicit MyException2(const char * m) : message{m} {}
28
+ const char * what() const noexcept override {return message.c_str();}
29
+ private:
30
+ std::string message = "";
31
+ };
32
+
33
+ // A type that is not derived from std::exception (and is thus unknown)
34
+ class MyException3 {
35
+ public:
36
+ explicit MyException3(const char * m) : message{m} {}
37
+ virtual const char * what() const noexcept {return message.c_str();}
38
+ // Rule of 5 BEGIN: to preempt compiler warnings.
39
+ MyException3(const MyException3&) = default;
40
+ MyException3(MyException3&&) = default;
41
+ MyException3& operator=(const MyException3&) = default;
42
+ MyException3& operator=(MyException3&&) = default;
43
+ virtual ~MyException3() = default;
44
+ // Rule of 5 END.
45
+ private:
46
+ std::string message = "";
47
+ };
48
+
49
+ // A type that should be translated to MyException
50
+ // and delegated to its exception translator
51
+ class MyException4 : public std::exception {
52
+ public:
53
+ explicit MyException4(const char * m) : message{m} {}
54
+ const char * what() const noexcept override {return message.c_str();}
55
+ private:
56
+ std::string message = "";
57
+ };
58
+
59
+
60
+ // Like the above, but declared via the helper function
61
+ class MyException5 : public std::logic_error {
62
+ public:
63
+ explicit MyException5(const std::string &what) : std::logic_error(what) {}
64
+ };
65
+
66
+ // Inherits from MyException5
67
+ class MyException5_1 : public MyException5 {
68
+ using MyException5::MyException5;
69
+ };
70
+
71
+ struct PythonCallInDestructor {
72
+ PythonCallInDestructor(const py::dict &d) : d(d) {}
73
+ ~PythonCallInDestructor() { d["good"] = true; }
74
+
75
+ py::dict d;
76
+ };
77
+
78
+
79
+
80
+ struct PythonAlreadySetInDestructor {
81
+ PythonAlreadySetInDestructor(const py::str &s) : s(s) {}
82
+ ~PythonAlreadySetInDestructor() {
83
+ py::dict foo;
84
+ try {
85
+ // Assign to a py::object to force read access of nonexistent dict entry
86
+ py::object o = foo["bar"];
87
+ }
88
+ catch (py::error_already_set& ex) {
89
+ ex.discard_as_unraisable(s);
90
+ }
91
+ }
92
+
93
+ py::str s;
94
+ };
95
+
96
+
97
+ TEST_SUBMODULE(exceptions, m) {
98
+ m.def("throw_std_exception", []() {
99
+ throw std::runtime_error("This exception was intentionally thrown.");
100
+ });
101
+
102
+ // make a new custom exception and use it as a translation target
103
+ static py::exception<MyException> ex(m, "MyException");
104
+ py::register_exception_translator([](std::exception_ptr p) {
105
+ try {
106
+ if (p) std::rethrow_exception(p);
107
+ } catch (const MyException &e) {
108
+ // Set MyException as the active python error
109
+ ex(e.what());
110
+ }
111
+ });
112
+
113
+ // register new translator for MyException2
114
+ // no need to store anything here because this type will
115
+ // never by visible from Python
116
+ py::register_exception_translator([](std::exception_ptr p) {
117
+ try {
118
+ if (p) std::rethrow_exception(p);
119
+ } catch (const MyException2 &e) {
120
+ // Translate this exception to a standard RuntimeError
121
+ PyErr_SetString(PyExc_RuntimeError, e.what());
122
+ }
123
+ });
124
+
125
+ // register new translator for MyException4
126
+ // which will catch it and delegate to the previously registered
127
+ // translator for MyException by throwing a new exception
128
+ py::register_exception_translator([](std::exception_ptr p) {
129
+ try {
130
+ if (p) std::rethrow_exception(p);
131
+ } catch (const MyException4 &e) {
132
+ throw MyException(e.what());
133
+ }
134
+ });
135
+
136
+ // A simple exception translation:
137
+ auto ex5 = py::register_exception<MyException5>(m, "MyException5");
138
+ // A slightly more complicated one that declares MyException5_1 as a subclass of MyException5
139
+ py::register_exception<MyException5_1>(m, "MyException5_1", ex5.ptr());
140
+
141
+ m.def("throws1", []() { throw MyException("this error should go to a custom type"); });
142
+ m.def("throws2", []() { throw MyException2("this error should go to a standard Python exception"); });
143
+ m.def("throws3", []() { throw MyException3("this error cannot be translated"); });
144
+ m.def("throws4", []() { throw MyException4("this error is rethrown"); });
145
+ m.def("throws5", []() { throw MyException5("this is a helper-defined translated exception"); });
146
+ m.def("throws5_1", []() { throw MyException5_1("MyException5 subclass"); });
147
+ m.def("throws_logic_error", []() { throw std::logic_error("this error should fall through to the standard handler"); });
148
+ m.def("throws_overflow_error", []() {throw std::overflow_error(""); });
149
+ m.def("exception_matches", []() {
150
+ py::dict foo;
151
+ try {
152
+ // Assign to a py::object to force read access of nonexistent dict entry
153
+ py::object o = foo["bar"];
154
+ }
155
+ catch (py::error_already_set& ex) {
156
+ if (!ex.matches(PyExc_KeyError)) throw;
157
+ return true;
158
+ }
159
+ return false;
160
+ });
161
+ m.def("exception_matches_base", []() {
162
+ py::dict foo;
163
+ try {
164
+ // Assign to a py::object to force read access of nonexistent dict entry
165
+ py::object o = foo["bar"];
166
+ }
167
+ catch (py::error_already_set &ex) {
168
+ if (!ex.matches(PyExc_Exception)) throw;
169
+ return true;
170
+ }
171
+ return false;
172
+ });
173
+ m.def("modulenotfound_exception_matches_base", []() {
174
+ try {
175
+ // On Python >= 3.6, this raises a ModuleNotFoundError, a subclass of ImportError
176
+ py::module_::import("nonexistent");
177
+ }
178
+ catch (py::error_already_set &ex) {
179
+ if (!ex.matches(PyExc_ImportError)) throw;
180
+ return true;
181
+ }
182
+ return false;
183
+ });
184
+
185
+ m.def("throw_already_set", [](bool err) {
186
+ if (err)
187
+ PyErr_SetString(PyExc_ValueError, "foo");
188
+ try {
189
+ throw py::error_already_set();
190
+ } catch (const std::runtime_error& e) {
191
+ if ((err && e.what() != std::string("ValueError: foo")) ||
192
+ (!err && e.what() != std::string("Unknown internal error occurred")))
193
+ {
194
+ PyErr_Clear();
195
+ throw std::runtime_error("error message mismatch");
196
+ }
197
+ }
198
+ PyErr_Clear();
199
+ if (err)
200
+ PyErr_SetString(PyExc_ValueError, "foo");
201
+ throw py::error_already_set();
202
+ });
203
+
204
+ m.def("python_call_in_destructor", [](const py::dict &d) {
205
+ bool retval = false;
206
+ try {
207
+ PythonCallInDestructor set_dict_in_destructor(d);
208
+ PyErr_SetString(PyExc_ValueError, "foo");
209
+ throw py::error_already_set();
210
+ } catch (const py::error_already_set&) {
211
+ retval = true;
212
+ }
213
+ return retval;
214
+ });
215
+
216
+ m.def("python_alreadyset_in_destructor", [](const py::str &s) {
217
+ PythonAlreadySetInDestructor alreadyset_in_destructor(s);
218
+ return true;
219
+ });
220
+
221
+ // test_nested_throws
222
+ m.def("try_catch",
223
+ [m](const py::object &exc_type, const py::function &f, const py::args &args) {
224
+ try {
225
+ f(*args);
226
+ } catch (py::error_already_set &ex) {
227
+ if (ex.matches(exc_type))
228
+ py::print(ex.what());
229
+ else
230
+ throw;
231
+ }
232
+ });
233
+
234
+ // Test repr that cannot be displayed
235
+ m.def("simple_bool_passthrough", [](bool x) {return x;});
236
+
237
+ m.def("throw_should_be_translated_to_key_error", []() { throw shared_exception(); });
238
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_exceptions.h ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #pragma once
2
+ #include "pybind11_tests.h"
3
+ #include <stdexcept>
4
+
5
+ // shared exceptions for cross_module_tests
6
+
7
+ class PYBIND11_EXPORT_EXCEPTION shared_exception : public pybind11::builtin_exception {
8
+ public:
9
+ using builtin_exception::builtin_exception;
10
+ explicit shared_exception() : shared_exception("") {}
11
+ void set_error() const override { PyErr_SetString(PyExc_RuntimeError, what()); }
12
+ };
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_exceptions.py ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ import sys
3
+
4
+ import pytest
5
+
6
+ import env # noqa: F401
7
+
8
+ from pybind11_tests import exceptions as m
9
+ import pybind11_cross_module_tests as cm
10
+
11
+
12
+ def test_std_exception(msg):
13
+ with pytest.raises(RuntimeError) as excinfo:
14
+ m.throw_std_exception()
15
+ assert msg(excinfo.value) == "This exception was intentionally thrown."
16
+
17
+
18
+ def test_error_already_set(msg):
19
+ with pytest.raises(RuntimeError) as excinfo:
20
+ m.throw_already_set(False)
21
+ assert msg(excinfo.value) == "Unknown internal error occurred"
22
+
23
+ with pytest.raises(ValueError) as excinfo:
24
+ m.throw_already_set(True)
25
+ assert msg(excinfo.value) == "foo"
26
+
27
+
28
+ def test_cross_module_exceptions():
29
+ with pytest.raises(RuntimeError) as excinfo:
30
+ cm.raise_runtime_error()
31
+ assert str(excinfo.value) == "My runtime error"
32
+
33
+ with pytest.raises(ValueError) as excinfo:
34
+ cm.raise_value_error()
35
+ assert str(excinfo.value) == "My value error"
36
+
37
+ with pytest.raises(ValueError) as excinfo:
38
+ cm.throw_pybind_value_error()
39
+ assert str(excinfo.value) == "pybind11 value error"
40
+
41
+ with pytest.raises(TypeError) as excinfo:
42
+ cm.throw_pybind_type_error()
43
+ assert str(excinfo.value) == "pybind11 type error"
44
+
45
+ with pytest.raises(StopIteration) as excinfo:
46
+ cm.throw_stop_iteration()
47
+
48
+
49
+ # TODO: FIXME
50
+ @pytest.mark.xfail(
51
+ "env.PYPY and env.MACOS",
52
+ raises=RuntimeError,
53
+ reason="Expected failure with PyPy and libc++ (Issue #2847 & PR #2999)",
54
+ )
55
+ def test_cross_module_exception_translator():
56
+ with pytest.raises(KeyError):
57
+ # translator registered in cross_module_tests
58
+ m.throw_should_be_translated_to_key_error()
59
+
60
+
61
+ def test_python_call_in_catch():
62
+ d = {}
63
+ assert m.python_call_in_destructor(d) is True
64
+ assert d["good"] is True
65
+
66
+
67
+ def ignore_pytest_unraisable_warning(f):
68
+ unraisable = "PytestUnraisableExceptionWarning"
69
+ if hasattr(pytest, unraisable): # Python >= 3.8 and pytest >= 6
70
+ dec = pytest.mark.filterwarnings("ignore::pytest.{}".format(unraisable))
71
+ return dec(f)
72
+ else:
73
+ return f
74
+
75
+
76
+ @ignore_pytest_unraisable_warning
77
+ def test_python_alreadyset_in_destructor(monkeypatch, capsys):
78
+ hooked = False
79
+ triggered = [False] # mutable, so Python 2.7 closure can modify it
80
+
81
+ if hasattr(sys, "unraisablehook"): # Python 3.8+
82
+ hooked = True
83
+ # Don't take `sys.unraisablehook`, as that's overwritten by pytest
84
+ default_hook = sys.__unraisablehook__
85
+
86
+ def hook(unraisable_hook_args):
87
+ exc_type, exc_value, exc_tb, err_msg, obj = unraisable_hook_args
88
+ if obj == "already_set demo":
89
+ triggered[0] = True
90
+ default_hook(unraisable_hook_args)
91
+ return
92
+
93
+ # Use monkeypatch so pytest can apply and remove the patch as appropriate
94
+ monkeypatch.setattr(sys, "unraisablehook", hook)
95
+
96
+ assert m.python_alreadyset_in_destructor("already_set demo") is True
97
+ if hooked:
98
+ assert triggered[0] is True
99
+
100
+ _, captured_stderr = capsys.readouterr()
101
+ # Error message is different in Python 2 and 3, check for words that appear in both
102
+ assert "ignored" in captured_stderr and "already_set demo" in captured_stderr
103
+
104
+
105
+ def test_exception_matches():
106
+ assert m.exception_matches()
107
+ assert m.exception_matches_base()
108
+ assert m.modulenotfound_exception_matches_base()
109
+
110
+
111
+ def test_custom(msg):
112
+ # Can we catch a MyException?
113
+ with pytest.raises(m.MyException) as excinfo:
114
+ m.throws1()
115
+ assert msg(excinfo.value) == "this error should go to a custom type"
116
+
117
+ # Can we translate to standard Python exceptions?
118
+ with pytest.raises(RuntimeError) as excinfo:
119
+ m.throws2()
120
+ assert msg(excinfo.value) == "this error should go to a standard Python exception"
121
+
122
+ # Can we handle unknown exceptions?
123
+ with pytest.raises(RuntimeError) as excinfo:
124
+ m.throws3()
125
+ assert msg(excinfo.value) == "Caught an unknown exception!"
126
+
127
+ # Can we delegate to another handler by rethrowing?
128
+ with pytest.raises(m.MyException) as excinfo:
129
+ m.throws4()
130
+ assert msg(excinfo.value) == "this error is rethrown"
131
+
132
+ # Can we fall-through to the default handler?
133
+ with pytest.raises(RuntimeError) as excinfo:
134
+ m.throws_logic_error()
135
+ assert (
136
+ msg(excinfo.value) == "this error should fall through to the standard handler"
137
+ )
138
+
139
+ # OverFlow error translation.
140
+ with pytest.raises(OverflowError) as excinfo:
141
+ m.throws_overflow_error()
142
+
143
+ # Can we handle a helper-declared exception?
144
+ with pytest.raises(m.MyException5) as excinfo:
145
+ m.throws5()
146
+ assert msg(excinfo.value) == "this is a helper-defined translated exception"
147
+
148
+ # Exception subclassing:
149
+ with pytest.raises(m.MyException5) as excinfo:
150
+ m.throws5_1()
151
+ assert msg(excinfo.value) == "MyException5 subclass"
152
+ assert isinstance(excinfo.value, m.MyException5_1)
153
+
154
+ with pytest.raises(m.MyException5_1) as excinfo:
155
+ m.throws5_1()
156
+ assert msg(excinfo.value) == "MyException5 subclass"
157
+
158
+ with pytest.raises(m.MyException5) as excinfo:
159
+ try:
160
+ m.throws5()
161
+ except m.MyException5_1:
162
+ raise RuntimeError("Exception error: caught child from parent")
163
+ assert msg(excinfo.value) == "this is a helper-defined translated exception"
164
+
165
+
166
+ def test_nested_throws(capture):
167
+ """Tests nested (e.g. C++ -> Python -> C++) exception handling"""
168
+
169
+ def throw_myex():
170
+ raise m.MyException("nested error")
171
+
172
+ def throw_myex5():
173
+ raise m.MyException5("nested error 5")
174
+
175
+ # In the comments below, the exception is caught in the first step, thrown in the last step
176
+
177
+ # C++ -> Python
178
+ with capture:
179
+ m.try_catch(m.MyException5, throw_myex5)
180
+ assert str(capture).startswith("MyException5: nested error 5")
181
+
182
+ # Python -> C++ -> Python
183
+ with pytest.raises(m.MyException) as excinfo:
184
+ m.try_catch(m.MyException5, throw_myex)
185
+ assert str(excinfo.value) == "nested error"
186
+
187
+ def pycatch(exctype, f, *args):
188
+ try:
189
+ f(*args)
190
+ except m.MyException as e:
191
+ print(e)
192
+
193
+ # C++ -> Python -> C++ -> Python
194
+ with capture:
195
+ m.try_catch(
196
+ m.MyException5,
197
+ pycatch,
198
+ m.MyException,
199
+ m.try_catch,
200
+ m.MyException,
201
+ throw_myex5,
202
+ )
203
+ assert str(capture).startswith("MyException5: nested error 5")
204
+
205
+ # C++ -> Python -> C++
206
+ with capture:
207
+ m.try_catch(m.MyException, pycatch, m.MyException5, m.throws4)
208
+ assert capture == "this error is rethrown"
209
+
210
+ # Python -> C++ -> Python -> C++
211
+ with pytest.raises(m.MyException5) as excinfo:
212
+ m.try_catch(m.MyException, pycatch, m.MyException, m.throws5)
213
+ assert str(excinfo.value) == "this is a helper-defined translated exception"
214
+
215
+
216
+ # This can often happen if you wrap a pybind11 class in a Python wrapper
217
+ def test_invalid_repr():
218
+ class MyRepr(object):
219
+ def __repr__(self):
220
+ raise AttributeError("Example error")
221
+
222
+ with pytest.raises(TypeError):
223
+ m.simple_bool_passthrough(MyRepr())
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_factory_constructors.cpp ADDED
@@ -0,0 +1,382 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ tests/test_factory_constructors.cpp -- tests construction from a factory function
3
+ via py::init_factory()
4
+
5
+ Copyright (c) 2017 Jason Rhinelander <[email protected]>
6
+
7
+ All rights reserved. Use of this source code is governed by a
8
+ BSD-style license that can be found in the LICENSE file.
9
+ */
10
+
11
+ #include "constructor_stats.h"
12
+ #include "pybind11_tests.h"
13
+ #include <cmath>
14
+ #include <new>
15
+ #include <utility>
16
+
17
+ // Classes for testing python construction via C++ factory function:
18
+ // Not publicly constructible, copyable, or movable:
19
+ class TestFactory1 {
20
+ friend class TestFactoryHelper;
21
+ TestFactory1() : value("(empty)") { print_default_created(this); }
22
+ TestFactory1(int v) : value(std::to_string(v)) { print_created(this, value); }
23
+ TestFactory1(std::string v) : value(std::move(v)) { print_created(this, value); }
24
+ public:
25
+ std::string value;
26
+ TestFactory1(TestFactory1 &&) = delete;
27
+ TestFactory1(const TestFactory1 &) = delete;
28
+ TestFactory1 &operator=(TestFactory1 &&) = delete;
29
+ TestFactory1 &operator=(const TestFactory1 &) = delete;
30
+ ~TestFactory1() { print_destroyed(this); }
31
+ };
32
+ // Non-public construction, but moveable:
33
+ class TestFactory2 {
34
+ friend class TestFactoryHelper;
35
+ TestFactory2() : value("(empty2)") { print_default_created(this); }
36
+ TestFactory2(int v) : value(std::to_string(v)) { print_created(this, value); }
37
+ TestFactory2(std::string v) : value(std::move(v)) { print_created(this, value); }
38
+ public:
39
+ TestFactory2(TestFactory2 &&m) noexcept {
40
+ value = std::move(m.value);
41
+ print_move_created(this);
42
+ }
43
+ TestFactory2 &operator=(TestFactory2 &&m) noexcept {
44
+ value = std::move(m.value);
45
+ print_move_assigned(this);
46
+ return *this;
47
+ }
48
+ std::string value;
49
+ ~TestFactory2() { print_destroyed(this); }
50
+ };
51
+ // Mixed direct/factory construction:
52
+ class TestFactory3 {
53
+ protected:
54
+ friend class TestFactoryHelper;
55
+ TestFactory3() : value("(empty3)") { print_default_created(this); }
56
+ TestFactory3(int v) : value(std::to_string(v)) { print_created(this, value); }
57
+ public:
58
+ TestFactory3(std::string v) : value(std::move(v)) { print_created(this, value); }
59
+ TestFactory3(TestFactory3 &&m) noexcept {
60
+ value = std::move(m.value);
61
+ print_move_created(this);
62
+ }
63
+ TestFactory3 &operator=(TestFactory3 &&m) noexcept {
64
+ value = std::move(m.value);
65
+ print_move_assigned(this);
66
+ return *this;
67
+ }
68
+ std::string value;
69
+ virtual ~TestFactory3() { print_destroyed(this); }
70
+ };
71
+ // Inheritance test
72
+ class TestFactory4 : public TestFactory3 {
73
+ public:
74
+ TestFactory4() : TestFactory3() { print_default_created(this); }
75
+ TestFactory4(int v) : TestFactory3(v) { print_created(this, v); }
76
+ ~TestFactory4() override { print_destroyed(this); }
77
+ };
78
+ // Another class for an invalid downcast test
79
+ class TestFactory5 : public TestFactory3 {
80
+ public:
81
+ TestFactory5(int i) : TestFactory3(i) { print_created(this, i); }
82
+ ~TestFactory5() override { print_destroyed(this); }
83
+ };
84
+
85
+ class TestFactory6 {
86
+ protected:
87
+ int value;
88
+ bool alias = false;
89
+ public:
90
+ TestFactory6(int i) : value{i} { print_created(this, i); }
91
+ TestFactory6(TestFactory6 &&f) noexcept {
92
+ print_move_created(this);
93
+ value = f.value;
94
+ alias = f.alias;
95
+ }
96
+ TestFactory6(const TestFactory6 &f) { print_copy_created(this); value = f.value; alias = f.alias; }
97
+ virtual ~TestFactory6() { print_destroyed(this); }
98
+ virtual int get() { return value; }
99
+ bool has_alias() const { return alias; }
100
+ };
101
+ class PyTF6 : public TestFactory6 {
102
+ public:
103
+ // Special constructor that allows the factory to construct a PyTF6 from a TestFactory6 only
104
+ // when an alias is needed:
105
+ PyTF6(TestFactory6 &&base) : TestFactory6(std::move(base)) { alias = true; print_created(this, "move", value); }
106
+ PyTF6(int i) : TestFactory6(i) { alias = true; print_created(this, i); }
107
+ PyTF6(PyTF6 &&f) noexcept : TestFactory6(std::move(f)) { print_move_created(this); }
108
+ PyTF6(const PyTF6 &f) : TestFactory6(f) { print_copy_created(this); }
109
+ PyTF6(std::string s) : TestFactory6((int) s.size()) { alias = true; print_created(this, s); }
110
+ ~PyTF6() override { print_destroyed(this); }
111
+ int get() override { PYBIND11_OVERRIDE(int, TestFactory6, get, /*no args*/); }
112
+ };
113
+
114
+ class TestFactory7 {
115
+ protected:
116
+ int value;
117
+ bool alias = false;
118
+ public:
119
+ TestFactory7(int i) : value{i} { print_created(this, i); }
120
+ TestFactory7(TestFactory7 &&f) noexcept {
121
+ print_move_created(this);
122
+ value = f.value;
123
+ alias = f.alias;
124
+ }
125
+ TestFactory7(const TestFactory7 &f) { print_copy_created(this); value = f.value; alias = f.alias; }
126
+ virtual ~TestFactory7() { print_destroyed(this); }
127
+ virtual int get() { return value; }
128
+ bool has_alias() const { return alias; }
129
+ };
130
+ class PyTF7 : public TestFactory7 {
131
+ public:
132
+ PyTF7(int i) : TestFactory7(i) { alias = true; print_created(this, i); }
133
+ PyTF7(PyTF7 &&f) noexcept : TestFactory7(std::move(f)) { print_move_created(this); }
134
+ PyTF7(const PyTF7 &f) : TestFactory7(f) { print_copy_created(this); }
135
+ ~PyTF7() override { print_destroyed(this); }
136
+ int get() override { PYBIND11_OVERRIDE(int, TestFactory7, get, /*no args*/); }
137
+ };
138
+
139
+
140
+ class TestFactoryHelper {
141
+ public:
142
+ // Non-movable, non-copyable type:
143
+ // Return via pointer:
144
+ static TestFactory1 *construct1() { return new TestFactory1(); }
145
+ // Holder:
146
+ static std::unique_ptr<TestFactory1> construct1(int a) { return std::unique_ptr<TestFactory1>(new TestFactory1(a)); }
147
+ // pointer again
148
+ static TestFactory1 *construct1_string(std::string a) {
149
+ return new TestFactory1(std::move(a));
150
+ }
151
+
152
+ // Moveable type:
153
+ // pointer:
154
+ static TestFactory2 *construct2() { return new TestFactory2(); }
155
+ // holder:
156
+ static std::unique_ptr<TestFactory2> construct2(int a) { return std::unique_ptr<TestFactory2>(new TestFactory2(a)); }
157
+ // by value moving:
158
+ static TestFactory2 construct2(std::string a) { return TestFactory2(std::move(a)); }
159
+
160
+ // shared_ptr holder type:
161
+ // pointer:
162
+ static TestFactory3 *construct3() { return new TestFactory3(); }
163
+ // holder:
164
+ static std::shared_ptr<TestFactory3> construct3(int a) { return std::shared_ptr<TestFactory3>(new TestFactory3(a)); }
165
+ };
166
+
167
+ TEST_SUBMODULE(factory_constructors, m) {
168
+
169
+ // Define various trivial types to allow simpler overload resolution:
170
+ py::module_ m_tag = m.def_submodule("tag");
171
+ #define MAKE_TAG_TYPE(Name) \
172
+ struct Name##_tag {}; \
173
+ py::class_<Name##_tag>(m_tag, #Name "_tag").def(py::init<>()); \
174
+ m_tag.attr(#Name) = py::cast(Name##_tag{})
175
+ MAKE_TAG_TYPE(pointer);
176
+ MAKE_TAG_TYPE(unique_ptr);
177
+ MAKE_TAG_TYPE(move);
178
+ MAKE_TAG_TYPE(shared_ptr);
179
+ MAKE_TAG_TYPE(derived);
180
+ MAKE_TAG_TYPE(TF4);
181
+ MAKE_TAG_TYPE(TF5);
182
+ MAKE_TAG_TYPE(null_ptr);
183
+ MAKE_TAG_TYPE(null_unique_ptr);
184
+ MAKE_TAG_TYPE(null_shared_ptr);
185
+ MAKE_TAG_TYPE(base);
186
+ MAKE_TAG_TYPE(invalid_base);
187
+ MAKE_TAG_TYPE(alias);
188
+ MAKE_TAG_TYPE(unaliasable);
189
+ MAKE_TAG_TYPE(mixed);
190
+
191
+ // test_init_factory_basic, test_bad_type
192
+ py::class_<TestFactory1>(m, "TestFactory1")
193
+ .def(py::init([](unique_ptr_tag, int v) { return TestFactoryHelper::construct1(v); }))
194
+ .def(py::init(&TestFactoryHelper::construct1_string)) // raw function pointer
195
+ .def(py::init([](pointer_tag) { return TestFactoryHelper::construct1(); }))
196
+ .def(py::init([](py::handle, int v, py::handle) { return TestFactoryHelper::construct1(v); }))
197
+ .def_readwrite("value", &TestFactory1::value)
198
+ ;
199
+ py::class_<TestFactory2>(m, "TestFactory2")
200
+ .def(py::init([](pointer_tag, int v) { return TestFactoryHelper::construct2(v); }))
201
+ .def(py::init([](unique_ptr_tag, std::string v) {
202
+ return TestFactoryHelper::construct2(std::move(v));
203
+ }))
204
+ .def(py::init([](move_tag) { return TestFactoryHelper::construct2(); }))
205
+ .def_readwrite("value", &TestFactory2::value);
206
+
207
+ // Stateful & reused:
208
+ int c = 1;
209
+ auto c4a = [c](pointer_tag, TF4_tag, int a) { (void) c; return new TestFactory4(a);};
210
+
211
+ // test_init_factory_basic, test_init_factory_casting
212
+ py::class_<TestFactory3, std::shared_ptr<TestFactory3>> pyTestFactory3(m, "TestFactory3");
213
+ pyTestFactory3
214
+ .def(py::init([](pointer_tag, int v) { return TestFactoryHelper::construct3(v); }))
215
+ .def(py::init([](shared_ptr_tag) { return TestFactoryHelper::construct3(); }));
216
+ ignoreOldStyleInitWarnings([&pyTestFactory3]() {
217
+ pyTestFactory3.def("__init__", [](TestFactory3 &self, std::string v) {
218
+ new (&self) TestFactory3(std::move(v));
219
+ }); // placement-new ctor
220
+ });
221
+ pyTestFactory3
222
+ // factories returning a derived type:
223
+ .def(py::init(c4a)) // derived ptr
224
+ .def(py::init([](pointer_tag, TF5_tag, int a) { return new TestFactory5(a); }))
225
+ // derived shared ptr:
226
+ .def(py::init([](shared_ptr_tag, TF4_tag, int a) { return std::make_shared<TestFactory4>(a); }))
227
+ .def(py::init([](shared_ptr_tag, TF5_tag, int a) { return std::make_shared<TestFactory5>(a); }))
228
+
229
+ // Returns nullptr:
230
+ .def(py::init([](null_ptr_tag) { return (TestFactory3 *) nullptr; }))
231
+ .def(py::init([](null_unique_ptr_tag) { return std::unique_ptr<TestFactory3>(); }))
232
+ .def(py::init([](null_shared_ptr_tag) { return std::shared_ptr<TestFactory3>(); }))
233
+
234
+ .def_readwrite("value", &TestFactory3::value)
235
+ ;
236
+
237
+ // test_init_factory_casting
238
+ py::class_<TestFactory4, TestFactory3, std::shared_ptr<TestFactory4>>(m, "TestFactory4")
239
+ .def(py::init(c4a)) // pointer
240
+ ;
241
+
242
+ // Doesn't need to be registered, but registering makes getting ConstructorStats easier:
243
+ py::class_<TestFactory5, TestFactory3, std::shared_ptr<TestFactory5>>(m, "TestFactory5");
244
+
245
+ // test_init_factory_alias
246
+ // Alias testing
247
+ py::class_<TestFactory6, PyTF6>(m, "TestFactory6")
248
+ .def(py::init([](base_tag, int i) { return TestFactory6(i); }))
249
+ .def(py::init([](alias_tag, int i) { return PyTF6(i); }))
250
+ .def(py::init([](alias_tag, std::string s) { return PyTF6(std::move(s)); }))
251
+ .def(py::init([](alias_tag, pointer_tag, int i) { return new PyTF6(i); }))
252
+ .def(py::init([](base_tag, pointer_tag, int i) { return new TestFactory6(i); }))
253
+ .def(py::init(
254
+ [](base_tag, alias_tag, pointer_tag, int i) { return (TestFactory6 *) new PyTF6(i); }))
255
+
256
+ .def("get", &TestFactory6::get)
257
+ .def("has_alias", &TestFactory6::has_alias)
258
+
259
+ .def_static(
260
+ "get_cstats", &ConstructorStats::get<TestFactory6>, py::return_value_policy::reference)
261
+ .def_static(
262
+ "get_alias_cstats", &ConstructorStats::get<PyTF6>, py::return_value_policy::reference);
263
+
264
+ // test_init_factory_dual
265
+ // Separate alias constructor testing
266
+ py::class_<TestFactory7, PyTF7, std::shared_ptr<TestFactory7>>(m, "TestFactory7")
267
+ .def(py::init([](int i) { return TestFactory7(i); }, [](int i) { return PyTF7(i); }))
268
+ .def(py::init([](pointer_tag, int i) { return new TestFactory7(i); },
269
+ [](pointer_tag, int i) { return new PyTF7(i); }))
270
+ .def(py::init([](mixed_tag, int i) { return new TestFactory7(i); },
271
+ [](mixed_tag, int i) { return PyTF7(i); }))
272
+ .def(py::init([](mixed_tag, const std::string &s) { return TestFactory7((int) s.size()); },
273
+ [](mixed_tag, const std::string &s) { return new PyTF7((int) s.size()); }))
274
+ .def(py::init([](base_tag, pointer_tag, int i) { return new TestFactory7(i); },
275
+ [](base_tag, pointer_tag, int i) { return (TestFactory7 *) new PyTF7(i); }))
276
+ .def(py::init([](alias_tag, pointer_tag, int i) { return new PyTF7(i); },
277
+ [](alias_tag, pointer_tag, int i) { return new PyTF7(10 * i); }))
278
+ .def(py::init(
279
+ [](shared_ptr_tag, base_tag, int i) { return std::make_shared<TestFactory7>(i); },
280
+ [](shared_ptr_tag, base_tag, int i) {
281
+ auto *p = new PyTF7(i);
282
+ return std::shared_ptr<TestFactory7>(p);
283
+ }))
284
+ .def(py::init([](shared_ptr_tag,
285
+ invalid_base_tag,
286
+ int i) { return std::make_shared<TestFactory7>(i); },
287
+ [](shared_ptr_tag, invalid_base_tag, int i) {
288
+ return std::make_shared<TestFactory7>(i);
289
+ })) // <-- invalid alias factory
290
+
291
+ .def("get", &TestFactory7::get)
292
+ .def("has_alias", &TestFactory7::has_alias)
293
+
294
+ .def_static(
295
+ "get_cstats", &ConstructorStats::get<TestFactory7>, py::return_value_policy::reference)
296
+ .def_static(
297
+ "get_alias_cstats", &ConstructorStats::get<PyTF7>, py::return_value_policy::reference);
298
+
299
+ // test_placement_new_alternative
300
+ // Class with a custom new operator but *without* a placement new operator (issue #948)
301
+ class NoPlacementNew {
302
+ public:
303
+ NoPlacementNew(int i) : i(i) { }
304
+ static void *operator new(std::size_t s) {
305
+ auto *p = ::operator new(s);
306
+ py::print("operator new called, returning", reinterpret_cast<uintptr_t>(p));
307
+ return p;
308
+ }
309
+ static void operator delete(void *p) {
310
+ py::print("operator delete called on", reinterpret_cast<uintptr_t>(p));
311
+ ::operator delete(p);
312
+ }
313
+ int i;
314
+ };
315
+ // As of 2.2, `py::init<args>` no longer requires placement new
316
+ py::class_<NoPlacementNew>(m, "NoPlacementNew")
317
+ .def(py::init<int>())
318
+ .def(py::init([]() { return new NoPlacementNew(100); }))
319
+ .def_readwrite("i", &NoPlacementNew::i)
320
+ ;
321
+
322
+
323
+ // test_reallocations
324
+ // Class that has verbose operator_new/operator_delete calls
325
+ struct NoisyAlloc {
326
+ NoisyAlloc(const NoisyAlloc &) = default;
327
+ NoisyAlloc(int i) { py::print(py::str("NoisyAlloc(int {})").format(i)); }
328
+ NoisyAlloc(double d) { py::print(py::str("NoisyAlloc(double {})").format(d)); }
329
+ ~NoisyAlloc() { py::print("~NoisyAlloc()"); }
330
+
331
+ static void *operator new(size_t s) { py::print("noisy new"); return ::operator new(s); }
332
+ static void *operator new(size_t, void *p) { py::print("noisy placement new"); return p; }
333
+ static void operator delete(void *p, size_t) { py::print("noisy delete"); ::operator delete(p); }
334
+ static void operator delete(void *, void *) { py::print("noisy placement delete"); }
335
+ #if defined(_MSC_VER) && _MSC_VER < 1910
336
+ // MSVC 2015 bug: the above "noisy delete" isn't invoked (fixed in MSVC 2017)
337
+ static void operator delete(void *p) { py::print("noisy delete"); ::operator delete(p); }
338
+ #endif
339
+ };
340
+
341
+
342
+ py::class_<NoisyAlloc> pyNoisyAlloc(m, "NoisyAlloc");
343
+ // Since these overloads have the same number of arguments, the dispatcher will try each of
344
+ // them until the arguments convert. Thus we can get a pre-allocation here when passing a
345
+ // single non-integer:
346
+ ignoreOldStyleInitWarnings([&pyNoisyAlloc]() {
347
+ pyNoisyAlloc.def("__init__", [](NoisyAlloc *a, int i) { new (a) NoisyAlloc(i); }); // Regular constructor, runs first, requires preallocation
348
+ });
349
+
350
+ pyNoisyAlloc.def(py::init([](double d) { return new NoisyAlloc(d); }));
351
+
352
+ // The two-argument version: first the factory pointer overload.
353
+ pyNoisyAlloc.def(py::init([](int i, int) { return new NoisyAlloc(i); }));
354
+ // Return-by-value:
355
+ pyNoisyAlloc.def(py::init([](double d, int) { return NoisyAlloc(d); }));
356
+ // Old-style placement new init; requires preallocation
357
+ ignoreOldStyleInitWarnings([&pyNoisyAlloc]() {
358
+ pyNoisyAlloc.def("__init__", [](NoisyAlloc &a, double d, double) { new (&a) NoisyAlloc(d); });
359
+ });
360
+ // Requires deallocation of previous overload preallocated value:
361
+ pyNoisyAlloc.def(py::init([](int i, double) { return new NoisyAlloc(i); }));
362
+ // Regular again: requires yet another preallocation
363
+ ignoreOldStyleInitWarnings([&pyNoisyAlloc]() {
364
+ pyNoisyAlloc.def(
365
+ "__init__", [](NoisyAlloc &a, int i, const std::string &) { new (&a) NoisyAlloc(i); });
366
+ });
367
+
368
+ // static_assert testing (the following def's should all fail with appropriate compilation errors):
369
+ #if 0
370
+ struct BadF1Base {};
371
+ struct BadF1 : BadF1Base {};
372
+ struct PyBadF1 : BadF1 {};
373
+ py::class_<BadF1, PyBadF1, std::shared_ptr<BadF1>> bf1(m, "BadF1");
374
+ // wrapped factory function must return a compatible pointer, holder, or value
375
+ bf1.def(py::init([]() { return 3; }));
376
+ // incompatible factory function pointer return type
377
+ bf1.def(py::init([]() { static int three = 3; return &three; }));
378
+ // incompatible factory function std::shared_ptr<T> return type: cannot convert shared_ptr<T> to holder
379
+ // (non-polymorphic base)
380
+ bf1.def(py::init([]() { return std::shared_ptr<BadF1Base>(new BadF1()); }));
381
+ #endif
382
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_factory_constructors.py ADDED
@@ -0,0 +1,520 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ import pytest
3
+ import re
4
+
5
+ import env # noqa: F401
6
+
7
+ from pybind11_tests import factory_constructors as m
8
+ from pybind11_tests.factory_constructors import tag
9
+ from pybind11_tests import ConstructorStats
10
+
11
+
12
+ def test_init_factory_basic():
13
+ """Tests py::init_factory() wrapper around various ways of returning the object"""
14
+
15
+ cstats = [
16
+ ConstructorStats.get(c)
17
+ for c in [m.TestFactory1, m.TestFactory2, m.TestFactory3]
18
+ ]
19
+ cstats[0].alive() # force gc
20
+ n_inst = ConstructorStats.detail_reg_inst()
21
+
22
+ x1 = m.TestFactory1(tag.unique_ptr, 3)
23
+ assert x1.value == "3"
24
+ y1 = m.TestFactory1(tag.pointer)
25
+ assert y1.value == "(empty)"
26
+ z1 = m.TestFactory1("hi!")
27
+ assert z1.value == "hi!"
28
+
29
+ assert ConstructorStats.detail_reg_inst() == n_inst + 3
30
+
31
+ x2 = m.TestFactory2(tag.move)
32
+ assert x2.value == "(empty2)"
33
+ y2 = m.TestFactory2(tag.pointer, 7)
34
+ assert y2.value == "7"
35
+ z2 = m.TestFactory2(tag.unique_ptr, "hi again")
36
+ assert z2.value == "hi again"
37
+
38
+ assert ConstructorStats.detail_reg_inst() == n_inst + 6
39
+
40
+ x3 = m.TestFactory3(tag.shared_ptr)
41
+ assert x3.value == "(empty3)"
42
+ y3 = m.TestFactory3(tag.pointer, 42)
43
+ assert y3.value == "42"
44
+ z3 = m.TestFactory3("bye")
45
+ assert z3.value == "bye"
46
+
47
+ for null_ptr_kind in [tag.null_ptr, tag.null_unique_ptr, tag.null_shared_ptr]:
48
+ with pytest.raises(TypeError) as excinfo:
49
+ m.TestFactory3(null_ptr_kind)
50
+ assert (
51
+ str(excinfo.value) == "pybind11::init(): factory function returned nullptr"
52
+ )
53
+
54
+ assert [i.alive() for i in cstats] == [3, 3, 3]
55
+ assert ConstructorStats.detail_reg_inst() == n_inst + 9
56
+
57
+ del x1, y2, y3, z3
58
+ assert [i.alive() for i in cstats] == [2, 2, 1]
59
+ assert ConstructorStats.detail_reg_inst() == n_inst + 5
60
+ del x2, x3, y1, z1, z2
61
+ assert [i.alive() for i in cstats] == [0, 0, 0]
62
+ assert ConstructorStats.detail_reg_inst() == n_inst
63
+
64
+ assert [i.values() for i in cstats] == [
65
+ ["3", "hi!"],
66
+ ["7", "hi again"],
67
+ ["42", "bye"],
68
+ ]
69
+ assert [i.default_constructions for i in cstats] == [1, 1, 1]
70
+
71
+
72
+ def test_init_factory_signature(msg):
73
+ with pytest.raises(TypeError) as excinfo:
74
+ m.TestFactory1("invalid", "constructor", "arguments")
75
+ assert (
76
+ msg(excinfo.value)
77
+ == """
78
+ __init__(): incompatible constructor arguments. The following argument types are supported:
79
+ 1. m.factory_constructors.TestFactory1(arg0: m.factory_constructors.tag.unique_ptr_tag, arg1: int)
80
+ 2. m.factory_constructors.TestFactory1(arg0: str)
81
+ 3. m.factory_constructors.TestFactory1(arg0: m.factory_constructors.tag.pointer_tag)
82
+ 4. m.factory_constructors.TestFactory1(arg0: handle, arg1: int, arg2: handle)
83
+
84
+ Invoked with: 'invalid', 'constructor', 'arguments'
85
+ """ # noqa: E501 line too long
86
+ )
87
+
88
+ assert (
89
+ msg(m.TestFactory1.__init__.__doc__)
90
+ == """
91
+ __init__(*args, **kwargs)
92
+ Overloaded function.
93
+
94
+ 1. __init__(self: m.factory_constructors.TestFactory1, arg0: m.factory_constructors.tag.unique_ptr_tag, arg1: int) -> None
95
+
96
+ 2. __init__(self: m.factory_constructors.TestFactory1, arg0: str) -> None
97
+
98
+ 3. __init__(self: m.factory_constructors.TestFactory1, arg0: m.factory_constructors.tag.pointer_tag) -> None
99
+
100
+ 4. __init__(self: m.factory_constructors.TestFactory1, arg0: handle, arg1: int, arg2: handle) -> None
101
+ """ # noqa: E501 line too long
102
+ )
103
+
104
+
105
+ def test_init_factory_casting():
106
+ """Tests py::init_factory() wrapper with various upcasting and downcasting returns"""
107
+
108
+ cstats = [
109
+ ConstructorStats.get(c)
110
+ for c in [m.TestFactory3, m.TestFactory4, m.TestFactory5]
111
+ ]
112
+ cstats[0].alive() # force gc
113
+ n_inst = ConstructorStats.detail_reg_inst()
114
+
115
+ # Construction from derived references:
116
+ a = m.TestFactory3(tag.pointer, tag.TF4, 4)
117
+ assert a.value == "4"
118
+ b = m.TestFactory3(tag.shared_ptr, tag.TF4, 5)
119
+ assert b.value == "5"
120
+ c = m.TestFactory3(tag.pointer, tag.TF5, 6)
121
+ assert c.value == "6"
122
+ d = m.TestFactory3(tag.shared_ptr, tag.TF5, 7)
123
+ assert d.value == "7"
124
+
125
+ assert ConstructorStats.detail_reg_inst() == n_inst + 4
126
+
127
+ # Shared a lambda with TF3:
128
+ e = m.TestFactory4(tag.pointer, tag.TF4, 8)
129
+ assert e.value == "8"
130
+
131
+ assert ConstructorStats.detail_reg_inst() == n_inst + 5
132
+ assert [i.alive() for i in cstats] == [5, 3, 2]
133
+
134
+ del a
135
+ assert [i.alive() for i in cstats] == [4, 2, 2]
136
+ assert ConstructorStats.detail_reg_inst() == n_inst + 4
137
+
138
+ del b, c, e
139
+ assert [i.alive() for i in cstats] == [1, 0, 1]
140
+ assert ConstructorStats.detail_reg_inst() == n_inst + 1
141
+
142
+ del d
143
+ assert [i.alive() for i in cstats] == [0, 0, 0]
144
+ assert ConstructorStats.detail_reg_inst() == n_inst
145
+
146
+ assert [i.values() for i in cstats] == [
147
+ ["4", "5", "6", "7", "8"],
148
+ ["4", "5", "8"],
149
+ ["6", "7"],
150
+ ]
151
+
152
+
153
+ def test_init_factory_alias():
154
+ """Tests py::init_factory() wrapper with value conversions and alias types"""
155
+
156
+ cstats = [m.TestFactory6.get_cstats(), m.TestFactory6.get_alias_cstats()]
157
+ cstats[0].alive() # force gc
158
+ n_inst = ConstructorStats.detail_reg_inst()
159
+
160
+ a = m.TestFactory6(tag.base, 1)
161
+ assert a.get() == 1
162
+ assert not a.has_alias()
163
+ b = m.TestFactory6(tag.alias, "hi there")
164
+ assert b.get() == 8
165
+ assert b.has_alias()
166
+ c = m.TestFactory6(tag.alias, 3)
167
+ assert c.get() == 3
168
+ assert c.has_alias()
169
+ d = m.TestFactory6(tag.alias, tag.pointer, 4)
170
+ assert d.get() == 4
171
+ assert d.has_alias()
172
+ e = m.TestFactory6(tag.base, tag.pointer, 5)
173
+ assert e.get() == 5
174
+ assert not e.has_alias()
175
+ f = m.TestFactory6(tag.base, tag.alias, tag.pointer, 6)
176
+ assert f.get() == 6
177
+ assert f.has_alias()
178
+
179
+ assert ConstructorStats.detail_reg_inst() == n_inst + 6
180
+ assert [i.alive() for i in cstats] == [6, 4]
181
+
182
+ del a, b, e
183
+ assert [i.alive() for i in cstats] == [3, 3]
184
+ assert ConstructorStats.detail_reg_inst() == n_inst + 3
185
+ del f, c, d
186
+ assert [i.alive() for i in cstats] == [0, 0]
187
+ assert ConstructorStats.detail_reg_inst() == n_inst
188
+
189
+ class MyTest(m.TestFactory6):
190
+ def __init__(self, *args):
191
+ m.TestFactory6.__init__(self, *args)
192
+
193
+ def get(self):
194
+ return -5 + m.TestFactory6.get(self)
195
+
196
+ # Return Class by value, moved into new alias:
197
+ z = MyTest(tag.base, 123)
198
+ assert z.get() == 118
199
+ assert z.has_alias()
200
+
201
+ # Return alias by value, moved into new alias:
202
+ y = MyTest(tag.alias, "why hello!")
203
+ assert y.get() == 5
204
+ assert y.has_alias()
205
+
206
+ # Return Class by pointer, moved into new alias then original destroyed:
207
+ x = MyTest(tag.base, tag.pointer, 47)
208
+ assert x.get() == 42
209
+ assert x.has_alias()
210
+
211
+ assert ConstructorStats.detail_reg_inst() == n_inst + 3
212
+ assert [i.alive() for i in cstats] == [3, 3]
213
+ del x, y, z
214
+ assert [i.alive() for i in cstats] == [0, 0]
215
+ assert ConstructorStats.detail_reg_inst() == n_inst
216
+
217
+ assert [i.values() for i in cstats] == [
218
+ ["1", "8", "3", "4", "5", "6", "123", "10", "47"],
219
+ ["hi there", "3", "4", "6", "move", "123", "why hello!", "move", "47"],
220
+ ]
221
+
222
+
223
+ def test_init_factory_dual():
224
+ """Tests init factory functions with dual main/alias factory functions"""
225
+ from pybind11_tests.factory_constructors import TestFactory7
226
+
227
+ cstats = [TestFactory7.get_cstats(), TestFactory7.get_alias_cstats()]
228
+ cstats[0].alive() # force gc
229
+ n_inst = ConstructorStats.detail_reg_inst()
230
+
231
+ class PythFactory7(TestFactory7):
232
+ def get(self):
233
+ return 100 + TestFactory7.get(self)
234
+
235
+ a1 = TestFactory7(1)
236
+ a2 = PythFactory7(2)
237
+ assert a1.get() == 1
238
+ assert a2.get() == 102
239
+ assert not a1.has_alias()
240
+ assert a2.has_alias()
241
+
242
+ b1 = TestFactory7(tag.pointer, 3)
243
+ b2 = PythFactory7(tag.pointer, 4)
244
+ assert b1.get() == 3
245
+ assert b2.get() == 104
246
+ assert not b1.has_alias()
247
+ assert b2.has_alias()
248
+
249
+ c1 = TestFactory7(tag.mixed, 5)
250
+ c2 = PythFactory7(tag.mixed, 6)
251
+ assert c1.get() == 5
252
+ assert c2.get() == 106
253
+ assert not c1.has_alias()
254
+ assert c2.has_alias()
255
+
256
+ d1 = TestFactory7(tag.base, tag.pointer, 7)
257
+ d2 = PythFactory7(tag.base, tag.pointer, 8)
258
+ assert d1.get() == 7
259
+ assert d2.get() == 108
260
+ assert not d1.has_alias()
261
+ assert d2.has_alias()
262
+
263
+ # Both return an alias; the second multiplies the value by 10:
264
+ e1 = TestFactory7(tag.alias, tag.pointer, 9)
265
+ e2 = PythFactory7(tag.alias, tag.pointer, 10)
266
+ assert e1.get() == 9
267
+ assert e2.get() == 200
268
+ assert e1.has_alias()
269
+ assert e2.has_alias()
270
+
271
+ f1 = TestFactory7(tag.shared_ptr, tag.base, 11)
272
+ f2 = PythFactory7(tag.shared_ptr, tag.base, 12)
273
+ assert f1.get() == 11
274
+ assert f2.get() == 112
275
+ assert not f1.has_alias()
276
+ assert f2.has_alias()
277
+
278
+ g1 = TestFactory7(tag.shared_ptr, tag.invalid_base, 13)
279
+ assert g1.get() == 13
280
+ assert not g1.has_alias()
281
+ with pytest.raises(TypeError) as excinfo:
282
+ PythFactory7(tag.shared_ptr, tag.invalid_base, 14)
283
+ assert (
284
+ str(excinfo.value)
285
+ == "pybind11::init(): construction failed: returned holder-wrapped instance is not an "
286
+ "alias instance"
287
+ )
288
+
289
+ assert [i.alive() for i in cstats] == [13, 7]
290
+ assert ConstructorStats.detail_reg_inst() == n_inst + 13
291
+
292
+ del a1, a2, b1, d1, e1, e2
293
+ assert [i.alive() for i in cstats] == [7, 4]
294
+ assert ConstructorStats.detail_reg_inst() == n_inst + 7
295
+ del b2, c1, c2, d2, f1, f2, g1
296
+ assert [i.alive() for i in cstats] == [0, 0]
297
+ assert ConstructorStats.detail_reg_inst() == n_inst
298
+
299
+ assert [i.values() for i in cstats] == [
300
+ ["1", "2", "3", "4", "5", "6", "7", "8", "9", "100", "11", "12", "13", "14"],
301
+ ["2", "4", "6", "8", "9", "100", "12"],
302
+ ]
303
+
304
+
305
+ def test_no_placement_new(capture):
306
+ """Prior to 2.2, `py::init<...>` relied on the type supporting placement
307
+ new; this tests a class without placement new support."""
308
+ with capture:
309
+ a = m.NoPlacementNew(123)
310
+
311
+ found = re.search(r"^operator new called, returning (\d+)\n$", str(capture))
312
+ assert found
313
+ assert a.i == 123
314
+ with capture:
315
+ del a
316
+ pytest.gc_collect()
317
+ assert capture == "operator delete called on " + found.group(1)
318
+
319
+ with capture:
320
+ b = m.NoPlacementNew()
321
+
322
+ found = re.search(r"^operator new called, returning (\d+)\n$", str(capture))
323
+ assert found
324
+ assert b.i == 100
325
+ with capture:
326
+ del b
327
+ pytest.gc_collect()
328
+ assert capture == "operator delete called on " + found.group(1)
329
+
330
+
331
+ def test_multiple_inheritance():
332
+ class MITest(m.TestFactory1, m.TestFactory2):
333
+ def __init__(self):
334
+ m.TestFactory1.__init__(self, tag.unique_ptr, 33)
335
+ m.TestFactory2.__init__(self, tag.move)
336
+
337
+ a = MITest()
338
+ assert m.TestFactory1.value.fget(a) == "33"
339
+ assert m.TestFactory2.value.fget(a) == "(empty2)"
340
+
341
+
342
+ def create_and_destroy(*args):
343
+ a = m.NoisyAlloc(*args)
344
+ print("---")
345
+ del a
346
+ pytest.gc_collect()
347
+
348
+
349
+ def strip_comments(s):
350
+ return re.sub(r"\s+#.*", "", s)
351
+
352
+
353
+ def test_reallocation_a(capture, msg):
354
+ """When the constructor is overloaded, previous overloads can require a preallocated value.
355
+ This test makes sure that such preallocated values only happen when they might be necessary,
356
+ and that they are deallocated properly."""
357
+
358
+ pytest.gc_collect()
359
+
360
+ with capture:
361
+ create_and_destroy(1)
362
+ assert (
363
+ msg(capture)
364
+ == """
365
+ noisy new
366
+ noisy placement new
367
+ NoisyAlloc(int 1)
368
+ ---
369
+ ~NoisyAlloc()
370
+ noisy delete
371
+ """
372
+ )
373
+
374
+
375
+ def test_reallocation_b(capture, msg):
376
+ with capture:
377
+ create_and_destroy(1.5)
378
+ assert msg(capture) == strip_comments(
379
+ """
380
+ noisy new # allocation required to attempt first overload
381
+ noisy delete # have to dealloc before considering factory init overload
382
+ noisy new # pointer factory calling "new", part 1: allocation
383
+ NoisyAlloc(double 1.5) # ... part two, invoking constructor
384
+ ---
385
+ ~NoisyAlloc() # Destructor
386
+ noisy delete # operator delete
387
+ """
388
+ )
389
+
390
+
391
+ def test_reallocation_c(capture, msg):
392
+ with capture:
393
+ create_and_destroy(2, 3)
394
+ assert msg(capture) == strip_comments(
395
+ """
396
+ noisy new # pointer factory calling "new", allocation
397
+ NoisyAlloc(int 2) # constructor
398
+ ---
399
+ ~NoisyAlloc() # Destructor
400
+ noisy delete # operator delete
401
+ """
402
+ )
403
+
404
+
405
+ def test_reallocation_d(capture, msg):
406
+ with capture:
407
+ create_and_destroy(2.5, 3)
408
+ assert msg(capture) == strip_comments(
409
+ """
410
+ NoisyAlloc(double 2.5) # construction (local func variable: operator_new not called)
411
+ noisy new # return-by-value "new" part 1: allocation
412
+ ~NoisyAlloc() # moved-away local func variable destruction
413
+ ---
414
+ ~NoisyAlloc() # Destructor
415
+ noisy delete # operator delete
416
+ """
417
+ )
418
+
419
+
420
+ def test_reallocation_e(capture, msg):
421
+ with capture:
422
+ create_and_destroy(3.5, 4.5)
423
+ assert msg(capture) == strip_comments(
424
+ """
425
+ noisy new # preallocation needed before invoking placement-new overload
426
+ noisy placement new # Placement new
427
+ NoisyAlloc(double 3.5) # construction
428
+ ---
429
+ ~NoisyAlloc() # Destructor
430
+ noisy delete # operator delete
431
+ """
432
+ )
433
+
434
+
435
+ def test_reallocation_f(capture, msg):
436
+ with capture:
437
+ create_and_destroy(4, 0.5)
438
+ assert msg(capture) == strip_comments(
439
+ """
440
+ noisy new # preallocation needed before invoking placement-new overload
441
+ noisy delete # deallocation of preallocated storage
442
+ noisy new # Factory pointer allocation
443
+ NoisyAlloc(int 4) # factory pointer construction
444
+ ---
445
+ ~NoisyAlloc() # Destructor
446
+ noisy delete # operator delete
447
+ """
448
+ )
449
+
450
+
451
+ def test_reallocation_g(capture, msg):
452
+ with capture:
453
+ create_and_destroy(5, "hi")
454
+ assert msg(capture) == strip_comments(
455
+ """
456
+ noisy new # preallocation needed before invoking first placement new
457
+ noisy delete # delete before considering new-style constructor
458
+ noisy new # preallocation for second placement new
459
+ noisy placement new # Placement new in the second placement new overload
460
+ NoisyAlloc(int 5) # construction
461
+ ---
462
+ ~NoisyAlloc() # Destructor
463
+ noisy delete # operator delete
464
+ """
465
+ )
466
+
467
+
468
+ @pytest.mark.skipif("env.PY2")
469
+ def test_invalid_self():
470
+ """Tests invocation of the pybind-registered base class with an invalid `self` argument. You
471
+ can only actually do this on Python 3: Python 2 raises an exception itself if you try."""
472
+
473
+ class NotPybindDerived(object):
474
+ pass
475
+
476
+ # Attempts to initialize with an invalid type passed as `self`:
477
+ class BrokenTF1(m.TestFactory1):
478
+ def __init__(self, bad):
479
+ if bad == 1:
480
+ a = m.TestFactory2(tag.pointer, 1)
481
+ m.TestFactory1.__init__(a, tag.pointer)
482
+ elif bad == 2:
483
+ a = NotPybindDerived()
484
+ m.TestFactory1.__init__(a, tag.pointer)
485
+
486
+ # Same as above, but for a class with an alias:
487
+ class BrokenTF6(m.TestFactory6):
488
+ def __init__(self, bad):
489
+ if bad == 0:
490
+ m.TestFactory6.__init__()
491
+ elif bad == 1:
492
+ a = m.TestFactory2(tag.pointer, 1)
493
+ m.TestFactory6.__init__(a, tag.base, 1)
494
+ elif bad == 2:
495
+ a = m.TestFactory2(tag.pointer, 1)
496
+ m.TestFactory6.__init__(a, tag.alias, 1)
497
+ elif bad == 3:
498
+ m.TestFactory6.__init__(
499
+ NotPybindDerived.__new__(NotPybindDerived), tag.base, 1
500
+ )
501
+ elif bad == 4:
502
+ m.TestFactory6.__init__(
503
+ NotPybindDerived.__new__(NotPybindDerived), tag.alias, 1
504
+ )
505
+
506
+ for arg in (1, 2):
507
+ with pytest.raises(TypeError) as excinfo:
508
+ BrokenTF1(arg)
509
+ assert (
510
+ str(excinfo.value)
511
+ == "__init__(self, ...) called with invalid or missing `self` argument"
512
+ )
513
+
514
+ for arg in (0, 1, 2, 3, 4):
515
+ with pytest.raises(TypeError) as excinfo:
516
+ BrokenTF6(arg)
517
+ assert (
518
+ str(excinfo.value)
519
+ == "__init__(self, ...) called with invalid or missing `self` argument"
520
+ )
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_gil_scoped.cpp ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ tests/test_gil_scoped.cpp -- acquire and release gil
3
+
4
+ Copyright (c) 2017 Borja Zarco (Google LLC) <[email protected]>
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 <pybind11/functional.h>
12
+
13
+
14
+ class VirtClass {
15
+ public:
16
+ virtual ~VirtClass() = default;
17
+ VirtClass() = default;
18
+ VirtClass(const VirtClass&) = delete;
19
+ virtual void virtual_func() {}
20
+ virtual void pure_virtual_func() = 0;
21
+ };
22
+
23
+ class PyVirtClass : public VirtClass {
24
+ void virtual_func() override {
25
+ PYBIND11_OVERRIDE(void, VirtClass, virtual_func,);
26
+ }
27
+ void pure_virtual_func() override {
28
+ PYBIND11_OVERRIDE_PURE(void, VirtClass, pure_virtual_func,);
29
+ }
30
+ };
31
+
32
+ TEST_SUBMODULE(gil_scoped, m) {
33
+ py::class_<VirtClass, PyVirtClass>(m, "VirtClass")
34
+ .def(py::init<>())
35
+ .def("virtual_func", &VirtClass::virtual_func)
36
+ .def("pure_virtual_func", &VirtClass::pure_virtual_func);
37
+
38
+ m.def("test_callback_py_obj", [](py::object &func) { func(); });
39
+ m.def("test_callback_std_func", [](const std::function<void()> &func) { func(); });
40
+ m.def("test_callback_virtual_func", [](VirtClass &virt) { virt.virtual_func(); });
41
+ m.def("test_callback_pure_virtual_func", [](VirtClass &virt) { virt.pure_virtual_func(); });
42
+ m.def("test_cross_module_gil", []() {
43
+ auto cm = py::module_::import("cross_module_gil_utils");
44
+ auto gil_acquire
45
+ = reinterpret_cast<void (*)()>(PyLong_AsVoidPtr(cm.attr("gil_acquire_funcaddr").ptr()));
46
+ py::gil_scoped_release gil_release;
47
+ gil_acquire();
48
+ });
49
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_gil_scoped.py ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ import multiprocessing
3
+ import threading
4
+
5
+ from pybind11_tests import gil_scoped as m
6
+
7
+
8
+ def _run_in_process(target, *args, **kwargs):
9
+ """Runs target in process and returns its exitcode after 10s (None if still alive)."""
10
+ process = multiprocessing.Process(target=target, args=args, kwargs=kwargs)
11
+ process.daemon = True
12
+ try:
13
+ process.start()
14
+ # Do not need to wait much, 10s should be more than enough.
15
+ process.join(timeout=10)
16
+ return process.exitcode
17
+ finally:
18
+ if process.is_alive():
19
+ process.terminate()
20
+
21
+
22
+ def _python_to_cpp_to_python():
23
+ """Calls different C++ functions that come back to Python."""
24
+
25
+ class ExtendedVirtClass(m.VirtClass):
26
+ def virtual_func(self):
27
+ pass
28
+
29
+ def pure_virtual_func(self):
30
+ pass
31
+
32
+ extended = ExtendedVirtClass()
33
+ m.test_callback_py_obj(lambda: None)
34
+ m.test_callback_std_func(lambda: None)
35
+ m.test_callback_virtual_func(extended)
36
+ m.test_callback_pure_virtual_func(extended)
37
+
38
+
39
+ def _python_to_cpp_to_python_from_threads(num_threads, parallel=False):
40
+ """Calls different C++ functions that come back to Python, from Python threads."""
41
+ threads = []
42
+ for _ in range(num_threads):
43
+ thread = threading.Thread(target=_python_to_cpp_to_python)
44
+ thread.daemon = True
45
+ thread.start()
46
+ if parallel:
47
+ threads.append(thread)
48
+ else:
49
+ thread.join()
50
+ for thread in threads:
51
+ thread.join()
52
+
53
+
54
+ # TODO: FIXME, sometimes returns -11 (segfault) instead of 0 on macOS Python 3.9
55
+ def test_python_to_cpp_to_python_from_thread():
56
+ """Makes sure there is no GIL deadlock when running in a thread.
57
+
58
+ It runs in a separate process to be able to stop and assert if it deadlocks.
59
+ """
60
+ assert _run_in_process(_python_to_cpp_to_python_from_threads, 1) == 0
61
+
62
+
63
+ # TODO: FIXME on macOS Python 3.9
64
+ def test_python_to_cpp_to_python_from_thread_multiple_parallel():
65
+ """Makes sure there is no GIL deadlock when running in a thread multiple times in parallel.
66
+
67
+ It runs in a separate process to be able to stop and assert if it deadlocks.
68
+ """
69
+ assert _run_in_process(_python_to_cpp_to_python_from_threads, 8, parallel=True) == 0
70
+
71
+
72
+ # TODO: FIXME on macOS Python 3.9
73
+ def test_python_to_cpp_to_python_from_thread_multiple_sequential():
74
+ """Makes sure there is no GIL deadlock when running in a thread multiple times sequentially.
75
+
76
+ It runs in a separate process to be able to stop and assert if it deadlocks.
77
+ """
78
+ assert (
79
+ _run_in_process(_python_to_cpp_to_python_from_threads, 8, parallel=False) == 0
80
+ )
81
+
82
+
83
+ # TODO: FIXME on macOS Python 3.9
84
+ def test_python_to_cpp_to_python_from_process():
85
+ """Makes sure there is no GIL deadlock when using processes.
86
+
87
+ This test is for completion, but it was never an issue.
88
+ """
89
+ assert _run_in_process(_python_to_cpp_to_python) == 0
90
+
91
+
92
+ def test_cross_module_gil():
93
+ """Makes sure that the GIL can be acquired by another module from a GIL-released state."""
94
+ m.test_cross_module_gil() # Should not raise a SIGSEGV
third-party/DPVO/Pangolin/components/pango_python/pybind11/tests/test_iostream.cpp ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ tests/test_iostream.cpp -- Usage of scoped_output_redirect
3
+
4
+ Copyright (c) 2017 Henry F. Schreiner
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
+ #if defined(_MSC_VER) && _MSC_VER < 1910 // VS 2015's MSVC
11
+ # pragma warning(disable: 4702) // unreachable code in system header (xatomic.h(382))
12
+ #endif
13
+
14
+ #include <pybind11/iostream.h>
15
+ #include "pybind11_tests.h"
16
+ #include <atomic>
17
+ #include <iostream>
18
+ #include <mutex>
19
+ #include <string>
20
+ #include <thread>
21
+
22
+ void noisy_function(const std::string &msg, bool flush) {
23
+
24
+ std::cout << msg;
25
+ if (flush)
26
+ std::cout << std::flush;
27
+ }
28
+
29
+ void noisy_funct_dual(const std::string &msg, const std::string &emsg) {
30
+ std::cout << msg;
31
+ std::cerr << emsg;
32
+ }
33
+
34
+ // object to manage C++ thread
35
+ // simply repeatedly write to std::cerr until stopped
36
+ // redirect is called at some point to test the safety of scoped_estream_redirect
37
+ struct TestThread {
38
+ TestThread() : stop_{false} {
39
+ auto thread_f = [this] {
40
+ static std::mutex cout_mutex;
41
+ while (!stop_) {
42
+ {
43
+ // #HelpAppreciated: Work on iostream.h thread safety.
44
+ // Without this lock, the clang ThreadSanitizer (tsan) reliably reports a
45
+ // data race, and this test is predictably flakey on Windows.
46
+ // For more background see the discussion under
47
+ // https://github.com/pybind/pybind11/pull/2982 and
48
+ // https://github.com/pybind/pybind11/pull/2995.
49
+ const std::lock_guard<std::mutex> lock(cout_mutex);
50
+ std::cout << "x" << std::flush;
51
+ }
52
+ std::this_thread::sleep_for(std::chrono::microseconds(50));
53
+ } };
54
+ t_ = new std::thread(std::move(thread_f));
55
+ }
56
+
57
+ ~TestThread() {
58
+ delete t_;
59
+ }
60
+
61
+ void stop() { stop_ = true; }
62
+
63
+ void join() const {
64
+ py::gil_scoped_release gil_lock;
65
+ t_->join();
66
+ }
67
+
68
+ void sleep() {
69
+ py::gil_scoped_release gil_lock;
70
+ std::this_thread::sleep_for(std::chrono::milliseconds(50));
71
+ }
72
+
73
+ std::thread *t_{nullptr};
74
+ std::atomic<bool> stop_;
75
+ };
76
+
77
+
78
+ TEST_SUBMODULE(iostream, m) {
79
+
80
+ add_ostream_redirect(m);
81
+
82
+ // test_evals
83
+
84
+ m.def("captured_output_default", [](const std::string &msg) {
85
+ py::scoped_ostream_redirect redir;
86
+ std::cout << msg << std::flush;
87
+ });
88
+
89
+ m.def("captured_output", [](const std::string &msg) {
90
+ py::scoped_ostream_redirect redir(std::cout, py::module_::import("sys").attr("stdout"));
91
+ std::cout << msg << std::flush;
92
+ });
93
+
94
+ m.def("guard_output", &noisy_function,
95
+ py::call_guard<py::scoped_ostream_redirect>(),
96
+ py::arg("msg"), py::arg("flush")=true);
97
+
98
+ m.def("captured_err", [](const std::string &msg) {
99
+ py::scoped_ostream_redirect redir(std::cerr, py::module_::import("sys").attr("stderr"));
100
+ std::cerr << msg << std::flush;
101
+ });
102
+
103
+ m.def("noisy_function", &noisy_function, py::arg("msg"), py::arg("flush") = true);
104
+
105
+ m.def("dual_guard", &noisy_funct_dual,
106
+ py::call_guard<py::scoped_ostream_redirect, py::scoped_estream_redirect>(),
107
+ py::arg("msg"), py::arg("emsg"));
108
+
109
+ m.def("raw_output", [](const std::string &msg) { std::cout << msg << std::flush; });
110
+
111
+ m.def("raw_err", [](const std::string &msg) { std::cerr << msg << std::flush; });
112
+
113
+ m.def("captured_dual", [](const std::string &msg, const std::string &emsg) {
114
+ py::scoped_ostream_redirect redirout(std::cout, py::module_::import("sys").attr("stdout"));
115
+ py::scoped_ostream_redirect redirerr(std::cerr, py::module_::import("sys").attr("stderr"));
116
+ std::cout << msg << std::flush;
117
+ std::cerr << emsg << std::flush;
118
+ });
119
+
120
+ py::class_<TestThread>(m, "TestThread")
121
+ .def(py::init<>())
122
+ .def("stop", &TestThread::stop)
123
+ .def("join", &TestThread::join)
124
+ .def("sleep", &TestThread::sleep);
125
+ }