]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-40724: Support setting buffer slots from type specs (GH-20648)
authorscoder <stefan_ml@behnel.de>
Sat, 6 Jun 2020 19:35:10 +0000 (21:35 +0200)
committerGitHub <noreply@github.com>
Sat, 6 Jun 2020 19:35:10 +0000 (21:35 +0200)
This is not part of the limited API but makes the buffer slots available for type specs.

Include/typeslots.h
Lib/test/test_capi.py
Misc/NEWS.d/next/C API/2020-06-04-08-01-23.bpo-40724.qIIdSi.rst [new file with mode: 0644]
Modules/_testcapimodule.c
Objects/typeslots.inc

index 0ce6a377dcfbd692e5b2204496a5c8dd8d7cc8f2..64f6fff51444937d70c3d2af414af0bfa040cbee 100644 (file)
@@ -1,7 +1,12 @@
 /* Do not renumber the file; these numbers are part of the stable ABI. */
+#if defined(Py_LIMITED_API)
 /* Disabled, see #10181 */
 #undef Py_bf_getbuffer
 #undef Py_bf_releasebuffer
+#else
+#define Py_bf_getbuffer 1
+#define Py_bf_releasebuffer 2
+#endif
 #define Py_mp_ass_subscript 3
 #define Py_mp_length 4
 #define Py_mp_subscript 5
index 5b8b9f6a86f4b27ab64d3f242a6cc00e0d9e261c..73e167a0b05a53310e4ea04940ed2980fadfcf56 100644 (file)
@@ -477,6 +477,11 @@ class CAPITest(unittest.TestCase):
         self.assertEqual(ref(), inst)
         self.assertEqual(inst.weakreflist, ref)
 
+    def test_heaptype_with_buffer(self):
+        inst = _testcapi.HeapCTypeWithBuffer()
+        b = bytes(inst)
+        self.assertEqual(b, b"1234")
+
     def test_c_subclass_of_heap_ctype_with_tpdealloc_decrefs_once(self):
         subclass_instance = _testcapi.HeapCTypeSubclass()
         type_refcnt = sys.getrefcount(_testcapi.HeapCTypeSubclass)
diff --git a/Misc/NEWS.d/next/C API/2020-06-04-08-01-23.bpo-40724.qIIdSi.rst b/Misc/NEWS.d/next/C API/2020-06-04-08-01-23.bpo-40724.qIIdSi.rst
new file mode 100644 (file)
index 0000000..82793db
--- /dev/null
@@ -0,0 +1 @@
+Allow defining buffer slots in type specs.
index 101d54932d913dfa0cb19bac61bf72caafb03610..d6a90b807d0267e84d13e3f70c1a7fefd1ab10e8 100644 (file)
@@ -6298,6 +6298,47 @@ static PyType_Spec HeapCTypeSubclass_spec = {
     HeapCTypeSubclass_slots
 };
 
+PyDoc_STRVAR(heapctypewithbuffer__doc__,
+"Heap type with buffer support.\n\n"
+"The buffer is set to [b'1', b'2', b'3', b'4']");
+
+typedef struct {
+    HeapCTypeObject base;
+    char buffer[4];
+} HeapCTypeWithBufferObject;
+
+static int
+heapctypewithbuffer_getbuffer(HeapCTypeWithBufferObject *self, Py_buffer *view, int flags)
+{
+    self->buffer[0] = '1';
+    self->buffer[1] = '2';
+    self->buffer[2] = '3';
+    self->buffer[3] = '4';
+    return PyBuffer_FillInfo(
+        view, (PyObject*)self, (void *)self->buffer, 4, 1, flags);
+}
+
+static int
+heapctypewithbuffer_releasebuffer(HeapCTypeWithBufferObject *self, Py_buffer *view)
+{
+    assert(view->obj == (void*) self);
+}
+
+static PyType_Slot HeapCTypeWithBuffer_slots[] = {
+    {Py_bf_getbuffer, heapctypewithbuffer_getbuffer},
+    {Py_bf_releasebuffer, heapctypewithbuffer_releasebuffer},
+    {Py_tp_doc, (char*)heapctypewithbuffer__doc__},
+    {0, 0},
+};
+
+static PyType_Spec HeapCTypeWithBuffer_spec = {
+    "_testcapi.HeapCTypeWithBuffer",
+    sizeof(HeapCTypeWithBufferObject),
+    0,
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+    HeapCTypeWithBuffer_slots
+};
+
 PyDoc_STRVAR(heapctypesubclasswithfinalizer__doc__,
 "Subclass of HeapCType with a finalizer that reassigns __class__.\n\n"
 "__class__ is set to plain HeapCTypeSubclass during finalization.\n"
@@ -6775,6 +6816,12 @@ PyInit__testcapi(void)
     }
     PyModule_AddObject(m, "HeapCTypeWithWeakref", HeapCTypeWithWeakref);
 
+    PyObject *HeapCTypeWithBuffer = PyType_FromSpec(&HeapCTypeWithBuffer_spec);
+    if (HeapCTypeWithBuffer == NULL) {
+        return NULL;
+    }
+    PyModule_AddObject(m, "HeapCTypeWithBuffer", HeapCTypeWithBuffer);
+
     PyObject *subclass_with_finalizer_bases = PyTuple_Pack(1, HeapCTypeSubclass);
     if (subclass_with_finalizer_bases == NULL) {
         return NULL;
index dc750cc0c41975963fb3af1a94286c6a2e356e5f..ffc9bb2e1c7710bc3ed96ccd4183a8bc5f910048 100644 (file)
@@ -1,6 +1,6 @@
 /* Generated by typeslots.py */
-0,
-0,
+offsetof(PyHeapTypeObject, as_buffer.bf_getbuffer),
+offsetof(PyHeapTypeObject, as_buffer.bf_releasebuffer),
 offsetof(PyHeapTypeObject, as_mapping.mp_ass_subscript),
 offsetof(PyHeapTypeObject, as_mapping.mp_length),
 offsetof(PyHeapTypeObject, as_mapping.mp_subscript),