File tree 3 files changed +28
-2
lines changed 3 files changed +28
-2
lines changed Original file line number Diff line number Diff line change @@ -447,11 +447,17 @@ inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) {
447
447
448
448
// / buffer_protocol: Fill in the view as specified by flags.
449
449
extern " C" inline int pybind11_getbuffer (PyObject *obj, Py_buffer *view, int flags) {
450
- auto tinfo = get_type_info (Py_TYPE (obj));
450
+ // Look for a `get_buffer` implementation in this type's info or any bases (following MRO).
451
+ type_info *tinfo = nullptr ;
452
+ for (auto type : reinterpret_borrow<tuple>(Py_TYPE (obj)->tp_mro )) {
453
+ tinfo = get_type_info ((PyTypeObject *) type.ptr ());
454
+ if (tinfo && tinfo->get_buffer )
455
+ break ;
456
+ }
451
457
if (view == nullptr || obj == nullptr || !tinfo || !tinfo->get_buffer ) {
452
458
if (view)
453
459
view->obj = nullptr ;
454
- PyErr_SetString (PyExc_BufferError, " generic_type::getbuffer (): Internal error" );
460
+ PyErr_SetString (PyExc_BufferError, " pybind11_getbuffer (): Internal error" );
455
461
return -1 ;
456
462
}
457
463
memset (view, 0 , sizeof (Py_buffer));
Original file line number Diff line number Diff line change @@ -74,6 +74,11 @@ class Matrix {
74
74
float *m_data;
75
75
};
76
76
77
+ class SquareMatrix : public Matrix {
78
+ public:
79
+ SquareMatrix (ssize_t n) : Matrix(n, n) { }
80
+ };
81
+
77
82
struct PTMFBuffer {
78
83
int32_t value = 0 ;
79
84
@@ -141,6 +146,10 @@ test_initializer buffers([](py::module &m) {
141
146
})
142
147
;
143
148
149
+ // Derived classes inherit the buffer protocol and the buffer access function
150
+ py::class_<SquareMatrix, Matrix>(m, " SquareMatrix" )
151
+ .def (py::init<ssize_t >());
152
+
144
153
py::class_<PTMFBuffer>(m, " PTMFBuffer" , py::buffer_protocol ())
145
154
.def (py::init<>())
146
155
.def_readwrite (" value" , &PTMFBuffer::value)
Original file line number Diff line number Diff line change @@ -36,6 +36,7 @@ def test_from_python():
36
36
@pytest .unsupported_on_pypy
37
37
def test_to_python ():
38
38
m = Matrix (5 , 5 )
39
+ assert memoryview (m ).shape == (5 , 5 )
39
40
40
41
assert m [2 , 3 ] == 0
41
42
m [2 , 3 ] = 4
@@ -63,6 +64,16 @@ def test_to_python():
63
64
assert cstats .move_assignments == 0
64
65
65
66
67
+ @pytest .unsupported_on_pypy
68
+ def test_inherited_protocol ():
69
+ """SquareMatrix is derived from Matrix and inherits the buffer protocol"""
70
+ from pybind11_tests import SquareMatrix
71
+
72
+ matrix = SquareMatrix (5 )
73
+ assert memoryview (matrix ).shape == (5 , 5 )
74
+ assert np .asarray (matrix ).shape == (5 , 5 )
75
+
76
+
66
77
@pytest .unsupported_on_pypy
67
78
def test_ptmf ():
68
79
for cls in [PTMFBuffer , ConstPTMFBuffer , DerivedPTMFBuffer ]:
You can’t perform that action at this time.
0 commit comments