Skip to content

Commit

Permalink
Add optional _align_ attribute to ctypes.Structure
Browse files Browse the repository at this point in the history
  • Loading branch information
monkeyman192 committed Nov 17, 2023
1 parent 0ee2d77 commit e3ad227
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 2 deletions.
1 change: 1 addition & 0 deletions Include/internal/pycore_global_objects_fini_generated.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Include/internal/pycore_global_strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(_abc_impl)
STRUCT_FOR_ID(_abstract_)
STRUCT_FOR_ID(_active)
STRUCT_FOR_ID(_align_)
STRUCT_FOR_ID(_annotation)
STRUCT_FOR_ID(_anonymous_)
STRUCT_FOR_ID(_argtypes_)
Expand Down
1 change: 1 addition & 0 deletions Include/internal/pycore_runtime_init_generated.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Include/internal/pycore_unicodeobject_generated.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 25 additions & 2 deletions Modules/_ctypes/stgdict.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,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;
Expand Down Expand Up @@ -419,6 +420,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)) {
Expand Down Expand Up @@ -463,7 +486,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
size = offset = basedict->size;
align = basedict->align;
union_size = 0;
total_align = align ? align : 1;
total_align = align ? 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) {
Expand All @@ -483,7 +506,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) {
Expand Down

0 comments on commit e3ad227

Please sign in to comment.