Verify the sizes of the basic ctypes data types against the struct
module. Will backport to release25-maint.
This commit is contained in:
parent
1211edd81b
commit
85a2192bb6
|
@ -133,6 +133,18 @@ elif _os.name == "posix":
|
||||||
from _ctypes import sizeof, byref, addressof, alignment, resize
|
from _ctypes import sizeof, byref, addressof, alignment, resize
|
||||||
from _ctypes import _SimpleCData
|
from _ctypes import _SimpleCData
|
||||||
|
|
||||||
|
def _check_size(typ, typecode=None):
|
||||||
|
# Check if sizeof(ctypes_type) against struct.calcsize. This
|
||||||
|
# should protect somewhat against a misconfigured libffi.
|
||||||
|
from struct import calcsize
|
||||||
|
if typecode is None:
|
||||||
|
# Most _type_ codes are the same as used in struct
|
||||||
|
typecode = typ._type_
|
||||||
|
actual, required = sizeof(typ), calcsize(typecode)
|
||||||
|
if actual != required:
|
||||||
|
raise SystemError("sizeof(%s) wrong: %d instead of %d" % \
|
||||||
|
(typ, actual, required))
|
||||||
|
|
||||||
class py_object(_SimpleCData):
|
class py_object(_SimpleCData):
|
||||||
_type_ = "O"
|
_type_ = "O"
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -140,18 +152,23 @@ class py_object(_SimpleCData):
|
||||||
return super(py_object, self).__repr__()
|
return super(py_object, self).__repr__()
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return "%s(<NULL>)" % type(self).__name__
|
return "%s(<NULL>)" % type(self).__name__
|
||||||
|
_check_size(py_object, "P")
|
||||||
|
|
||||||
class c_short(_SimpleCData):
|
class c_short(_SimpleCData):
|
||||||
_type_ = "h"
|
_type_ = "h"
|
||||||
|
_check_size(c_short)
|
||||||
|
|
||||||
class c_ushort(_SimpleCData):
|
class c_ushort(_SimpleCData):
|
||||||
_type_ = "H"
|
_type_ = "H"
|
||||||
|
_check_size(c_ushort)
|
||||||
|
|
||||||
class c_long(_SimpleCData):
|
class c_long(_SimpleCData):
|
||||||
_type_ = "l"
|
_type_ = "l"
|
||||||
|
_check_size(c_long)
|
||||||
|
|
||||||
class c_ulong(_SimpleCData):
|
class c_ulong(_SimpleCData):
|
||||||
_type_ = "L"
|
_type_ = "L"
|
||||||
|
_check_size(c_ulong)
|
||||||
|
|
||||||
if _calcsize("i") == _calcsize("l"):
|
if _calcsize("i") == _calcsize("l"):
|
||||||
# if int and long have the same size, make c_int an alias for c_long
|
# if int and long have the same size, make c_int an alias for c_long
|
||||||
|
@ -160,15 +177,19 @@ if _calcsize("i") == _calcsize("l"):
|
||||||
else:
|
else:
|
||||||
class c_int(_SimpleCData):
|
class c_int(_SimpleCData):
|
||||||
_type_ = "i"
|
_type_ = "i"
|
||||||
|
_check_size(c_int)
|
||||||
|
|
||||||
class c_uint(_SimpleCData):
|
class c_uint(_SimpleCData):
|
||||||
_type_ = "I"
|
_type_ = "I"
|
||||||
|
_check_size(c_uint)
|
||||||
|
|
||||||
class c_float(_SimpleCData):
|
class c_float(_SimpleCData):
|
||||||
_type_ = "f"
|
_type_ = "f"
|
||||||
|
_check_size(c_float)
|
||||||
|
|
||||||
class c_double(_SimpleCData):
|
class c_double(_SimpleCData):
|
||||||
_type_ = "d"
|
_type_ = "d"
|
||||||
|
_check_size(c_double)
|
||||||
|
|
||||||
if _calcsize("l") == _calcsize("q"):
|
if _calcsize("l") == _calcsize("q"):
|
||||||
# if long and long long have the same size, make c_longlong an alias for c_long
|
# if long and long long have the same size, make c_longlong an alias for c_long
|
||||||
|
@ -177,33 +198,40 @@ if _calcsize("l") == _calcsize("q"):
|
||||||
else:
|
else:
|
||||||
class c_longlong(_SimpleCData):
|
class c_longlong(_SimpleCData):
|
||||||
_type_ = "q"
|
_type_ = "q"
|
||||||
|
_check_size(c_longlong)
|
||||||
|
|
||||||
class c_ulonglong(_SimpleCData):
|
class c_ulonglong(_SimpleCData):
|
||||||
_type_ = "Q"
|
_type_ = "Q"
|
||||||
## def from_param(cls, val):
|
## def from_param(cls, val):
|
||||||
## return ('d', float(val), val)
|
## return ('d', float(val), val)
|
||||||
## from_param = classmethod(from_param)
|
## from_param = classmethod(from_param)
|
||||||
|
_check_size(c_ulonglong)
|
||||||
|
|
||||||
class c_ubyte(_SimpleCData):
|
class c_ubyte(_SimpleCData):
|
||||||
_type_ = "B"
|
_type_ = "B"
|
||||||
c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte
|
c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte
|
||||||
# backward compatibility:
|
# backward compatibility:
|
||||||
##c_uchar = c_ubyte
|
##c_uchar = c_ubyte
|
||||||
|
_check_size(c_ubyte)
|
||||||
|
|
||||||
class c_byte(_SimpleCData):
|
class c_byte(_SimpleCData):
|
||||||
_type_ = "b"
|
_type_ = "b"
|
||||||
c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte
|
c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte
|
||||||
|
_check_size(c_byte)
|
||||||
|
|
||||||
class c_char(_SimpleCData):
|
class c_char(_SimpleCData):
|
||||||
_type_ = "c"
|
_type_ = "c"
|
||||||
c_char.__ctype_le__ = c_char.__ctype_be__ = c_char
|
c_char.__ctype_le__ = c_char.__ctype_be__ = c_char
|
||||||
|
_check_size(c_char)
|
||||||
|
|
||||||
class c_char_p(_SimpleCData):
|
class c_char_p(_SimpleCData):
|
||||||
_type_ = "z"
|
_type_ = "z"
|
||||||
|
_check_size(c_char_p, "P")
|
||||||
|
|
||||||
class c_void_p(_SimpleCData):
|
class c_void_p(_SimpleCData):
|
||||||
_type_ = "P"
|
_type_ = "P"
|
||||||
c_voidp = c_void_p # backwards compatibility (to a bug)
|
c_voidp = c_void_p # backwards compatibility (to a bug)
|
||||||
|
_check_size(c_void_p)
|
||||||
|
|
||||||
# This cache maps types to pointers to them.
|
# This cache maps types to pointers to them.
|
||||||
_pointer_type_cache = {}
|
_pointer_type_cache = {}
|
||||||
|
|
Loading…
Reference in New Issue