Skip to main content

Include/internal/pycore_memoryobject.h

Overview

Include/internal/pycore_memoryobject.h is a roughly 40-line internal header that exposes the private internals of the memoryview machinery. The public API (PyMemoryView_FromObject, PyMemoryView_FromMemory, etc.) lives in Include/memoryobject.h. This internal header adds:

  • _PyManagedBuffer_Type -- the hidden object that holds the exporter reference and the Py_buffer struct, shared among all views derived from the same export.
  • _PyMemoryView_FromBufferProc -- a way to create a memoryview directly from a Py_buffer that was filled in by C code rather than by calling PyObject_GetBuffer.
  • _PyMemoryView_GetBuffer -- an accessor that reaches into the internals of a memoryview object to retrieve the underlying Py_buffer pointer without going through the public slot.

Understanding the relationship between _PyManagedBuffer and PyMemoryView is essential for anyone porting or reimplementing the buffer protocol.

Reading Subsections

1. The managed buffer object

// Include/internal/pycore_memoryobject.h (CPython 3.14)

/* Flags for _PyManagedBufferObject.flags */
#define _Py_MANAGED_BUFFER_RELEASED 0x001 /* PyBuffer_Release() was called */
#define _Py_MANAGED_BUFFER_FREE_FORMAT 0x002 /* format string must be freed */

typedef struct {
PyObject_HEAD
int flags; /* combination of the flags above */
Py_ssize_t exports; /* number of memoryview objects pointing here */
Py_buffer master; /* the Py_buffer obtained from the exporter */
} _PyManagedBufferObject;

PyAPI_DATA(PyTypeObject) _PyManagedBuffer_Type;

2. Creating a memoryview from a pre-filled Py_buffer

// Include/internal/pycore_memoryobject.h (CPython 3.14)

/* Create a new memoryview from a Py_buffer that has already been filled
in by the caller. The memoryview takes ownership of the buffer:
PyBuffer_Release() will be called on it when the last view is
released. Returns a new reference, or NULL on error. */
PyAPI_FUNC(PyObject *)
_PyMemoryView_FromBufferProc(PyObject *base,
int flags,
getbufferproc bufferproc);

3. Accessing the raw Py_buffer from a memoryview

// Include/internal/pycore_memoryobject.h (CPython 3.14)

/* Return the Py_buffer* for the given memoryview object.
The caller must ensure mview is a PyMemoryView_Object*.
The returned pointer is valid as long as mview is alive. */
static inline Py_buffer *
_PyMemoryView_GetBuffer(PyObject *mview)
{
assert(PyMemoryView_Check(mview));
return &((_PyMemoryViewObject *)mview)->view;
}

Port status

Not yet ported to gopy. The buffer protocol is a prerequisite for memoryview support. A gopy port would represent _PyManagedBufferObject as a Go struct holding a reference count, an exporter Object pointer, and an equivalent of Py_buffer (shape, strides, format string, and a raw unsafe.Pointer to the data).