File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -4447,6 +4447,43 @@ def test_bytearray_release_buffer_read_flag(self):
44474447 with self .assertRaises (SystemError ):
44484448 obj .__buffer__ (inspect .BufferFlags .WRITE )
44494449
4450+ @support .cpython_only
4451+ @unittest .skipIf (_testcapi is None , "requires _testcapi" )
4452+ @unittest .skipIf (ctypes is None , "requires ctypes" )
4453+ def test_bytearray_alignment (self ):
4454+ # gh-140557: pointer alignment of buffers including empty allocation
4455+ max_align = ctypes .alignment (ctypes .c_longdouble )
4456+ cases = [
4457+ bytearray (),
4458+ bytearray (1 ),
4459+ bytearray (b"0123456789abcdef" ),
4460+ bytearray (16 ),
4461+ ]
4462+ ptrs = [_testcapi .buffer_pointer_as_int (array ) for array in cases ]
4463+ self .assertEqual ([ptr % max_align for ptr in ptrs ], [0 ]* len (ptrs ))
4464+
4465+ @support .cpython_only
4466+ @unittest .skipIf (_testcapi is None , "requires _testcapi" )
4467+ @unittest .skipIf (ctypes is None , "requires ctypes" )
4468+ def test_array_alignment (self ):
4469+ # gh-140557: pointer alignment of buffers including empty allocation
4470+ max_align = ctypes .alignment (ctypes .c_longdouble )
4471+ cases = [array .array (fmt ) for fmt in ARRAY ]
4472+ # Empty arrays
4473+ self .assertEqual (
4474+ [_testcapi .buffer_pointer_as_int (case ) % max_align
4475+ for case in cases ],
4476+ [0 ] * len (cases ),
4477+ )
4478+ for case in cases :
4479+ case .append (0 )
4480+ # Allocated arrays
4481+ self .assertEqual (
4482+ [_testcapi .buffer_pointer_as_int (case ) % max_align
4483+ for case in cases ],
4484+ [0 ] * len (cases ),
4485+ )
4486+
44504487 @support .cpython_only
44514488 def test_pybuffer_size_from_format (self ):
44524489 # basic tests
Original file line number Diff line number Diff line change @@ -98,6 +98,27 @@ static PyTypeObject testBufType = {
9898 .tp_members = testbuf_members
9999};
100100
101+ /* Get the pointer from a buffer-supporting object as a PyLong.
102+ *
103+ * Used to test alignment properties.*/
104+ static PyObject *
105+ buffer_pointer_as_int (PyObject * Py_UNUSED (module ), PyObject * obj )
106+ {
107+ PyObject * out ;
108+ Py_buffer view ;
109+ if (PyObject_GetBuffer (obj , & view , PyBUF_SIMPLE ) != 0 ) {
110+ return NULL ;
111+ }
112+ out = PyLong_FromVoidPtr (view .buf );
113+ PyBuffer_Release (& view );
114+ return out ;
115+ }
116+
117+ static PyMethodDef test_methods [] = {
118+ {"buffer_pointer_as_int" , buffer_pointer_as_int , METH_O },
119+ {NULL },
120+ };
121+
101122int
102123_PyTestCapi_Init_Buffer (PyObject * m ) {
103124 if (PyType_Ready (& testBufType ) < 0 ) {
@@ -106,6 +127,9 @@ _PyTestCapi_Init_Buffer(PyObject *m) {
106127 if (PyModule_AddObjectRef (m , "testBuf" , (PyObject * )& testBufType )) {
107128 return -1 ;
108129 }
130+ if (PyModule_AddFunctions (m , test_methods ) < 0 ) {
131+ return -1 ;
132+ }
109133
110134 return 0 ;
111135}
You can’t perform that action at this time.
0 commit comments