Skip to content

Commit f7c4e23

Browse files
authored
bpo-40724: Support setting buffer slots from type specs (GH-20648)
This is not part of the limited API but makes the buffer slots available for type specs.
1 parent 68874a8 commit f7c4e23

File tree

5 files changed

+60
-2
lines changed

5 files changed

+60
-2
lines changed

Include/typeslots.h

+5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
/* Do not renumber the file; these numbers are part of the stable ABI. */
2+
#if defined(Py_LIMITED_API)
23
/* Disabled, see #10181 */
34
#undef Py_bf_getbuffer
45
#undef Py_bf_releasebuffer
6+
#else
7+
#define Py_bf_getbuffer 1
8+
#define Py_bf_releasebuffer 2
9+
#endif
510
#define Py_mp_ass_subscript 3
611
#define Py_mp_length 4
712
#define Py_mp_subscript 5

Lib/test/test_capi.py

+5
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,11 @@ def test_heaptype_with_weakref(self):
477477
self.assertEqual(ref(), inst)
478478
self.assertEqual(inst.weakreflist, ref)
479479

480+
def test_heaptype_with_buffer(self):
481+
inst = _testcapi.HeapCTypeWithBuffer()
482+
b = bytes(inst)
483+
self.assertEqual(b, b"1234")
484+
480485
def test_c_subclass_of_heap_ctype_with_tpdealloc_decrefs_once(self):
481486
subclass_instance = _testcapi.HeapCTypeSubclass()
482487
type_refcnt = sys.getrefcount(_testcapi.HeapCTypeSubclass)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Allow defining buffer slots in type specs.

Modules/_testcapimodule.c

+47
Original file line numberDiff line numberDiff line change
@@ -6298,6 +6298,47 @@ static PyType_Spec HeapCTypeSubclass_spec = {
62986298
HeapCTypeSubclass_slots
62996299
};
63006300

6301+
PyDoc_STRVAR(heapctypewithbuffer__doc__,
6302+
"Heap type with buffer support.\n\n"
6303+
"The buffer is set to [b'1', b'2', b'3', b'4']");
6304+
6305+
typedef struct {
6306+
HeapCTypeObject base;
6307+
char buffer[4];
6308+
} HeapCTypeWithBufferObject;
6309+
6310+
static int
6311+
heapctypewithbuffer_getbuffer(HeapCTypeWithBufferObject *self, Py_buffer *view, int flags)
6312+
{
6313+
self->buffer[0] = '1';
6314+
self->buffer[1] = '2';
6315+
self->buffer[2] = '3';
6316+
self->buffer[3] = '4';
6317+
return PyBuffer_FillInfo(
6318+
view, (PyObject*)self, (void *)self->buffer, 4, 1, flags);
6319+
}
6320+
6321+
static int
6322+
heapctypewithbuffer_releasebuffer(HeapCTypeWithBufferObject *self, Py_buffer *view)
6323+
{
6324+
assert(view->obj == (void*) self);
6325+
}
6326+
6327+
static PyType_Slot HeapCTypeWithBuffer_slots[] = {
6328+
{Py_bf_getbuffer, heapctypewithbuffer_getbuffer},
6329+
{Py_bf_releasebuffer, heapctypewithbuffer_releasebuffer},
6330+
{Py_tp_doc, (char*)heapctypewithbuffer__doc__},
6331+
{0, 0},
6332+
};
6333+
6334+
static PyType_Spec HeapCTypeWithBuffer_spec = {
6335+
"_testcapi.HeapCTypeWithBuffer",
6336+
sizeof(HeapCTypeWithBufferObject),
6337+
0,
6338+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
6339+
HeapCTypeWithBuffer_slots
6340+
};
6341+
63016342
PyDoc_STRVAR(heapctypesubclasswithfinalizer__doc__,
63026343
"Subclass of HeapCType with a finalizer that reassigns __class__.\n\n"
63036344
"__class__ is set to plain HeapCTypeSubclass during finalization.\n"
@@ -6775,6 +6816,12 @@ PyInit__testcapi(void)
67756816
}
67766817
PyModule_AddObject(m, "HeapCTypeWithWeakref", HeapCTypeWithWeakref);
67776818

6819+
PyObject *HeapCTypeWithBuffer = PyType_FromSpec(&HeapCTypeWithBuffer_spec);
6820+
if (HeapCTypeWithBuffer == NULL) {
6821+
return NULL;
6822+
}
6823+
PyModule_AddObject(m, "HeapCTypeWithBuffer", HeapCTypeWithBuffer);
6824+
67786825
PyObject *subclass_with_finalizer_bases = PyTuple_Pack(1, HeapCTypeSubclass);
67796826
if (subclass_with_finalizer_bases == NULL) {
67806827
return NULL;

Objects/typeslots.inc

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)