gh-112433: Add optional _align_ attribute to ctypes.Structure (GH-113790)

This commit is contained in:
monkeyman192 2024-02-16 01:40:20 +11:00 • committed by GitHub
parent f42e112fd8
commit 298bcdc185
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 328 additions and 1 deletions

View file

@ -384,6 +384,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
int bitofs;
PyObject *tmp;
int pack;
int forced_alignment = 1;
Py_ssize_t ffi_ofs;
int big_endian;
int arrays_seen = 0;
@ -424,6 +425,28 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
pack = 0;
}
if (PyObject_GetOptionalAttr(type, &_Py_ID(_align_), &tmp) < 0) {
return -1;
}
if (tmp) {
forced_alignment = PyLong_AsInt(tmp);
Py_DECREF(tmp);
if (forced_alignment < 0) {
if (!PyErr_Occurred() ||
PyErr_ExceptionMatches(PyExc_TypeError) ||
PyErr_ExceptionMatches(PyExc_OverflowError))
{
PyErr_SetString(PyExc_ValueError,
"_align_ must be a non-negative integer");
}
return -1;
}
}
else {
/* Setting `_align_ = 0` amounts to using the default alignment */
forced_alignment = 1;
}
len = PySequence_Size(fields);
if (len == -1) {
if (PyErr_ExceptionMatches(PyExc_TypeError)) {
@ -469,6 +492,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
align = basedict->align;
union_size = 0;
total_align = align ? align : 1;
total_align = max(total_align, forced_alignment);
stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT;
stgdict->ffi_type_pointer.elements = PyMem_New(ffi_type *, basedict->length + len + 1);
if (stgdict->ffi_type_pointer.elements == NULL) {
@ -488,7 +512,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
size = 0;
align = 0;
union_size = 0;
total_align = 1;
total_align = forced_alignment;
stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT;
stgdict->ffi_type_pointer.elements = PyMem_New(ffi_type *, len + 1);
if (stgdict->ffi_type_pointer.elements == NULL) {