def from_dtype(dtype): """ Return a Numba Type instance corresponding to the given Numpy *dtype*. NotImplementedError is raised on unsupported Numpy dtypes. """ if type(dtype) == type and issubclass(dtype, np.generic): dtype = np.dtype(dtype) elif getattr(dtype, "fields", None) is not None: return from_struct_dtype(dtype) try: return FROM_DTYPE[dtype] except KeyError: pass try: char = dtype.char except AttributeError: pass else: if char in 'SU': return _from_str_dtype(dtype) if char in 'mM': return _from_datetime_dtype(dtype) if char in 'V' and dtype.subdtype is not None: subtype = from_dtype(dtype.subdtype[0]) return types.NestedArray(subtype, dtype.shape) raise NotImplementedError(dtype)
def test_type_parsing(self): ffi = self.get_ffi() # Check struct typedef big_struct = ffi.typeof('big_struct') nbtype = cffi_support.map_type(big_struct, use_record_dtype=True) self.assertIsInstance(nbtype, types.Record) self.assertEqual(len(nbtype), 4) self.assertEqual(nbtype.typeof('i1'), types.int32) self.assertEqual(nbtype.typeof('f2'), types.float32) self.assertEqual(nbtype.typeof('d3'), types.float64) self.assertEqual( nbtype.typeof('af4'), types.NestedArray(dtype=types.float32, shape=(9, )), ) # Check function typedef myfunc = ffi.typeof('myfunc') sig = cffi_support.map_type(myfunc, use_record_dtype=True) self.assertIsInstance(sig, typing.Signature) self.assertEqual(sig.args[0], types.CPointer(nbtype)) self.assertEqual(sig.args[1], types.uintp) self.assertEqual(sig.return_type, types.float64)
def map_type(cffi_type, use_record_dtype=False): """ Map CFFI type to numba type. Parameters ---------- cffi_type: The CFFI type to be converted. use_record_dtype: bool (default: False) When True, struct types are mapped to a NumPy Record dtype. """ primed_map_type = partial(map_type, use_record_dtype=use_record_dtype) kind = getattr(cffi_type, 'kind', '') if kind == 'union': raise TypeError("No support for CFFI union") elif kind == 'function': if cffi_type.ellipsis: raise TypeError("vararg function is not supported") restype = primed_map_type(cffi_type.result) argtypes = [primed_map_type(arg) for arg in cffi_type.args] return templates.signature(restype, *argtypes) elif kind == 'pointer': pointee = cffi_type.item if pointee.kind == 'void': return types.voidptr else: return types.CPointer(primed_map_type(pointee)) elif kind == 'array': dtype = primed_map_type(cffi_type.item) nelem = cffi_type.length return types.NestedArray(dtype=dtype, shape=(nelem, )) elif kind == 'struct' and use_record_dtype: return map_struct_to_record_dtype(cffi_type) else: result = _type_map().get(cffi_type) if result is None: raise TypeError(cffi_type) return result