MCPcopy Create free account
hub / github.com/pybind/pybind11 / pybind11_getbuffer

Function pybind11_getbuffer

include/pybind11/detail/class.h:627–725  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

625
626/// buffer_protocol: Fill in the view as specified by flags.
627extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int flags) {
628 // Look for a `get_buffer` implementation in this type's info or any bases (following MRO).
629 type_info *tinfo = nullptr;
630 for (auto type : reinterpret_borrow<tuple>(Py_TYPE(obj)->tp_mro)) {
631 tinfo = get_type_info((PyTypeObject *) type.ptr());
632 if (tinfo && tinfo->get_buffer) {
633 break;
634 }
635 }
636 if (view == nullptr || !tinfo || !tinfo->get_buffer) {
637 if (view) {
638 view->obj = nullptr;
639 }
640 set_error(PyExc_BufferError, "pybind11_getbuffer(): Internal error");
641 return -1;
642 }
643 std::memset(view, 0, sizeof(Py_buffer));
644 std::unique_ptr<buffer_info> info = nullptr;
645 try {
646 info.reset(tinfo->get_buffer(obj, tinfo->get_buffer_data));
647 } catch (...) {
648 try_translate_exceptions();
649 raise_from(PyExc_BufferError, "Error getting buffer");
650 return -1;
651 }
652 if (info == nullptr) {
653 pybind11_fail("FATAL UNEXPECTED SITUATION: tinfo->get_buffer() returned nullptr.");
654 }
655
656 if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE && info->readonly) {
657 // view->obj = nullptr; // Was just memset to 0, so not necessary
658 set_error(PyExc_BufferError, "Writable buffer requested for readonly storage");
659 return -1;
660 }
661
662 // Fill in all the information, and then downgrade as requested by the caller, or raise an
663 // error if that's not possible.
664 view->itemsize = info->itemsize;
665 view->len = view->itemsize;
666 for (auto s : info->shape) {
667 view->len *= s;
668 }
669 view->ndim = static_cast<int>(info->ndim);
670 view->shape = info->shape.data();
671 view->strides = info->strides.data();
672 view->readonly = static_cast<int>(info->readonly);
673 if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {
674 view->format = const_cast<char *>(info->format.c_str());
675 }
676
677 // Note, all contiguity flags imply PyBUF_STRIDES and lower.
678 if ((flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) {
679 if (PyBuffer_IsContiguous(view, 'C') == 0) {
680 std::memset(view, 0, sizeof(Py_buffer));
681 set_error(PyExc_BufferError,
682 "C-contiguous buffer requested for discontiguous storage");
683 return -1;
684 }

Callers

nothing calls this directly

Calls 7

try_translate_exceptionsFunction · 0.85
raise_fromFunction · 0.85
ptrMethod · 0.80
releaseMethod · 0.80
set_errorFunction · 0.50
get_bufferMethod · 0.45
dataMethod · 0.45

Tested by

no test coverage detected