summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorJelle Zijlstra <jelle.zijlstra@gmail.com>2023-05-04 14:59:46 (GMT)
committerGitHub <noreply@github.com>2023-05-04 14:59:46 (GMT)
commit04f673327530f47f002e784459037231de478412 (patch)
tree56b29e35a1147b9655b5f4b4337f8a2f905b0e3f /Modules
parentb17d32c1142d16a5fea0c95bce185bf9be696491 (diff)
downloadcpython-04f673327530f47f002e784459037231de478412.zip
cpython-04f673327530f47f002e784459037231de478412.tar.gz
cpython-04f673327530f47f002e784459037231de478412.tar.bz2
gh-102500: Implement PEP 688 (#102521)
Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
Diffstat (limited to 'Modules')
-rw-r--r--Modules/Setup.stdlib.in2
-rw-r--r--Modules/_testcapi/buffer.c102
-rw-r--r--Modules/_testcapi/parts.h1
-rw-r--r--Modules/_testcapimodule.c4
4 files changed, 107 insertions, 2 deletions
diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in
index 6b48334..a7803cf 100644
--- a/Modules/Setup.stdlib.in
+++ b/Modules/Setup.stdlib.in
@@ -169,7 +169,7 @@
@MODULE__XXTESTFUZZ_TRUE@_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c
@MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c
@MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c
-@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c _testcapi/unicode.c _testcapi/getargs.c _testcapi/pytime.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/structmember.c _testcapi/exceptions.c _testcapi/code.c _testcapi/pyos.c _testcapi/immortal.c _testcapi/heaptype_relative.c
+@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c _testcapi/unicode.c _testcapi/getargs.c _testcapi/pytime.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/structmember.c _testcapi/exceptions.c _testcapi/code.c _testcapi/buffer.c _testcapi/pyos.c _testcapi/immortal.c _testcapi/heaptype_relative.c
@MODULE__TESTCLINIC_TRUE@_testclinic _testclinic.c
# Some testing modules MUST be built as shared libraries.
diff --git a/Modules/_testcapi/buffer.c b/Modules/_testcapi/buffer.c
new file mode 100644
index 0000000..aff9a47
--- /dev/null
+++ b/Modules/_testcapi/buffer.c
@@ -0,0 +1,102 @@
+/* Test PEP 688 - Buffers */
+
+#include "parts.h"
+
+#include "structmember.h" // PyMemberDef
+#include <stddef.h> // offsetof
+
+typedef struct {
+ PyObject_HEAD
+ PyObject *obj;
+ Py_ssize_t references;
+} testBufObject;
+
+static PyObject *
+testbuf_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *obj = PyBytes_FromString("test");
+ if (obj == NULL) {
+ return NULL;
+ }
+ testBufObject *self = (testBufObject *)type->tp_alloc(type, 0);
+ if (self == NULL) {
+ Py_DECREF(obj);
+ return NULL;
+ }
+ self->obj = obj;
+ self->references = 0;
+ return (PyObject *)self;
+}
+
+static int
+testbuf_traverse(testBufObject *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->obj);
+ return 0;
+}
+
+static int
+testbuf_clear(testBufObject *self)
+{
+ Py_CLEAR(self->obj);
+ return 0;
+}
+
+static void
+testbuf_dealloc(testBufObject *self)
+{
+ PyObject_GC_UnTrack(self);
+ Py_XDECREF(self->obj);
+ Py_TYPE(self)->tp_free((PyObject *) self);
+}
+
+static int
+testbuf_getbuf(testBufObject *self, Py_buffer *view, int flags)
+{
+ int buf = PyObject_GetBuffer(self->obj, view, flags);
+ Py_SETREF(view->obj, Py_NewRef(self));
+ self->references++;
+ return buf;
+}
+
+static void
+testbuf_releasebuf(testBufObject *self, Py_buffer *view)
+{
+ self->references--;
+ assert(self->references >= 0);
+}
+
+static PyBufferProcs testbuf_as_buffer = {
+ .bf_getbuffer = (getbufferproc) testbuf_getbuf,
+ .bf_releasebuffer = (releasebufferproc) testbuf_releasebuf,
+};
+
+static struct PyMemberDef testbuf_members[] = {
+ {"references", T_PYSSIZET, offsetof(testBufObject, references), READONLY},
+ {NULL},
+};
+
+static PyTypeObject testBufType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "testBufType",
+ .tp_basicsize = sizeof(testBufObject),
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+ .tp_new = testbuf_new,
+ .tp_dealloc = (destructor) testbuf_dealloc,
+ .tp_traverse = (traverseproc) testbuf_traverse,
+ .tp_clear = (inquiry) testbuf_clear,
+ .tp_as_buffer = &testbuf_as_buffer,
+ .tp_members = testbuf_members
+};
+
+int
+_PyTestCapi_Init_Buffer(PyObject *m) {
+ if (PyType_Ready(&testBufType) < 0) {
+ return -1;
+ }
+ if (PyModule_AddObjectRef(m, "testBuf", (PyObject *)&testBufType)) {
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/Modules/_testcapi/parts.h b/Modules/_testcapi/parts.h
index d75412d..663d4f2 100644
--- a/Modules/_testcapi/parts.h
+++ b/Modules/_testcapi/parts.h
@@ -38,6 +38,7 @@ int _PyTestCapi_Init_Float(PyObject *module);
int _PyTestCapi_Init_Structmember(PyObject *module);
int _PyTestCapi_Init_Exceptions(PyObject *module);
int _PyTestCapi_Init_Code(PyObject *module);
+int _PyTestCapi_Init_Buffer(PyObject *module);
int _PyTestCapi_Init_PyOS(PyObject *module);
int _PyTestCapi_Init_Immortal(PyObject *module);
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 1ecc442..38f4758 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -3959,7 +3959,6 @@ static PyTypeObject MyList_Type = {
MyList_new, /* tp_new */
};
-
/* Test PEP 560 */
typedef struct {
@@ -4310,6 +4309,9 @@ PyInit__testcapi(void)
if (_PyTestCapi_Init_Code(m) < 0) {
return NULL;
}
+ if (_PyTestCapi_Init_Buffer(m) < 0) {
+ return NULL;
+ }
if (_PyTestCapi_Init_PyOS(m) < 0) {
return NULL;
}