summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorscoder <stefan_ml@behnel.de>2020-06-06 19:35:10 (GMT)
committerGitHub <noreply@github.com>2020-06-06 19:35:10 (GMT)
commitf7c4e236429606e1c982cacf24e10fc86ef4462f (patch)
treed54aa7bc07169ac0a7c472d72d44e10b9dd16b3a
parent68874a8502da440a1dc4746cf73262648b870aee (diff)
downloadcpython-f7c4e236429606e1c982cacf24e10fc86ef4462f.zip
cpython-f7c4e236429606e1c982cacf24e10fc86ef4462f.tar.gz
cpython-f7c4e236429606e1c982cacf24e10fc86ef4462f.tar.bz2
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.
-rw-r--r--Include/typeslots.h5
-rw-r--r--Lib/test/test_capi.py5
-rw-r--r--Misc/NEWS.d/next/C API/2020-06-04-08-01-23.bpo-40724.qIIdSi.rst1
-rw-r--r--Modules/_testcapimodule.c47
-rw-r--r--Objects/typeslots.inc4
5 files changed, 60 insertions, 2 deletions
diff --git a/Include/typeslots.h b/Include/typeslots.h
index 0ce6a37..64f6fff 100644
--- a/Include/typeslots.h
+++ b/Include/typeslots.h
@@ -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
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py
index 5b8b9f6..73e167a 100644
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -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
index 0000000..82793db
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2020-06-04-08-01-23.bpo-40724.qIIdSi.rst
@@ -0,0 +1 @@
+Allow defining buffer slots in type specs.
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 101d549..d6a90b8 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -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;
diff --git a/Objects/typeslots.inc b/Objects/typeslots.inc
index dc750cc..ffc9bb2 100644
--- a/Objects/typeslots.inc
+++ b/Objects/typeslots.inc
@@ -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),