ctypeslib
ctypeslib copied to clipboard
Test failure on i586
[ 72s] ======================================================================
[ 72s] FAIL: test_extern_function_pointer_multiarg (test_types_values.ConstantsTest)
[ 72s] ----------------------------------------------------------------------
[ 72s] Traceback (most recent call last):
[ 72s] File "/home/abuild/rpmbuild/BUILD/ctypeslib-2.2.2/test/test_types_values.py", line 283, in test_extern_function_pointer_multiarg
[ 72s] 'c_int')
[ 72s] AssertionError: 'c_long' != 'c_int'
[ 72s] - c_long
[ 72s] + c_int
mmh.. yeah, that would requires making the tests architecture-aware... i'll pass on that.
does clang2py produces workable results on i586 ?
For example: clang2py test/data/test-records.c --clang-args="-target i586-linux"
clang2py test/data/test-records.c --clang-args="-target i586-linux"
When run on i586 machine
[ 56s] INFO:codegen:No members for: struct_Anon
[ 56s] INFO:codegen:No members for: struct_Anon2
[ 56s] # -*- coding: utf-8 -*-
[ 56s] #
[ 56s] # TARGET arch is: ['-target', 'i586-linux']
[ 56s] # WORD_SIZE is: 4
[ 56s] # POINTER_SIZE is: 4
[ 56s] # LONGDOUBLE_SIZE is: 12
[ 56s] #
[ 56s] import ctypes
[ 56s]
[ 56s]
[ 56s] class AsDictMixin:
[ 56s] @classmethod
[ 56s] def as_dict(cls, self):
[ 56s] result = {}
[ 56s] if not isinstance(self, AsDictMixin):
[ 56s] # not a structure, assume it's already a python object
[ 56s] return self
[ 56s] if not hasattr(cls, "_fields_"):
[ 56s] return result
[ 56s] for (field, *_) in cls._fields_: # noqa
[ 56s] if field.startswith('PADDING_'):
[ 56s] continue
[ 56s] value = getattr(self, field)
[ 56s] type_ = type(value)
[ 56s] if hasattr(value, "_length_") and hasattr(value, "_type_"):
[ 56s] # array
[ 56s] if not hasattr(type_, "as_dict"):
[ 56s] value = [v for v in value]
[ 56s] else:
[ 56s] type_ = type_._type_
[ 56s] value = [type_.as_dict(v) for v in value]
[ 56s] elif hasattr(value, "contents") and hasattr(value, "_type_"):
[ 56s] # pointer
[ 56s] try:
[ 56s] if not hasattr(type_, "as_dict"):
[ 56s] value = value.contents
[ 56s] else:
[ 56s] type_ = type_._type_
[ 56s] value = type_.as_dict(value.contents)
[ 56s] except ValueError:
[ 56s] # nullptr
[ 56s] value = None
[ 56s] elif isinstance(value, AsDictMixin):
[ 56s] # other structure
[ 56s] value = type_.as_dict(value)
[ 56s] result[field] = value
[ 56s] return result
[ 56s]
[ 56s]
[ 56s] class Structure(ctypes.Structure, AsDictMixin):
[ 56s]
[ 56s] def __init__(self, *args, **kwds):
[ 56s] # We don't want to use positional arguments fill PADDING_* fields
[ 56s]
[ 56s] args = dict(zip(self.__class__._field_names_(), args))
[ 56s] args.update(kwds)
[ 56s] super(Structure, self).__init__(**args)
[ 56s]
[ 56s] @classmethod
[ 56s] def _field_names_(cls):
[ 56s] if hasattr(cls, '_fields_'):
[ 56s] return (f[0] for f in cls._fields_ if not f[0].startswith('PADDING'))
[ 56s] else:
[ 56s] return ()
[ 56s]
[ 56s] @classmethod
[ 56s] def get_type(cls, field):
[ 56s] for f in cls._fields_:
[ 56s] if f[0] == field:
[ 56s] return f[1]
[ 56s] return None
[ 56s]
[ 56s] @classmethod
[ 56s] def bind(cls, bound_fields):
[ 56s] fields = {}
[ 56s] for name, type_ in cls._fields_:
[ 56s] if hasattr(type_, "restype"):
[ 56s] if name in bound_fields:
[ 56s] # use a closure to capture the callback from the loop scope
[ 56s] fields[name] = (
[ 56s] type_((lambda callback: lambda *args: callback(*args))(
[ 56s] bound_fields[name]))
[ 56s] )
[ 56s] del bound_fields[name]
[ 56s] else:
[ 56s] # default callback implementation (does nothing)
[ 56s] try:
[ 56s] default_ = type_(0).restype().value
[ 56s] except TypeError:
[ 56s] default_ = None
[ 56s] fields[name] = type_((
[ 56s] lambda default_: lambda *args: default_)(default_))
[ 56s] else:
[ 56s] # not a callback function, use default initialization
[ 56s] if name in bound_fields:
[ 56s] fields[name] = bound_fields[name]
[ 56s] del bound_fields[name]
[ 56s] else:
[ 56s] fields[name] = type_()
[ 56s] if len(bound_fields) != 0:
[ 56s] raise ValueError(
[ 56s] "Cannot bind the following unknown callback(s) {}.{}".format(
[ 56s] cls.__name__, bound_fields.keys()
[ 56s] ))
[ 56s] return cls(**fields)
[ 56s]
[ 56s]
[ 56s] class Union(ctypes.Union, AsDictMixin):
[ 56s] pass
[ 56s]
[ 56s]
[ 56s]
[ 56s] # if local wordsize is same as target, keep ctypes pointer function.
[ 56s] if ctypes.sizeof(ctypes.c_void_p) == 4:
[ 56s] POINTER_T = ctypes.POINTER
[ 56s] else:
[ 56s] class IncorrectWordSizeError(TypeError):
[ 56s] pass
[ 56s] # required to access _ctypes
[ 56s] import _ctypes
[ 56s] # Emulate a pointer class using the approriate c_int32/c_int64 type
[ 56s] # The new class should have :
[ 56s] # ['__module__', 'from_param', '_type_', '__dict__', '__weakref__', '__doc__']
[ 56s] # but the class should be submitted to a unique instance for each base type
[ 56s] # to that if A == B, POINTER_T(A) == POINTER_T(B)
[ 56s] ctypes._pointer_t_type_cache = {}
[ 56s] def POINTER_T(pointee):
[ 56s] # a pointer should have the same length as LONG
[ 56s] fake_ptr_base_type = ctypes.c_uint32
[ 56s] # specific case for c_void_p
[ 56s] if pointee is None: # VOID pointer type. c_void_p.
[ 56s] pointee = type(None) # ctypes.c_void_p # ctypes.c_ulong
[ 56s] clsname = 'c_void'
[ 56s] else:
[ 56s] clsname = pointee.__name__
[ 56s] if clsname in ctypes._pointer_t_type_cache:
[ 56s] return ctypes._pointer_t_type_cache[clsname]
[ 56s] # make template
[ 56s] class _T(_ctypes._SimpleCData,):
[ 56s] _type_ = 'L'
[ 56s] _subtype_ = pointee
[ 56s] def _sub_addr_(self):
[ 56s] return self.value
[ 56s] def __repr__(self):
[ 56s] return '%s(%d)'%(clsname, self.value)
[ 56s] def contents(self):
[ 56s] raise IncorrectWordSizeError('This is not a ctypes pointer.')
[ 56s] def __init__(self, **args):
[ 56s] raise IncorrectWordSizeError('This is not a ctypes pointer. It is not instanciable.')
[ 56s] _class = type('LP_%d_%s'%(4, clsname), (_T,),{})
[ 56s] ctypes._pointer_t_type_cache[clsname] = _class
[ 56s] return _class
[ 56s]
[ 56s] c_int128 = ctypes.c_ubyte*16
[ 56s] c_uint128 = c_int128
[ 56s] void = None
[ 56s] if ctypes.sizeof(ctypes.c_longdouble) == 12:
[ 56s] c_long_double_t = ctypes.c_longdouble
[ 56s] else:
[ 56s] c_long_double_t = ctypes.c_ubyte*12
[ 56s]
[ 56s]
[ 56s]
[ 56s] class struct_Name(Structure):
[ 56s] _pack_ = True # source:True
[ 56s] _fields_ = [
[ 56s] ('member1', ctypes.c_int16),
[ 56s] ('member2', ctypes.c_int32),
[ 56s] ('member3', ctypes.c_uint32),
[ 56s] ('member4', ctypes.c_uint32),
[ 56s] ('member5', ctypes.c_uint32),
[ 56s] ]
[ 56s]
[ 56s] class struct_Name2(Structure):
[ 56s] _pack_ = True # source:False
[ 56s] _fields_ = [
[ 56s] ('member1', ctypes.c_int16),
[ 56s] ('PADDING_0', ctypes.c_ubyte * 2),
[ 56s] ('member2', ctypes.c_int32),
[ 56s] ('member3', ctypes.c_uint32),
[ 56s] ('member4', ctypes.c_uint32),
[ 56s] ('member5', ctypes.c_uint32),
[ 56s] ]
[ 56s]
[ 56s] class struct_Node(Structure):
[ 56s] pass
[ 56s]
[ 56s] class struct_Node2(Structure):
[ 56s] _pack_ = True # source:False
[ 56s] _fields_ = [
[ 56s] ('m1', ctypes.c_ubyte),
[ 56s] ('PADDING_0', ctypes.c_ubyte * 3),
[ 56s] ('m2', POINTER_T(struct_Node)),
[ 56s] ]
[ 56s]
[ 56s] struct_Node._pack_ = True # source:False
[ 56s] struct_Node._fields_ = [
[ 56s] ('val1', ctypes.c_uint32),
[ 56s] ('ptr2', POINTER_T(None)),
[ 56s] ('ptr3', POINTER_T(ctypes.c_int32)),
[ 56s] ('ptr4', POINTER_T(struct_Node2)),
[ 56s] ]
[ 56s]
[ 56s] class struct_Node3(Structure):
[ 56s] _pack_ = True # source:False
[ 56s] _fields_ = [
[ 56s] ('ptr1', POINTER_T(struct_Node)),
[ 56s] ('ptr2', POINTER_T(ctypes.c_ubyte)),
[ 56s] ('ptr3', POINTER_T(ctypes.c_uint16)),
[ 56s] ('ptr4', POINTER_T(ctypes.c_uint32)),
[ 56s] ('ptr5', POINTER_T(ctypes.c_uint32)),
[ 56s] ('ptr6', POINTER_T(ctypes.c_uint64)),
[ 56s] ('ptr7', POINTER_T(ctypes.c_double)),
[ 56s] ('ptr8', POINTER_T(c_long_double_t)),
[ 56s] ('ptr9', POINTER_T(None)),
[ 56s] ]
[ 56s]
[ 56s] class struct_Node4(Structure):
[ 56s] _pack_ = True # source:False
[ 56s] _fields_ = [
[ 56s] ('f1', struct_Node),
[ 56s] ('f2', ctypes.c_ubyte),
[ 56s] ('PADDING_0', ctypes.c_ubyte),
[ 56s] ('f3', ctypes.c_uint16),
[ 56s] ('f4', ctypes.c_uint32),
[ 56s] ('f5', ctypes.c_uint32),
[ 56s] ('f6', ctypes.c_uint64),
[ 56s] ('f7', ctypes.c_double),
[ 56s] ('f8', c_long_double_t),
[ 56s] ]
[ 56s]
[ 56s]
[ 56s] # values for enumeration 'myEnum'
[ 56s] myEnum__enumvalues = {
[ 56s] 0: 'ONE',
[ 56s] 1: 'TWO',
[ 56s] 4: 'FOUR',
[ 56s] }
[ 56s] ONE = 0
[ 56s] TWO = 1
[ 56s] FOUR = 4
[ 56s] myEnum = ctypes.c_int # enum
[ 56s] class struct_c__SA_my__quad_t(Structure):
[ 56s] _pack_ = True # source:False
[ 56s] _fields_ = [
[ 56s] ('__val', ctypes.c_int32 * 2),
[ 56s] ]
[ 56s]
[ 56s] my__quad_t = struct_c__SA_my__quad_t
[ 56s] class struct_c__SA_my_bitfield(Structure):
[ 56s] _pack_ = True # source:False
[ 56s] _fields_ = [
[ 56s] ('a', ctypes.c_int32, 3),
[ 56s] ('b', ctypes.c_int32, 4),
[ 56s] ('c', ctypes.c_int32, 3),
[ 56s] ('d', ctypes.c_int32, 3),
[ 56s] ('f', ctypes.c_int32, 2),
[ 56s] ('PADDING_0', ctypes.c_uint32, 17),
[ 56s] ]
[ 56s]
[ 56s] my_bitfield = struct_c__SA_my_bitfield
[ 56s] class struct_c__SA_mystruct(Structure):
[ 56s] _pack_ = True # source:True
[ 56s] _fields_ = [
[ 56s] ('a', ctypes.c_int32),
[ 56s] ('c', ctypes.c_char),
[ 56s] ]
[ 56s]
[ 56s] mystruct = struct_c__SA_mystruct
[ 56s] class struct_Anon(Structure):
[ 56s] pass
[ 56s]
[ 56s] class struct_Anon2(Structure):
[ 56s] pass
[ 56s]
[ 56s] __all__ = \
[ 56s] ['FOUR', 'ONE', 'TWO', 'myEnum', 'my__quad_t', 'my_bitfield',
[ 56s] 'mystruct', 'struct_Anon', 'struct_Anon2', 'struct_Name',
[ 56s] 'struct_Name2', 'struct_Node', 'struct_Node2', 'struct_Node3',
[ 56s] 'struct_Node4', 'struct_c__SA_my__quad_t',
[ 56s] 'struct_c__SA_my_bitfield', 'struct_c__SA_mystruct']
Note test_callbacks also fails. one test method fails on 64 bit, and the other fails on 32 bit.