mirror of https://github.com/python/cpython
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.
This commit is contained in:
parent
68874a8502
commit
f7c4e23642
|
@ -1,7 +1,12 @@
|
||||||
/* Do not renumber the file; these numbers are part of the stable ABI. */
|
/* Do not renumber the file; these numbers are part of the stable ABI. */
|
||||||
|
#if defined(Py_LIMITED_API)
|
||||||
/* Disabled, see #10181 */
|
/* Disabled, see #10181 */
|
||||||
#undef Py_bf_getbuffer
|
#undef Py_bf_getbuffer
|
||||||
#undef Py_bf_releasebuffer
|
#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_ass_subscript 3
|
||||||
#define Py_mp_length 4
|
#define Py_mp_length 4
|
||||||
#define Py_mp_subscript 5
|
#define Py_mp_subscript 5
|
||||||
|
|
|
@ -477,6 +477,11 @@ class CAPITest(unittest.TestCase):
|
||||||
self.assertEqual(ref(), inst)
|
self.assertEqual(ref(), inst)
|
||||||
self.assertEqual(inst.weakreflist, ref)
|
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):
|
def test_c_subclass_of_heap_ctype_with_tpdealloc_decrefs_once(self):
|
||||||
subclass_instance = _testcapi.HeapCTypeSubclass()
|
subclass_instance = _testcapi.HeapCTypeSubclass()
|
||||||
type_refcnt = sys.getrefcount(_testcapi.HeapCTypeSubclass)
|
type_refcnt = sys.getrefcount(_testcapi.HeapCTypeSubclass)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Allow defining buffer slots in type specs.
|
|
@ -6298,6 +6298,47 @@ static PyType_Spec HeapCTypeSubclass_spec = {
|
||||||
HeapCTypeSubclass_slots
|
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__,
|
PyDoc_STRVAR(heapctypesubclasswithfinalizer__doc__,
|
||||||
"Subclass of HeapCType with a finalizer that reassigns __class__.\n\n"
|
"Subclass of HeapCType with a finalizer that reassigns __class__.\n\n"
|
||||||
"__class__ is set to plain HeapCTypeSubclass during finalization.\n"
|
"__class__ is set to plain HeapCTypeSubclass during finalization.\n"
|
||||||
|
@ -6775,6 +6816,12 @@ PyInit__testcapi(void)
|
||||||
}
|
}
|
||||||
PyModule_AddObject(m, "HeapCTypeWithWeakref", HeapCTypeWithWeakref);
|
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);
|
PyObject *subclass_with_finalizer_bases = PyTuple_Pack(1, HeapCTypeSubclass);
|
||||||
if (subclass_with_finalizer_bases == NULL) {
|
if (subclass_with_finalizer_bases == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* Generated by typeslots.py */
|
/* Generated by typeslots.py */
|
||||||
0,
|
offsetof(PyHeapTypeObject, as_buffer.bf_getbuffer),
|
||||||
0,
|
offsetof(PyHeapTypeObject, as_buffer.bf_releasebuffer),
|
||||||
offsetof(PyHeapTypeObject, as_mapping.mp_ass_subscript),
|
offsetof(PyHeapTypeObject, as_mapping.mp_ass_subscript),
|
||||||
offsetof(PyHeapTypeObject, as_mapping.mp_length),
|
offsetof(PyHeapTypeObject, as_mapping.mp_length),
|
||||||
offsetof(PyHeapTypeObject, as_mapping.mp_subscript),
|
offsetof(PyHeapTypeObject, as_mapping.mp_subscript),
|
||||||
|
|
Loading…
Reference in New Issue