ctypeslib icon indicating copy to clipboard operation
ctypeslib copied to clipboard

Test failure on i586

Open jayvdb opened this issue 4 years ago • 2 comments

[   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

jayvdb avatar Oct 20 '19 07:10 jayvdb

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"

trolldbois avatar Feb 17 '21 04:02 trolldbois

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.

jayvdb avatar Feb 19 '21 04:02 jayvdb