with self.assertRaises(SystemError):
obj.__buffer__(inspect.BufferFlags.WRITE)
+ @support.cpython_only
+ @unittest.skipIf(_testcapi is None, "requires _testcapi")
+ def test_bytearray_alignment(self):
+ # gh-140557: pointer alignment of buffers including empty allocation
+ # should be at least to `size_t`.
+ align = struct.calcsize("N")
+ cases = [
+ bytearray(),
+ bytearray(1),
+ bytearray(b"0123456789abcdef"),
+ bytearray(16),
+ ]
+ ptrs = [_testcapi.buffer_pointer_as_int(array) for array in cases]
+ self.assertEqual([ptr % align for ptr in ptrs], [0]*len(ptrs))
+
+ @support.cpython_only
+ @unittest.skipIf(_testcapi is None, "requires _testcapi")
+ def test_array_alignment(self):
+ # gh-140557: pointer alignment of buffers including empty allocation
+ # should match the maximum array alignment.
+ align = max(struct.calcsize(fmt) for fmt in ARRAY)
+ cases = [array.array(fmt) for fmt in ARRAY]
+ # Empty arrays
+ self.assertEqual(
+ [_testcapi.buffer_pointer_as_int(case) % align for case in cases],
+ [0] * len(cases),
+ )
+ for case in cases:
+ case.append(0)
+ # Allocated arrays
+ self.assertEqual(
+ [_testcapi.buffer_pointer_as_int(case) % align for case in cases],
+ [0] * len(cases),
+ )
+
@support.cpython_only
def test_pybuffer_size_from_format(self):
# basic tests
.tp_members = testbuf_members
};
+/* Get the pointer from a buffer-supporting object as a PyLong.
+ *
+ * Used to test alignment properties. */
+static PyObject *
+buffer_pointer_as_int(PyObject *Py_UNUSED(module), PyObject *obj)
+{
+ PyObject *out;
+ Py_buffer view;
+ if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) != 0) {
+ return NULL;
+ }
+ out = PyLong_FromVoidPtr(view.buf);
+ PyBuffer_Release(&view);
+ return out;
+}
+
+static PyMethodDef test_methods[] = {
+ {"buffer_pointer_as_int", buffer_pointer_as_int, METH_O},
+ {NULL},
+};
+
int
_PyTestCapi_Init_Buffer(PyObject *m) {
if (PyType_Ready(&testBufType) < 0) {
if (PyModule_AddObjectRef(m, "testBuf", (PyObject *)&testBufType)) {
return -1;
}
+ if (PyModule_AddFunctions(m, test_methods) < 0) {
+ return -1;
+ }
return 0;
}