diff options
author | scoder <stefan_ml@behnel.de> | 2020-06-06 19:35:10 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-06 19:35:10 (GMT) |
commit | f7c4e236429606e1c982cacf24e10fc86ef4462f (patch) | |
tree | d54aa7bc07169ac0a7c472d72d44e10b9dd16b3a | |
parent | 68874a8502da440a1dc4746cf73262648b870aee (diff) | |
download | cpython-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.h | 5 | ||||
-rw-r--r-- | Lib/test/test_capi.py | 5 | ||||
-rw-r--r-- | Misc/NEWS.d/next/C API/2020-06-04-08-01-23.bpo-40724.qIIdSi.rst | 1 | ||||
-rw-r--r-- | Modules/_testcapimodule.c | 47 | ||||
-rw-r--r-- | Objects/typeslots.inc | 4 |
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), |