[pypy-commit] cffi default: Kill the ctypes backend.

arigo pypy.commits at gmail.com
Sat Sep 3 05:11:55 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r2749:0087e2aec9ef
Date: 2016-09-03 11:11 +0200
http://bitbucket.org/cffi/cffi/changeset/0087e2aec9ef/

Log:	Kill the ctypes backend.

diff too long, truncating to 2000 out of 2925 lines

diff --git a/cffi/api.py b/cffi/api.py
--- a/cffi/api.py
+++ b/cffi/api.py
@@ -46,20 +46,21 @@
     '''
 
     def __init__(self, backend=None):
-        """Create an FFI instance.  The 'backend' argument is used to
-        select a non-default backend, mostly for tests.
+        """Create an FFI instance.
+
+        The 'backend' argument is not used any more and must be set to None.
+        It is still present only so that 'FFI(None)' still works, and
+        for a few tests.
         """
         from . import cparser, model
+
         if backend is None:
-            # You need PyPy (>= 2.0 beta), or a CPython (>= 2.6) with
-            # _cffi_backend.so compiled.
+            # You need the corresponding version of PyPy, or CPython
+            # with the '_cffi_backend' C extension module compiled.
             import _cffi_backend as backend
             from . import __version__
             assert backend.__version__ == __version__, \
                "version mismatch, %s != %s" % (backend.__version__, __version__)
-            # (If you insist you can also try to pass the option
-            # 'backend=backend_ctypes.CTypesBackend()', but don't
-            # rely on it!  It's probably not going to work well.)
 
         self._backend = backend
         self._lock = allocate_lock()
@@ -75,8 +76,6 @@
         self._init_once_cache = {}
         self._cdef_version = None
         self._embedding = None
-        if hasattr(backend, 'set_ffi'):
-            backend.set_ffi(self)
         for name in backend.__dict__:
             if name.startswith('RTLD_'):
                 setattr(self, name, getattr(backend, name))
@@ -84,15 +83,10 @@
         with self._lock:
             self.BVoidP = self._get_cached_btype(model.voidp_type)
             self.BCharA = self._get_cached_btype(model.char_array_type)
-        if isinstance(backend, types.ModuleType):
-            # _cffi_backend: attach these constants to the class
-            if not hasattr(FFI, 'NULL'):
-                FFI.NULL = self.cast(self.BVoidP, 0)
-                FFI.CData, FFI.CType = backend._get_types()
-        else:
-            # ctypes backend: attach these constants to the instance
-            self.NULL = self.cast(self.BVoidP, 0)
-            self.CData, self.CType = backend._get_types()
+        # attach these constants to the class
+        if not hasattr(FFI, 'NULL'):
+            FFI.NULL = self.cast(self.BVoidP, 0)
+            FFI.CData, FFI.CType = backend._get_types()
 
     def cdef(self, csource, override=False, packed=False):
         """Parse the given C source.  This registers all declared functions,
diff --git a/cffi/backend_ctypes.py b/cffi/backend_ctypes.py
deleted file mode 100644
--- a/cffi/backend_ctypes.py
+++ /dev/null
@@ -1,1097 +0,0 @@
-import ctypes, ctypes.util, operator, sys
-from . import model
-
-if sys.version_info < (3,):
-    bytechr = chr
-else:
-    unicode = str
-    long = int
-    xrange = range
-    bytechr = lambda num: bytes([num])
-
-class CTypesType(type):
-    pass
-
-class CTypesData(object):
-    __metaclass__ = CTypesType
-    __slots__ = ['__weakref__']
-    __name__ = '<cdata>'
-
-    def __init__(self, *args):
-        raise TypeError("cannot instantiate %r" % (self.__class__,))
-
-    @classmethod
-    def _newp(cls, init):
-        raise TypeError("expected a pointer or array ctype, got '%s'"
-                        % (cls._get_c_name(),))
-
-    @staticmethod
-    def _to_ctypes(value):
-        raise TypeError
-
-    @classmethod
-    def _arg_to_ctypes(cls, *value):
-        try:
-            ctype = cls._ctype
-        except AttributeError:
-            raise TypeError("cannot create an instance of %r" % (cls,))
-        if value:
-            res = cls._to_ctypes(*value)
-            if not isinstance(res, ctype):
-                res = cls._ctype(res)
-        else:
-            res = cls._ctype()
-        return res
-
-    @classmethod
-    def _create_ctype_obj(cls, init):
-        if init is None:
-            return cls._arg_to_ctypes()
-        else:
-            return cls._arg_to_ctypes(init)
-
-    @staticmethod
-    def _from_ctypes(ctypes_value):
-        raise TypeError
-
-    @classmethod
-    def _get_c_name(cls, replace_with=''):
-        return cls._reftypename.replace(' &', replace_with)
-
-    @classmethod
-    def _fix_class(cls):
-        cls.__name__ = 'CData<%s>' % (cls._get_c_name(),)
-        cls.__qualname__ = 'CData<%s>' % (cls._get_c_name(),)
-        cls.__module__ = 'ffi'
-
-    def _get_own_repr(self):
-        raise NotImplementedError
-
-    def _addr_repr(self, address):
-        if address == 0:
-            return 'NULL'
-        else:
-            if address < 0:
-                address += 1 << (8*ctypes.sizeof(ctypes.c_void_p))
-            return '0x%x' % address
-
-    def __repr__(self, c_name=None):
-        own = self._get_own_repr()
-        return '<cdata %r %s>' % (c_name or self._get_c_name(), own)
-
-    def _convert_to_address(self, BClass):
-        if BClass is None:
-            raise TypeError("cannot convert %r to an address" % (
-                self._get_c_name(),))
-        else:
-            raise TypeError("cannot convert %r to %r" % (
-                self._get_c_name(), BClass._get_c_name()))
-
-    @classmethod
-    def _get_size(cls):
-        return ctypes.sizeof(cls._ctype)
-
-    def _get_size_of_instance(self):
-        return ctypes.sizeof(self._ctype)
-
-    @classmethod
-    def _cast_from(cls, source):
-        raise TypeError("cannot cast to %r" % (cls._get_c_name(),))
-
-    def _cast_to_integer(self):
-        return self._convert_to_address(None)
-
-    @classmethod
-    def _alignment(cls):
-        return ctypes.alignment(cls._ctype)
-
-    def __iter__(self):
-        raise TypeError("cdata %r does not support iteration" % (
-            self._get_c_name()),)
-
-    def _make_cmp(name):
-        cmpfunc = getattr(operator, name)
-        def cmp(self, other):
-            if isinstance(other, CTypesData):
-                return cmpfunc(self._convert_to_address(None),
-                               other._convert_to_address(None))
-            else:
-                return NotImplemented
-        cmp.func_name = name
-        return cmp
-
-    __eq__ = _make_cmp('__eq__')
-    __ne__ = _make_cmp('__ne__')
-    __lt__ = _make_cmp('__lt__')
-    __le__ = _make_cmp('__le__')
-    __gt__ = _make_cmp('__gt__')
-    __ge__ = _make_cmp('__ge__')
-
-    def __hash__(self):
-        return hash(type(self)) ^ hash(self._convert_to_address(None))
-
-    def _to_string(self, maxlen):
-        raise TypeError("string(): %r" % (self,))
-
-
-class CTypesGenericPrimitive(CTypesData):
-    __slots__ = []
-
-    def __eq__(self, other):
-        return self is other
-
-    def __ne__(self, other):
-        return self is not other
-
-    def __hash__(self):
-        return object.__hash__(self)
-
-    def _get_own_repr(self):
-        return repr(self._from_ctypes(self._value))
-
-
-class CTypesGenericArray(CTypesData):
-    __slots__ = []
-
-    @classmethod
-    def _newp(cls, init):
-        return cls(init)
-
-    def __iter__(self):
-        for i in xrange(len(self)):
-            yield self[i]
-
-    def _get_own_repr(self):
-        return self._addr_repr(ctypes.addressof(self._blob))
-
-
-class CTypesGenericPtr(CTypesData):
-    __slots__ = ['_address', '_as_ctype_ptr']
-    _automatic_casts = False
-    kind = "pointer"
-
-    @classmethod
-    def _newp(cls, init):
-        return cls(init)
-
-    @classmethod
-    def _cast_from(cls, source):
-        if source is None:
-            address = 0
-        elif isinstance(source, CTypesData):
-            address = source._cast_to_integer()
-        elif isinstance(source, (int, long)):
-            address = source
-        else:
-            raise TypeError("bad type for cast to %r: %r" %
-                            (cls, type(source).__name__))
-        return cls._new_pointer_at(address)
-
-    @classmethod
-    def _new_pointer_at(cls, address):
-        self = cls.__new__(cls)
-        self._address = address
-        self._as_ctype_ptr = ctypes.cast(address, cls._ctype)
-        return self
-
-    def _get_own_repr(self):
-        try:
-            return self._addr_repr(self._address)
-        except AttributeError:
-            return '???'
-
-    def _cast_to_integer(self):
-        return self._address
-
-    def __nonzero__(self):
-        return bool(self._address)
-    __bool__ = __nonzero__
-
-    @classmethod
-    def _to_ctypes(cls, value):
-        if not isinstance(value, CTypesData):
-            raise TypeError("unexpected %s object" % type(value).__name__)
-        address = value._convert_to_address(cls)
-        return ctypes.cast(address, cls._ctype)
-
-    @classmethod
-    def _from_ctypes(cls, ctypes_ptr):
-        address = ctypes.cast(ctypes_ptr, ctypes.c_void_p).value or 0
-        return cls._new_pointer_at(address)
-
-    @classmethod
-    def _initialize(cls, ctypes_ptr, value):
-        if value:
-            ctypes_ptr.contents = cls._to_ctypes(value).contents
-
-    def _convert_to_address(self, BClass):
-        if (BClass in (self.__class__, None) or BClass._automatic_casts
-            or self._automatic_casts):
-            return self._address
-        else:
-            return CTypesData._convert_to_address(self, BClass)
-
-
-class CTypesBaseStructOrUnion(CTypesData):
-    __slots__ = ['_blob']
-
-    @classmethod
-    def _create_ctype_obj(cls, init):
-        # may be overridden
-        raise TypeError("cannot instantiate opaque type %s" % (cls,))
-
-    def _get_own_repr(self):
-        return self._addr_repr(ctypes.addressof(self._blob))
-
-    @classmethod
-    def _offsetof(cls, fieldname):
-        return getattr(cls._ctype, fieldname).offset
-
-    def _convert_to_address(self, BClass):
-        if getattr(BClass, '_BItem', None) is self.__class__:
-            return ctypes.addressof(self._blob)
-        else:
-            return CTypesData._convert_to_address(self, BClass)
-
-    @classmethod
-    def _from_ctypes(cls, ctypes_struct_or_union):
-        self = cls.__new__(cls)
-        self._blob = ctypes_struct_or_union
-        return self
-
-    @classmethod
-    def _to_ctypes(cls, value):
-        return value._blob
-
-    def __repr__(self, c_name=None):
-        return CTypesData.__repr__(self, c_name or self._get_c_name(' &'))
-
-
-class CTypesBackend(object):
-
-    PRIMITIVE_TYPES = {
-        'char': ctypes.c_char,
-        'short': ctypes.c_short,
-        'int': ctypes.c_int,
-        'long': ctypes.c_long,
-        'long long': ctypes.c_longlong,
-        'signed char': ctypes.c_byte,
-        'unsigned char': ctypes.c_ubyte,
-        'unsigned short': ctypes.c_ushort,
-        'unsigned int': ctypes.c_uint,
-        'unsigned long': ctypes.c_ulong,
-        'unsigned long long': ctypes.c_ulonglong,
-        'float': ctypes.c_float,
-        'double': ctypes.c_double,
-        '_Bool': ctypes.c_bool,
-        }
-
-    for _name in ['unsigned long long', 'unsigned long',
-                  'unsigned int', 'unsigned short', 'unsigned char']:
-        _size = ctypes.sizeof(PRIMITIVE_TYPES[_name])
-        PRIMITIVE_TYPES['uint%d_t' % (8*_size)] = PRIMITIVE_TYPES[_name]
-        if _size == ctypes.sizeof(ctypes.c_void_p):
-            PRIMITIVE_TYPES['uintptr_t'] = PRIMITIVE_TYPES[_name]
-        if _size == ctypes.sizeof(ctypes.c_size_t):
-            PRIMITIVE_TYPES['size_t'] = PRIMITIVE_TYPES[_name]
-
-    for _name in ['long long', 'long', 'int', 'short', 'signed char']:
-        _size = ctypes.sizeof(PRIMITIVE_TYPES[_name])
-        PRIMITIVE_TYPES['int%d_t' % (8*_size)] = PRIMITIVE_TYPES[_name]
-        if _size == ctypes.sizeof(ctypes.c_void_p):
-            PRIMITIVE_TYPES['intptr_t'] = PRIMITIVE_TYPES[_name]
-            PRIMITIVE_TYPES['ptrdiff_t'] = PRIMITIVE_TYPES[_name]
-        if _size == ctypes.sizeof(ctypes.c_size_t):
-            PRIMITIVE_TYPES['ssize_t'] = PRIMITIVE_TYPES[_name]
-
-
-    def __init__(self):
-        self.RTLD_LAZY = 0   # not supported anyway by ctypes
-        self.RTLD_NOW  = 0
-        self.RTLD_GLOBAL = ctypes.RTLD_GLOBAL
-        self.RTLD_LOCAL = ctypes.RTLD_LOCAL
-
-    def set_ffi(self, ffi):
-        self.ffi = ffi
-
-    def _get_types(self):
-        return CTypesData, CTypesType
-
-    def load_library(self, path, flags=0):
-        cdll = ctypes.CDLL(path, flags)
-        return CTypesLibrary(self, cdll)
-
-    def new_void_type(self):
-        class CTypesVoid(CTypesData):
-            __slots__ = []
-            _reftypename = 'void &'
-            @staticmethod
-            def _from_ctypes(novalue):
-                return None
-            @staticmethod
-            def _to_ctypes(novalue):
-                if novalue is not None:
-                    raise TypeError("None expected, got %s object" %
-                                    (type(novalue).__name__,))
-                return None
-        CTypesVoid._fix_class()
-        return CTypesVoid
-
-    def new_primitive_type(self, name):
-        if name == 'wchar_t':
-            raise NotImplementedError(name)
-        ctype = self.PRIMITIVE_TYPES[name]
-        if name == 'char':
-            kind = 'char'
-        elif name in ('float', 'double'):
-            kind = 'float'
-        else:
-            if name in ('signed char', 'unsigned char'):
-                kind = 'byte'
-            elif name == '_Bool':
-                kind = 'bool'
-            else:
-                kind = 'int'
-            is_signed = (ctype(-1).value == -1)
-        #
-        def _cast_source_to_int(source):
-            if isinstance(source, (int, long, float)):
-                source = int(source)
-            elif isinstance(source, CTypesData):
-                source = source._cast_to_integer()
-            elif isinstance(source, bytes):
-                source = ord(source)
-            elif source is None:
-                source = 0
-            else:
-                raise TypeError("bad type for cast to %r: %r" %
-                                (CTypesPrimitive, type(source).__name__))
-            return source
-        #
-        kind1 = kind
-        class CTypesPrimitive(CTypesGenericPrimitive):
-            __slots__ = ['_value']
-            _ctype = ctype
-            _reftypename = '%s &' % name
-            kind = kind1
-
-            def __init__(self, value):
-                self._value = value
-
-            @staticmethod
-            def _create_ctype_obj(init):
-                if init is None:
-                    return ctype()
-                return ctype(CTypesPrimitive._to_ctypes(init))
-
-            if kind == 'int' or kind == 'byte':
-                @classmethod
-                def _cast_from(cls, source):
-                    source = _cast_source_to_int(source)
-                    source = ctype(source).value     # cast within range
-                    return cls(source)
-                def __int__(self):
-                    return self._value
-
-            if kind == 'bool':
-                @classmethod
-                def _cast_from(cls, source):
-                    if not isinstance(source, (int, long, float)):
-                        source = _cast_source_to_int(source)
-                    return cls(bool(source))
-                def __int__(self):
-                    return self._value
-
-            if kind == 'char':
-                @classmethod
-                def _cast_from(cls, source):
-                    source = _cast_source_to_int(source)
-                    source = bytechr(source & 0xFF)
-                    return cls(source)
-                def __int__(self):
-                    return ord(self._value)
-
-            if kind == 'float':
-                @classmethod
-                def _cast_from(cls, source):
-                    if isinstance(source, float):
-                        pass
-                    elif isinstance(source, CTypesGenericPrimitive):
-                        if hasattr(source, '__float__'):
-                            source = float(source)
-                        else:
-                            source = int(source)
-                    else:
-                        source = _cast_source_to_int(source)
-                    source = ctype(source).value     # fix precision
-                    return cls(source)
-                def __int__(self):
-                    return int(self._value)
-                def __float__(self):
-                    return self._value
-
-            _cast_to_integer = __int__
-
-            if kind == 'int' or kind == 'byte' or kind == 'bool':
-                @staticmethod
-                def _to_ctypes(x):
-                    if not isinstance(x, (int, long)):
-                        if isinstance(x, CTypesData):
-                            x = int(x)
-                        else:
-                            raise TypeError("integer expected, got %s" %
-                                            type(x).__name__)
-                    if ctype(x).value != x:
-                        if not is_signed and x < 0:
-                            raise OverflowError("%s: negative integer" % name)
-                        else:
-                            raise OverflowError("%s: integer out of bounds"
-                                                % name)
-                    return x
-
-            if kind == 'char':
-                @staticmethod
-                def _to_ctypes(x):
-                    if isinstance(x, bytes) and len(x) == 1:
-                        return x
-                    if isinstance(x, CTypesPrimitive):    # <CData <char>>
-                        return x._value
-                    raise TypeError("character expected, got %s" %
-                                    type(x).__name__)
-                def __nonzero__(self):
-                    return ord(self._value) != 0
-            else:
-                def __nonzero__(self):
-                    return self._value != 0
-            __bool__ = __nonzero__
-
-            if kind == 'float':
-                @staticmethod
-                def _to_ctypes(x):
-                    if not isinstance(x, (int, long, float, CTypesData)):
-                        raise TypeError("float expected, got %s" %
-                                        type(x).__name__)
-                    return ctype(x).value
-
-            @staticmethod
-            def _from_ctypes(value):
-                return getattr(value, 'value', value)
-
-            @staticmethod
-            def _initialize(blob, init):
-                blob.value = CTypesPrimitive._to_ctypes(init)
-
-            if kind == 'char':
-                def _to_string(self, maxlen):
-                    return self._value
-            if kind == 'byte':
-                def _to_string(self, maxlen):
-                    return chr(self._value & 0xff)
-        #
-        CTypesPrimitive._fix_class()
-        return CTypesPrimitive
-
-    def new_pointer_type(self, BItem):
-        getbtype = self.ffi._get_cached_btype
-        if BItem is getbtype(model.PrimitiveType('char')):
-            kind = 'charp'
-        elif BItem in (getbtype(model.PrimitiveType('signed char')),
-                       getbtype(model.PrimitiveType('unsigned char'))):
-            kind = 'bytep'
-        elif BItem is getbtype(model.void_type):
-            kind = 'voidp'
-        else:
-            kind = 'generic'
-        #
-        class CTypesPtr(CTypesGenericPtr):
-            __slots__ = ['_own']
-            if kind == 'charp':
-                __slots__ += ['__as_strbuf']
-            _BItem = BItem
-            if hasattr(BItem, '_ctype'):
-                _ctype = ctypes.POINTER(BItem._ctype)
-                _bitem_size = ctypes.sizeof(BItem._ctype)
-            else:
-                _ctype = ctypes.c_void_p
-            if issubclass(BItem, CTypesGenericArray):
-                _reftypename = BItem._get_c_name('(* &)')
-            else:
-                _reftypename = BItem._get_c_name(' * &')
-
-            def __init__(self, init):
-                ctypeobj = BItem._create_ctype_obj(init)
-                if kind == 'charp':
-                    self.__as_strbuf = ctypes.create_string_buffer(
-                        ctypeobj.value + b'\x00')
-                    self._as_ctype_ptr = ctypes.cast(
-                        self.__as_strbuf, self._ctype)
-                else:
-                    self._as_ctype_ptr = ctypes.pointer(ctypeobj)
-                self._address = ctypes.cast(self._as_ctype_ptr,
-                                            ctypes.c_void_p).value
-                self._own = True
-
-            def __add__(self, other):
-                if isinstance(other, (int, long)):
-                    return self._new_pointer_at(self._address +
-                                                other * self._bitem_size)
-                else:
-                    return NotImplemented
-
-            def __sub__(self, other):
-                if isinstance(other, (int, long)):
-                    return self._new_pointer_at(self._address -
-                                                other * self._bitem_size)
-                elif type(self) is type(other):
-                    return (self._address - other._address) // self._bitem_size
-                else:
-                    return NotImplemented
-
-            def __getitem__(self, index):
-                if getattr(self, '_own', False) and index != 0:
-                    raise IndexError
-                return BItem._from_ctypes(self._as_ctype_ptr[index])
-
-            def __setitem__(self, index, value):
-                self._as_ctype_ptr[index] = BItem._to_ctypes(value)
-
-            if kind == 'charp' or kind == 'voidp':
-                @classmethod
-                def _arg_to_ctypes(cls, *value):
-                    if value and isinstance(value[0], bytes):
-                        return ctypes.c_char_p(value[0])
-                    else:
-                        return super(CTypesPtr, cls)._arg_to_ctypes(*value)
-
-            if kind == 'charp' or kind == 'bytep':
-                def _to_string(self, maxlen):
-                    if maxlen < 0:
-                        maxlen = sys.maxsize
-                    p = ctypes.cast(self._as_ctype_ptr,
-                                    ctypes.POINTER(ctypes.c_char))
-                    n = 0
-                    while n < maxlen and p[n] != b'\x00':
-                        n += 1
-                    return b''.join([p[i] for i in range(n)])
-
-            def _get_own_repr(self):
-                if getattr(self, '_own', False):
-                    return 'owning %d bytes' % (
-                        ctypes.sizeof(self._as_ctype_ptr.contents),)
-                return super(CTypesPtr, self)._get_own_repr()
-        #
-        if (BItem is self.ffi._get_cached_btype(model.void_type) or
-            BItem is self.ffi._get_cached_btype(model.PrimitiveType('char'))):
-            CTypesPtr._automatic_casts = True
-        #
-        CTypesPtr._fix_class()
-        return CTypesPtr
-
-    def new_array_type(self, CTypesPtr, length):
-        if length is None:
-            brackets = ' &[]'
-        else:
-            brackets = ' &[%d]' % length
-        BItem = CTypesPtr._BItem
-        getbtype = self.ffi._get_cached_btype
-        if BItem is getbtype(model.PrimitiveType('char')):
-            kind = 'char'
-        elif BItem in (getbtype(model.PrimitiveType('signed char')),
-                       getbtype(model.PrimitiveType('unsigned char'))):
-            kind = 'byte'
-        else:
-            kind = 'generic'
-        #
-        class CTypesArray(CTypesGenericArray):
-            __slots__ = ['_blob', '_own']
-            if length is not None:
-                _ctype = BItem._ctype * length
-            else:
-                __slots__.append('_ctype')
-            _reftypename = BItem._get_c_name(brackets)
-            _declared_length = length
-            _CTPtr = CTypesPtr
-
-            def __init__(self, init):
-                if length is None:
-                    if isinstance(init, (int, long)):
-                        len1 = init
-                        init = None
-                    elif kind == 'char' and isinstance(init, bytes):
-                        len1 = len(init) + 1    # extra null
-                    else:
-                        init = tuple(init)
-                        len1 = len(init)
-                    self._ctype = BItem._ctype * len1
-                self._blob = self._ctype()
-                self._own = True
-                if init is not None:
-                    self._initialize(self._blob, init)
-
-            @staticmethod
-            def _initialize(blob, init):
-                if isinstance(init, bytes):
-                    init = [init[i:i+1] for i in range(len(init))]
-                else:
-                    init = tuple(init)
-                if len(init) > len(blob):
-                    raise IndexError("too many initializers")
-                addr = ctypes.cast(blob, ctypes.c_void_p).value
-                PTR = ctypes.POINTER(BItem._ctype)
-                itemsize = ctypes.sizeof(BItem._ctype)
-                for i, value in enumerate(init):
-                    p = ctypes.cast(addr + i * itemsize, PTR)
-                    BItem._initialize(p.contents, value)
-
-            def __len__(self):
-                return len(self._blob)
-
-            def __getitem__(self, index):
-                if not (0 <= index < len(self._blob)):
-                    raise IndexError
-                return BItem._from_ctypes(self._blob[index])
-
-            def __setitem__(self, index, value):
-                if not (0 <= index < len(self._blob)):
-                    raise IndexError
-                self._blob[index] = BItem._to_ctypes(value)
-
-            if kind == 'char' or kind == 'byte':
-                def _to_string(self, maxlen):
-                    if maxlen < 0:
-                        maxlen = len(self._blob)
-                    p = ctypes.cast(self._blob,
-                                    ctypes.POINTER(ctypes.c_char))
-                    n = 0
-                    while n < maxlen and p[n] != b'\x00':
-                        n += 1
-                    return b''.join([p[i] for i in range(n)])
-
-            def _get_own_repr(self):
-                if getattr(self, '_own', False):
-                    return 'owning %d bytes' % (ctypes.sizeof(self._blob),)
-                return super(CTypesArray, self)._get_own_repr()
-
-            def _convert_to_address(self, BClass):
-                if BClass in (CTypesPtr, None) or BClass._automatic_casts:
-                    return ctypes.addressof(self._blob)
-                else:
-                    return CTypesData._convert_to_address(self, BClass)
-
-            @staticmethod
-            def _from_ctypes(ctypes_array):
-                self = CTypesArray.__new__(CTypesArray)
-                self._blob = ctypes_array
-                return self
-
-            @staticmethod
-            def _arg_to_ctypes(value):
-                return CTypesPtr._arg_to_ctypes(value)
-
-            def __add__(self, other):
-                if isinstance(other, (int, long)):
-                    return CTypesPtr._new_pointer_at(
-                        ctypes.addressof(self._blob) +
-                        other * ctypes.sizeof(BItem._ctype))
-                else:
-                    return NotImplemented
-
-            @classmethod
-            def _cast_from(cls, source):
-                raise NotImplementedError("casting to %r" % (
-                    cls._get_c_name(),))
-        #
-        CTypesArray._fix_class()
-        return CTypesArray
-
-    def _new_struct_or_union(self, kind, name, base_ctypes_class):
-        #
-        class struct_or_union(base_ctypes_class):
-            pass
-        struct_or_union.__name__ = '%s_%s' % (kind, name)
-        kind1 = kind
-        #
-        class CTypesStructOrUnion(CTypesBaseStructOrUnion):
-            __slots__ = ['_blob']
-            _ctype = struct_or_union
-            _reftypename = '%s &' % (name,)
-            _kind = kind = kind1
-        #
-        CTypesStructOrUnion._fix_class()
-        return CTypesStructOrUnion
-
-    def new_struct_type(self, name):
-        return self._new_struct_or_union('struct', name, ctypes.Structure)
-
-    def new_union_type(self, name):
-        return self._new_struct_or_union('union', name, ctypes.Union)
-
-    def complete_struct_or_union(self, CTypesStructOrUnion, fields, tp,
-                                 totalsize=-1, totalalignment=-1, sflags=0):
-        if totalsize >= 0 or totalalignment >= 0:
-            raise NotImplementedError("the ctypes backend of CFFI does not support "
-                                      "structures completed by verify(); please "
-                                      "compile and install the _cffi_backend module.")
-        struct_or_union = CTypesStructOrUnion._ctype
-        fnames = [fname for (fname, BField, bitsize) in fields]
-        btypes = [BField for (fname, BField, bitsize) in fields]
-        bitfields = [bitsize for (fname, BField, bitsize) in fields]
-        #
-        bfield_types = {}
-        cfields = []
-        for (fname, BField, bitsize) in fields:
-            if bitsize < 0:
-                cfields.append((fname, BField._ctype))
-                bfield_types[fname] = BField
-            else:
-                cfields.append((fname, BField._ctype, bitsize))
-                bfield_types[fname] = Ellipsis
-        if sflags & 8:
-            struct_or_union._pack_ = 1
-        struct_or_union._fields_ = cfields
-        CTypesStructOrUnion._bfield_types = bfield_types
-        #
-        @staticmethod
-        def _create_ctype_obj(init):
-            result = struct_or_union()
-            if init is not None:
-                initialize(result, init)
-            return result
-        CTypesStructOrUnion._create_ctype_obj = _create_ctype_obj
-        #
-        def initialize(blob, init):
-            if is_union:
-                if len(init) > 1:
-                    raise ValueError("union initializer: %d items given, but "
-                                    "only one supported (use a dict if needed)"
-                                     % (len(init),))
-            if not isinstance(init, dict):
-                if isinstance(init, (bytes, unicode)):
-                    raise TypeError("union initializer: got a str")
-                init = tuple(init)
-                if len(init) > len(fnames):
-                    raise ValueError("too many values for %s initializer" %
-                                     CTypesStructOrUnion._get_c_name())
-                init = dict(zip(fnames, init))
-            addr = ctypes.addressof(blob)
-            for fname, value in init.items():
-                BField, bitsize = name2fieldtype[fname]
-                assert bitsize < 0, \
-                       "not implemented: initializer with bit fields"
-                offset = CTypesStructOrUnion._offsetof(fname)
-                PTR = ctypes.POINTER(BField._ctype)
-                p = ctypes.cast(addr + offset, PTR)
-                BField._initialize(p.contents, value)
-        is_union = CTypesStructOrUnion._kind == 'union'
-        name2fieldtype = dict(zip(fnames, zip(btypes, bitfields)))
-        #
-        for fname, BField, bitsize in fields:
-            if fname == '':
-                raise NotImplementedError("nested anonymous structs/unions")
-            if hasattr(CTypesStructOrUnion, fname):
-                raise ValueError("the field name %r conflicts in "
-                                 "the ctypes backend" % fname)
-            if bitsize < 0:
-                def getter(self, fname=fname, BField=BField,
-                           offset=CTypesStructOrUnion._offsetof(fname),
-                           PTR=ctypes.POINTER(BField._ctype)):
-                    addr = ctypes.addressof(self._blob)
-                    p = ctypes.cast(addr + offset, PTR)
-                    return BField._from_ctypes(p.contents)
-                def setter(self, value, fname=fname, BField=BField):
-                    setattr(self._blob, fname, BField._to_ctypes(value))
-                #
-                if issubclass(BField, CTypesGenericArray):
-                    setter = None
-                    if BField._declared_length == 0:
-                        def getter(self, fname=fname, BFieldPtr=BField._CTPtr,
-                                   offset=CTypesStructOrUnion._offsetof(fname),
-                                   PTR=ctypes.POINTER(BField._ctype)):
-                            addr = ctypes.addressof(self._blob)
-                            p = ctypes.cast(addr + offset, PTR)
-                            return BFieldPtr._from_ctypes(p)
-                #
-            else:
-                def getter(self, fname=fname, BField=BField):
-                    return BField._from_ctypes(getattr(self._blob, fname))
-                def setter(self, value, fname=fname, BField=BField):
-                    # xxx obscure workaround
-                    value = BField._to_ctypes(value)
-                    oldvalue = getattr(self._blob, fname)
-                    setattr(self._blob, fname, value)
-                    if value != getattr(self._blob, fname):
-                        setattr(self._blob, fname, oldvalue)
-                        raise OverflowError("value too large for bitfield")
-            setattr(CTypesStructOrUnion, fname, property(getter, setter))
-        #
-        CTypesPtr = self.ffi._get_cached_btype(model.PointerType(tp))
-        for fname in fnames:
-            if hasattr(CTypesPtr, fname):
-                raise ValueError("the field name %r conflicts in "
-                                 "the ctypes backend" % fname)
-            def getter(self, fname=fname):
-                return getattr(self[0], fname)
-            def setter(self, value, fname=fname):
-                setattr(self[0], fname, value)
-            setattr(CTypesPtr, fname, property(getter, setter))
-
-    def new_function_type(self, BArgs, BResult, has_varargs):
-        nameargs = [BArg._get_c_name() for BArg in BArgs]
-        if has_varargs:
-            nameargs.append('...')
-        nameargs = ', '.join(nameargs)
-        #
-        class CTypesFunctionPtr(CTypesGenericPtr):
-            __slots__ = ['_own_callback', '_name']
-            _ctype = ctypes.CFUNCTYPE(getattr(BResult, '_ctype', None),
-                                      *[BArg._ctype for BArg in BArgs],
-                                      use_errno=True)
-            _reftypename = BResult._get_c_name('(* &)(%s)' % (nameargs,))
-
-            def __init__(self, init, error=None):
-                # create a callback to the Python callable init()
-                import traceback
-                assert not has_varargs, "varargs not supported for callbacks"
-                if getattr(BResult, '_ctype', None) is not None:
-                    error = BResult._from_ctypes(
-                        BResult._create_ctype_obj(error))
-                else:
-                    error = None
-                def callback(*args):
-                    args2 = []
-                    for arg, BArg in zip(args, BArgs):
-                        args2.append(BArg._from_ctypes(arg))
-                    try:
-                        res2 = init(*args2)
-                        res2 = BResult._to_ctypes(res2)
-                    except:
-                        traceback.print_exc()
-                        res2 = error
-                    if issubclass(BResult, CTypesGenericPtr):
-                        if res2:
-                            res2 = ctypes.cast(res2, ctypes.c_void_p).value
-                                # .value: http://bugs.python.org/issue1574593
-                        else:
-                            res2 = None
-                    #print repr(res2)
-                    return res2
-                if issubclass(BResult, CTypesGenericPtr):
-                    # The only pointers callbacks can return are void*s:
-                    # http://bugs.python.org/issue5710
-                    callback_ctype = ctypes.CFUNCTYPE(
-                        ctypes.c_void_p,
-                        *[BArg._ctype for BArg in BArgs],
-                        use_errno=True)
-                else:
-                    callback_ctype = CTypesFunctionPtr._ctype
-                self._as_ctype_ptr = callback_ctype(callback)
-                self._address = ctypes.cast(self._as_ctype_ptr,
-                                            ctypes.c_void_p).value
-                self._own_callback = init
-
-            @staticmethod
-            def _initialize(ctypes_ptr, value):
-                if value:
-                    raise NotImplementedError("ctypes backend: not supported: "
-                                          "initializers for function pointers")
-
-            def __repr__(self):
-                c_name = getattr(self, '_name', None)
-                if c_name:
-                    i = self._reftypename.index('(* &)')
-                    if self._reftypename[i-1] not in ' )*':
-                        c_name = ' ' + c_name
-                    c_name = self._reftypename.replace('(* &)', c_name)
-                return CTypesData.__repr__(self, c_name)
-
-            def _get_own_repr(self):
-                if getattr(self, '_own_callback', None) is not None:
-                    return 'calling %r' % (self._own_callback,)
-                return super(CTypesFunctionPtr, self)._get_own_repr()
-
-            def __call__(self, *args):
-                if has_varargs:
-                    assert len(args) >= len(BArgs)
-                    extraargs = args[len(BArgs):]
-                    args = args[:len(BArgs)]
-                else:
-                    assert len(args) == len(BArgs)
-                ctypes_args = []
-                for arg, BArg in zip(args, BArgs):
-                    ctypes_args.append(BArg._arg_to_ctypes(arg))
-                if has_varargs:
-                    for i, arg in enumerate(extraargs):
-                        if arg is None:
-                            ctypes_args.append(ctypes.c_void_p(0))  # NULL
-                            continue
-                        if not isinstance(arg, CTypesData):
-                            raise TypeError(
-                                "argument %d passed in the variadic part "
-                                "needs to be a cdata object (got %s)" %
-                                (1 + len(BArgs) + i, type(arg).__name__))
-                        ctypes_args.append(arg._arg_to_ctypes(arg))
-                result = self._as_ctype_ptr(*ctypes_args)
-                return BResult._from_ctypes(result)
-        #
-        CTypesFunctionPtr._fix_class()
-        return CTypesFunctionPtr
-
-    def new_enum_type(self, name, enumerators, enumvalues, CTypesInt):
-        assert isinstance(name, str)
-        reverse_mapping = dict(zip(reversed(enumvalues),
-                                   reversed(enumerators)))
-        #
-        class CTypesEnum(CTypesInt):
-            __slots__ = []
-            _reftypename = '%s &' % name
-
-            def _get_own_repr(self):
-                value = self._value
-                try:
-                    return '%d: %s' % (value, reverse_mapping[value])
-                except KeyError:
-                    return str(value)
-
-            def _to_string(self, maxlen):
-                value = self._value
-                try:
-                    return reverse_mapping[value]
-                except KeyError:
-                    return str(value)
-        #
-        CTypesEnum._fix_class()
-        return CTypesEnum
-
-    def get_errno(self):
-        return ctypes.get_errno()
-
-    def set_errno(self, value):
-        ctypes.set_errno(value)
-
-    def string(self, b, maxlen=-1):
-        return b._to_string(maxlen)
-
-    def buffer(self, bptr, size=-1):
-        raise NotImplementedError("buffer() with ctypes backend")
-
-    def sizeof(self, cdata_or_BType):
-        if isinstance(cdata_or_BType, CTypesData):
-            return cdata_or_BType._get_size_of_instance()
-        else:
-            assert issubclass(cdata_or_BType, CTypesData)
-            return cdata_or_BType._get_size()
-
-    def alignof(self, BType):
-        assert issubclass(BType, CTypesData)
-        return BType._alignment()
-
-    def newp(self, BType, source):
-        if not issubclass(BType, CTypesData):
-            raise TypeError
-        return BType._newp(source)
-
-    def cast(self, BType, source):
-        return BType._cast_from(source)
-
-    def callback(self, BType, source, error, onerror):
-        assert onerror is None   # XXX not implemented
-        return BType(source, error)
-
-    def gcp(self, cdata, destructor):
-        BType = self.typeof(cdata)
-
-        if destructor is None:
-            if not (hasattr(BType, '_gcp_type') and
-                    BType._gcp_type is BType):
-                raise TypeError("Can remove destructor only on a object "
-                                "previously returned by ffi.gc()")
-            cdata._destructor = None
-            return None
-
-        try:
-            gcp_type = BType._gcp_type
-        except AttributeError:
-            class CTypesDataGcp(BType):
-                __slots__ = ['_orig', '_destructor']
-                def __del__(self):
-                    if self._destructor is not None:
-                        self._destructor(self._orig)
-            gcp_type = BType._gcp_type = CTypesDataGcp
-        new_cdata = self.cast(gcp_type, cdata)
-        new_cdata._orig = cdata
-        new_cdata._destructor = destructor
-        return new_cdata
-
-    typeof = type
-
-    def getcname(self, BType, replace_with):
-        return BType._get_c_name(replace_with)
-
-    def typeoffsetof(self, BType, fieldname, num=0):
-        if isinstance(fieldname, str):
-            if num == 0 and issubclass(BType, CTypesGenericPtr):
-                BType = BType._BItem
-            if not issubclass(BType, CTypesBaseStructOrUnion):
-                raise TypeError("expected a struct or union ctype")
-            BField = BType._bfield_types[fieldname]
-            if BField is Ellipsis:
-                raise TypeError("not supported for bitfields")
-            return (BField, BType._offsetof(fieldname))
-        elif isinstance(fieldname, (int, long)):
-            if issubclass(BType, CTypesGenericArray):
-                BType = BType._CTPtr
-            if not issubclass(BType, CTypesGenericPtr):
-                raise TypeError("expected an array or ptr ctype")
-            BItem = BType._BItem
-            offset = BItem._get_size() * fieldname
-            if offset > sys.maxsize:
-                raise OverflowError
-            return (BItem, offset)
-        else:
-            raise TypeError(type(fieldname))
-
-    def rawaddressof(self, BTypePtr, cdata, offset=None):
-        if isinstance(cdata, CTypesBaseStructOrUnion):
-            ptr = ctypes.pointer(type(cdata)._to_ctypes(cdata))
-        elif isinstance(cdata, CTypesGenericPtr):
-            if offset is None or not issubclass(type(cdata)._BItem,
-                                                CTypesBaseStructOrUnion):
-                raise TypeError("unexpected cdata type")
-            ptr = type(cdata)._to_ctypes(cdata)
-        elif isinstance(cdata, CTypesGenericArray):
-            ptr = type(cdata)._to_ctypes(cdata)
-        else:
-            raise TypeError("expected a <cdata 'struct-or-union'>")
-        if offset:
-            ptr = ctypes.cast(
-                ctypes.c_void_p(
-                    ctypes.cast(ptr, ctypes.c_void_p).value + offset),
-                type(ptr))
-        return BTypePtr._from_ctypes(ptr)
-
-
-class CTypesLibrary(object):
-
-    def __init__(self, backend, cdll):
-        self.backend = backend
-        self.cdll = cdll
-
-    def load_function(self, BType, name):
-        c_func = getattr(self.cdll, name)
-        funcobj = BType._from_ctypes(c_func)
-        funcobj._name = name
-        return funcobj
-
-    def read_variable(self, BType, name):
-        try:
-            ctypes_obj = BType._ctype.in_dll(self.cdll, name)
-        except AttributeError as e:
-            raise NotImplementedError(e)
-        return BType._from_ctypes(ctypes_obj)
-
-    def write_variable(self, BType, name, value):
-        new_ctypes_obj = BType._to_ctypes(value)
-        ctypes_obj = BType._ctype.in_dll(self.cdll, name)
-        ctypes.memmove(ctypes.addressof(ctypes_obj),
-                       ctypes.addressof(new_ctypes_obj),
-                       ctypes.sizeof(BType._ctype))
diff --git a/doc/source/whatsnew.rst b/doc/source/whatsnew.rst
--- a/doc/source/whatsnew.rst
+++ b/doc/source/whatsnew.rst
@@ -23,6 +23,10 @@
   argument (in older versions, a copy would be made).  This used to be
   a CPython-only optimization.
 
+* Removed the ctypes backend.  If ``_cffi_backend`` was not compiled,
+  you could ask (using an undocumented interface) for ``backend_ctypes``
+  instead.  That was never fully functional and long deprecated.
+
 
 v1.7
 ====
diff --git a/testing/cffi0/backend_tests.py b/testing/cffi0/test_backend.py
rename from testing/cffi0/backend_tests.py
rename to testing/cffi0/test_backend.py
--- a/testing/cffi0/backend_tests.py
+++ b/testing/cffi0/test_backend.py
@@ -11,10 +11,10 @@
 SIZE_OF_WCHAR = ctypes.sizeof(ctypes.c_wchar)
 
 
-class BackendTests:
+class TestBackend(object):
 
     def test_integer_ranges(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         for (c_type, size) in [('char', 1),
                                ('short', 2),
                                ('short int', 2),
@@ -34,7 +34,7 @@
                 self._test_int_type(ffi, c_decl, size, unsigned)
 
     def test_fixedsize_int(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         for size in [1, 2, 4, 8]:
             self._test_int_type(ffi, 'int%d_t' % (8*size), size, False)
             self._test_int_type(ffi, 'uint%d_t' % (8*size), size, True)
@@ -79,12 +79,12 @@
         assert ffi.new(c_decl_ptr, long(max))[0] == max
 
     def test_new_unsupported_type(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         e = py.test.raises(TypeError, ffi.new, "int")
         assert str(e.value) == "expected a pointer or array ctype, got 'int'"
 
     def test_new_single_integer(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         p = ffi.new("int *")     # similar to ffi.new("int[1]")
         assert p[0] == 0
         p[0] = -123
@@ -94,14 +94,14 @@
         assert repr(p) == "<cdata 'int *' owning %d bytes>" % SIZE_OF_INT
 
     def test_new_array_no_arg(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         p = ffi.new("int[10]")
         # the object was zero-initialized:
         for i in range(10):
             assert p[i] == 0
 
     def test_array_indexing(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         p = ffi.new("int[10]")
         p[0] = 42
         p[9] = 43
@@ -113,7 +113,7 @@
         py.test.raises(IndexError, "p[-1] = 44")
 
     def test_new_array_args(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         # this tries to be closer to C: where we say "int x[5] = {10, 20, ..}"
         # then here we must enclose the items in a list
         p = ffi.new("int[5]", [10, 20, 30, 40, 50])
@@ -132,7 +132,7 @@
         assert repr(p) == "<cdata 'int[4]' owning %d bytes>" % (4*SIZE_OF_INT)
 
     def test_new_array_varsize(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         p = ffi.new("int[]", 10)     # a single integer is the length
         assert p[9] == 0
         py.test.raises(IndexError, "p[10]")
@@ -151,7 +151,7 @@
         assert repr(p) == "<cdata 'int[]' owning 0 bytes>"
 
     def test_pointer_init(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         n = ffi.new("int *", 24)
         a = ffi.new("int *[10]", [ffi.NULL, ffi.NULL, n, n, ffi.NULL])
         for i in range(10):
@@ -160,14 +160,14 @@
         assert a[2] == a[3] == n
 
     def test_cannot_cast(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         a = ffi.new("short int[10]")
         e = py.test.raises(TypeError, ffi.new, "long int **", a)
         msg = str(e.value)
         assert "'short[10]'" in msg and "'long *'" in msg
 
     def test_new_pointer_to_array(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         a = ffi.new("int[4]", [100, 102, 104, 106])
         p = ffi.new("int **", a)
         assert p[0] == ffi.cast("int *", a)
@@ -180,7 +180,7 @@
         # keepalive: a
 
     def test_pointer_direct(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         p = ffi.cast("int*", 0)
         assert p is not None
         assert bool(p) is False
@@ -195,9 +195,11 @@
         assert p[0] == 123
         assert p[1] == 456
 
+    TypeRepr = "<ctype '%s'>"
+
     def test_repr(self):
         typerepr = self.TypeRepr
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("struct foo { short a, b, c; };")
         p = ffi.cast("short unsigned int", 0)
         assert repr(p) == "<cdata 'unsigned short' 0>"
@@ -248,7 +250,7 @@
         assert repr(ffi.typeof(q)) == typerepr % "struct foo"
 
     def test_new_array_of_array(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         p = ffi.new("int[3][4]")
         p[0][0] = 10
         p[2][3] = 33
@@ -257,12 +259,12 @@
         py.test.raises(IndexError, "p[1][-1]")
 
     def test_constructor_array_of_array(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         p = ffi.new("int[3][2]", [[10, 11], [12, 13], [14, 15]])
         assert p[2][1] == 15
 
     def test_new_array_of_pointer_1(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         n = ffi.new("int*", 99)
         p = ffi.new("int*[4]")
         p[3] = n
@@ -271,7 +273,7 @@
         assert a[0] == 99
 
     def test_new_array_of_pointer_2(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         n = ffi.new("int[1]", [99])
         p = ffi.new("int*[4]")
         p[3] = n
@@ -280,7 +282,7 @@
         assert a[0] == 99
 
     def test_char(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         assert ffi.new("char*", b"\xff")[0] == b'\xff'
         assert ffi.new("char*")[0] == b'\x00'
         assert int(ffi.cast("char", 300)) == 300 - 256
@@ -317,7 +319,7 @@
             py.test.skip("NotImplementedError: wchar_t")
 
     def test_wchar_t(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         self.check_wchar_t(ffi)
         assert ffi.new("wchar_t*", u+'x')[0] == u+'x'
         assert ffi.new("wchar_t*", u+'\u1234')[0] == u+'\u1234'
@@ -372,7 +374,7 @@
         py.test.raises(IndexError, ffi.new, "wchar_t[2]", u+"abc")
 
     def test_none_as_null_doesnt_work(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         p = ffi.new("int*[1]")
         assert p[0] is not None
         assert p[0] != None
@@ -387,7 +389,7 @@
         assert p[0] == ffi.NULL
 
     def test_float(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         p = ffi.new("float[]", [-2, -2.5])
         assert p[0] == -2.0
         assert p[1] == -2.5
@@ -412,7 +414,7 @@
         assert p[0] == INF     # infinite, not enough precision
 
     def test_struct_simple(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("struct foo { int a; short b, c; };")
         s = ffi.new("struct foo*")
         assert s.a == s.b == s.c == 0
@@ -431,7 +433,7 @@
         py.test.raises(ValueError, ffi.new, "struct foo*", [1, 2, 3, 4])
 
     def test_constructor_struct_from_dict(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("struct foo { int a; short b, c; };")
         s = ffi.new("struct foo*", {'b': 123, 'c': 456})
         assert s.a == 0
@@ -440,7 +442,7 @@
         py.test.raises(KeyError, ffi.new, "struct foo*", {'d': 456})
 
     def test_struct_pointer(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("struct foo { int a; short b, c; };")
         s = ffi.new("struct foo*")
         assert s[0].a == s[0].b == s[0].c == 0
@@ -450,13 +452,13 @@
         py.test.raises(IndexError, "s[1]")
 
     def test_struct_opaque(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         py.test.raises(TypeError, ffi.new, "struct baz*")
         p = ffi.new("struct baz **")    # this works
         assert p[0] == ffi.NULL
 
     def test_pointer_to_struct(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("struct foo { int a; short b, c; };")
         s = ffi.new("struct foo *")
         s.a = -42
@@ -478,7 +480,7 @@
         assert p[0][0].a == -46
 
     def test_constructor_struct_of_array(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("struct foo { int a[2]; char b[3]; };")
         s = ffi.new("struct foo *", [[10, 11], [b'a', b'b', b'c']])
         assert s.a[1] == 11
@@ -489,7 +491,7 @@
         assert s.b[2] == b'c'
 
     def test_recursive_struct(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("struct foo { int value; struct foo *next; };")
         s = ffi.new("struct foo*")
         t = ffi.new("struct foo*")
@@ -500,7 +502,7 @@
         assert s.next.value == 456
 
     def test_union_simple(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("union foo { int a; short b, c; };")
         u = ffi.new("union foo*")
         assert u.a == u.b == u.c == 0
@@ -515,13 +517,13 @@
         assert repr(u) == "<cdata 'union foo *' owning %d bytes>" % SIZE_OF_INT
 
     def test_union_opaque(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         py.test.raises(TypeError, ffi.new, "union baz *")
         u = ffi.new("union baz **")   # this works
         assert u[0] == ffi.NULL
 
     def test_union_initializer(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("union foo { char a; int b; };")
         py.test.raises(TypeError, ffi.new, "union foo*", b'A')
         py.test.raises(TypeError, ffi.new, "union foo*", 5)
@@ -536,7 +538,7 @@
         assert u.b == 0
 
     def test_sizeof_type(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("""
             struct foo { int a; short b, c, d; };
             union foo { int a; short b, c, d; };
@@ -553,7 +555,7 @@
             assert size == expected_size, (size, expected_size, ctype)
 
     def test_sizeof_cdata(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         assert ffi.sizeof(ffi.new("short*")) == SIZE_OF_PTR
         assert ffi.sizeof(ffi.cast("short", 123)) == SIZE_OF_SHORT
         #
@@ -562,7 +564,7 @@
         assert ffi.sizeof(a) == 5 * SIZE_OF_INT
 
     def test_string_from_char_pointer(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         x = ffi.new("char*", b"x")
         assert str(x) == repr(x)
         assert ffi.string(x) == b"x"
@@ -570,7 +572,7 @@
         py.test.raises(TypeError, ffi.new, "char*", unicode("foo"))
 
     def test_unicode_from_wchar_pointer(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         self.check_wchar_t(ffi)
         x = ffi.new("wchar_t*", u+"x")
         assert unicode(x) == unicode(repr(x))
@@ -578,7 +580,7 @@
         assert ffi.string(ffi.new("wchar_t*", u+"\x00")) == u+""
 
     def test_string_from_char_array(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         p = ffi.new("char[]", b"hello.")
         p[5] = b'!'
         assert ffi.string(p) == b"hello!"
@@ -595,7 +597,7 @@
         assert ffi.string(p) == b'hello'
 
     def test_string_from_wchar_array(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         self.check_wchar_t(ffi)
         assert ffi.string(ffi.cast("wchar_t", "x")) == u+"x"
         assert ffi.string(ffi.cast("wchar_t", u+"x")) == u+"x"
@@ -623,7 +625,7 @@
 
     def test_fetch_const_char_p_field(self):
         # 'const' is ignored so far
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("struct foo { const char *name; };")
         t = ffi.new("const char[]", b"testing")
         s = ffi.new("struct foo*", [t])
@@ -635,7 +637,7 @@
 
     def test_fetch_const_wchar_p_field(self):
         # 'const' is ignored so far
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         self.check_wchar_t(ffi)
         ffi.cdef("struct foo { const wchar_t *name; };")
         t = ffi.new("const wchar_t[]", u+"testing")
@@ -646,7 +648,7 @@
         assert s.name == ffi.NULL
 
     def test_voidp(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         py.test.raises(TypeError, ffi.new, "void*")
         p = ffi.new("void **")
         assert p[0] == ffi.NULL
@@ -667,7 +669,7 @@
         py.test.raises(TypeError, "s.r = b")    # fails
 
     def test_functionptr_simple(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         py.test.raises(TypeError, ffi.callback, "int(*)(int)", 0)
         def cb(n):
             return n + 1
@@ -692,12 +694,12 @@
         assert res == 46
 
     def test_functionptr_advanced(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         t = ffi.typeof("int(*(*)(int))(int)")
         assert repr(t) == self.TypeRepr % "int(*(*)(int))(int)"
 
     def test_functionptr_voidptr_return(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         def cb():
             return ffi.NULL
         p = ffi.callback("void*(*)()", cb)
@@ -713,7 +715,7 @@
         assert res == void_ptr
 
     def test_functionptr_intptr_return(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         def cb():
             return ffi.NULL
         p = ffi.callback("int*(*)()", cb)
@@ -735,7 +737,7 @@
         assert res == int_array_ptr
 
     def test_functionptr_void_return(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         def foo():
             pass
         foo_cb = ffi.callback("void foo()", foo)
@@ -743,7 +745,7 @@
         assert result is None
 
     def test_char_cast(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         p = ffi.cast("int", b'\x01')
         assert ffi.typeof(p) is ffi.typeof("int")
         assert int(p) == 1
@@ -755,7 +757,7 @@
         assert int(p) == 0x81
 
     def test_wchar_cast(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         self.check_wchar_t(ffi)
         p = ffi.cast("int", ffi.cast("wchar_t", u+'\u1234'))
         assert int(p) == 0x1234
@@ -771,7 +773,7 @@
         assert int(p) == 0x1234
 
     def test_cast_array_to_charp(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         a = ffi.new("short int[]", [0x1234, 0x5678])
         p = ffi.cast("char*", a)
         data = b''.join([p[i] for i in range(4)])
@@ -781,7 +783,7 @@
             assert data == b'\x12\x34\x56\x78'
 
     def test_cast_between_pointers(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         a = ffi.new("short int[]", [0x1234, 0x5678])
         p = ffi.cast("short*", a)
         p2 = ffi.cast("int*", p)
@@ -793,7 +795,7 @@
             assert data == b'\x12\x34\x56\x78'
 
     def test_cast_pointer_and_int(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         a = ffi.new("short int[]", [0x1234, 0x5678])
         l1 = ffi.cast("intptr_t", a)
         p = ffi.cast("short*", a)
@@ -805,7 +807,7 @@
         assert int(ffi.cast("intptr_t", ffi.NULL)) == 0
 
     def test_cast_functionptr_and_int(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         def cb(n):
             return n + 1
         a = ffi.callback("int(*)(int)", cb)
@@ -817,7 +819,7 @@
         assert hash(a) == hash(b)
 
     def test_callback_crash(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         def cb(n):
             raise Exception
         a = ffi.callback("int(*)(int)", cb, error=42)
@@ -825,7 +827,7 @@
         assert res == 42
 
     def test_structptr_argument(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("struct foo_s { int a, b; };")
         def cb(p):
             return p[0].a * 1000 + p[0].b * 100 + p[1].a * 10 + p[1].b
@@ -836,7 +838,7 @@
         assert res == 5008
 
     def test_array_argument_as_list(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("struct foo_s { int a, b; };")
         seen = []
         def cb(argv):
@@ -847,7 +849,7 @@
         assert seen == [b"foobar", b"baz"]
 
     def test_cast_float(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         a = ffi.cast("float", 12)
         assert float(a) == 12.0
         a = ffi.cast("float", 12.5)
@@ -871,7 +873,7 @@
         assert ffi.string(a) == b"B"
 
     def test_enum(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("enum foo { A0, B0, CC0, D0 };")
         assert ffi.string(ffi.cast("enum foo", 0)) == "A0"
         assert ffi.string(ffi.cast("enum foo", 2)) == "CC0"
@@ -893,7 +895,7 @@
         assert ffi.string(ffi.cast("enum baz", 0x2000)) == "B2"
 
     def test_enum_in_struct(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("enum foo { A, B, C, D }; struct bar { enum foo e; };")
         s = ffi.new("struct bar *")
         s.e = 0
@@ -914,7 +916,7 @@
         py.test.raises(TypeError, "s.e = '#7'")
 
     def test_enum_non_contiguous(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("enum foo { A, B=42, C };")
         assert ffi.string(ffi.cast("enum foo", 0)) == "A"
         assert ffi.string(ffi.cast("enum foo", 42)) == "B"
@@ -924,7 +926,7 @@
         assert ffi.string(invalid_value) == "2"
 
     def test_enum_char_hex_oct(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef(r"enum foo{A='!', B='\'', C=0x10, D=010, E=- 0x10, F=-010};")
         assert ffi.string(ffi.cast("enum foo", ord('!'))) == "A"
         assert ffi.string(ffi.cast("enum foo", ord("'"))) == "B"
@@ -934,7 +936,7 @@
         assert ffi.string(ffi.cast("enum foo", -8)) == "F"
 
     def test_enum_partial(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef(r"enum foo {A, ...}; enum bar { B, C };")
         lib = ffi.dlopen(None)
         assert lib.B == 0
@@ -942,7 +944,7 @@
         assert lib.C == 1
 
     def test_array_of_struct(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("struct foo { int a, b; };")
         s = ffi.new("struct foo[1]")
         py.test.raises(AttributeError, 's.b')
@@ -952,12 +954,12 @@
         py.test.raises(IndexError, 's[1]')
 
     def test_pointer_to_array(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         p = ffi.new("int(**)[5]")
         assert repr(p) == "<cdata 'int(* *)[5]' owning %d bytes>" % SIZE_OF_PTR
 
     def test_iterate_array(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         a = ffi.new("char[]", b"hello")
         assert list(a) == [b"h", b"e", b"l", b"l", b"o", b"\0"]
         assert list(iter(a)) == [b"h", b"e", b"l", b"l", b"o", b"\0"]
@@ -968,14 +970,14 @@
         py.test.raises(TypeError, list, ffi.new("int *"))
 
     def test_offsetof(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("struct foo { int a, b, c; };")
         assert ffi.offsetof("struct foo", "a") == 0
         assert ffi.offsetof("struct foo", "b") == 4
         assert ffi.offsetof("struct foo", "c") == 8
 
     def test_offsetof_nested(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("struct foo { int a, b, c; };"
                  "struct bar { struct foo d, e; };")
         assert ffi.offsetof("struct bar", "e") == 12
@@ -985,7 +987,7 @@
         assert ffi.offsetof("struct bar", "e", "c") == 20
 
     def test_offsetof_array(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         assert ffi.offsetof("int[]", 51) == 51 * ffi.sizeof("int")
         assert ffi.offsetof("int *", 51) == 51 * ffi.sizeof("int")
         ffi.cdef("struct bar { int a, b; int c[99]; };")
@@ -994,14 +996,14 @@
         assert ffi.offsetof("struct bar", "c", 51) == 53 * ffi.sizeof("int")
 
     def test_alignof(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("struct foo { char a; short b; char c; };")
         assert ffi.alignof("int") == 4
         assert ffi.alignof("double") in (4, 8)
         assert ffi.alignof("struct foo") == 2
 
     def test_bitfield(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("struct foo { int a:10, b:20, c:3; };")
         assert ffi.sizeof("struct foo") == 8
         s = ffi.new("struct foo *")
@@ -1021,7 +1023,7 @@
         assert s.c == -4
 
     def test_bitfield_enum(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("""
             typedef enum { AA, BB, CC } foo_e;
             typedef struct { foo_e f:2; } foo_s;
@@ -1031,7 +1033,7 @@
         assert s.f == 2
 
     def test_anonymous_struct(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("typedef struct { int a; } foo_t;")
         ffi.cdef("typedef struct { char b, c; } bar_t;")
         f = ffi.new("foo_t *", [12345])
@@ -1043,13 +1045,13 @@
 
     def test_struct_with_two_usages(self):
         for name in ['foo_s', '']:    # anonymous or not
-            ffi = FFI(backend=self.Backend())
+            ffi = FFI()
             ffi.cdef("typedef struct %s { int a; } foo_t, *foo_p;" % name)
             f = ffi.new("foo_t *", [12345])
             ps = ffi.new("foo_p[]", [f])
 
     def test_pointer_arithmetic(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         s = ffi.new("short[]", list(range(100, 110)))
         p = ffi.cast("short *", s)
         assert p[2] == 102
@@ -1063,7 +1065,7 @@
         assert p+1 == s+1
 
     def test_pointer_comparison(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         s = ffi.new("short[]", list(range(100)))
         p = ffi.cast("short *", s)
         assert (p <  s) is False
@@ -1114,7 +1116,7 @@
         assert (q != None) is True
 
     def test_no_integer_comparison(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         x = ffi.cast("int", 123)
         y = ffi.cast("int", 456)
         py.test.raises(TypeError, "x < y")
@@ -1124,7 +1126,7 @@
         py.test.raises(TypeError, "z < y")
 
     def test_ffi_buffer_ptr(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         a = ffi.new("short *", 100)
         try:
             b = ffi.buffer(a)
@@ -1143,7 +1145,7 @@
         assert a[0] == 101
 
     def test_ffi_buffer_array(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         a = ffi.new("int[]", list(range(100, 110)))
         try:
             b = ffi.buffer(a)
@@ -1160,7 +1162,7 @@
         assert a[1] == 0x45
 
     def test_ffi_buffer_ptr_size(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         a = ffi.new("short *", 0x4243)
         try:
             b = ffi.buffer(a, 1)
@@ -1178,7 +1180,7 @@
             assert a[0] == 0x6343
 
     def test_ffi_buffer_array_size(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         a1 = ffi.new("int[]", list(range(100, 110)))
         a2 = ffi.new("int[]", list(range(100, 115)))
         try:
@@ -1188,7 +1190,7 @@
         assert ffi.buffer(a1)[:] == ffi.buffer(a2, 4*10)[:]
 
     def test_ffi_buffer_with_file(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         import tempfile, os, array
         fd, filename = tempfile.mkstemp()
         f = os.fdopen(fd, 'r+b')
@@ -1208,7 +1210,7 @@
         os.unlink(filename)
 
     def test_ffi_buffer_with_io(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         import io, array
         f = io.BytesIO()
         a = ffi.new("int[]", list(range(1005)))
@@ -1226,7 +1228,7 @@
         f.close()
 
     def test_array_in_struct(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("struct foo_s { int len; short data[5]; };")
         p = ffi.new("struct foo_s *")
         p.data[3] = 5
@@ -1234,7 +1236,7 @@
         assert repr(p.data).startswith("<cdata 'short[5]' 0x")
 
     def test_struct_containing_array_varsize_workaround(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("struct foo_s { int len; short data[0]; };")
         p = ffi.new("char[]", ffi.sizeof("struct foo_s") + 7 * SIZE_OF_SHORT)
         q = ffi.cast("struct foo_s *", p)
@@ -1247,7 +1249,7 @@
 
     def test_new_struct_containing_array_varsize(self):
         py.test.skip("later?")
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("struct foo_s { int len; short data[]; };")
         p = ffi.new("struct foo_s *", 10)     # a single integer is the length
         assert p.len == 0
@@ -1255,7 +1257,7 @@
         py.test.raises(IndexError, "p.data[10]")
 
     def test_ffi_typeof_getcname(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         assert ffi.getctype("int") == "int"
         assert ffi.getctype("int", 'x') == "int x"
         assert ffi.getctype("int*") == "int *"
@@ -1273,7 +1275,7 @@
         assert ffi.getctype("int[5]", ' ** foo ') == "int(** foo)[5]"
 
     def test_array_of_func_ptr(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         f = ffi.cast("int(*)(int)", 42)
         assert f != ffi.NULL
         py.test.raises(CDefError, ffi.cast, "int(int)", 42)
@@ -1294,7 +1296,7 @@
     def test_callback_as_function_argument(self):
         # In C, function arguments can be declared with a function type,
         # which is automatically replaced with the ptr-to-function type.
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         def cb(a, b):
             return chr(ord(a) + ord(b)).encode()
         f = ffi.callback("char cb(char, char)", cb)
@@ -1306,7 +1308,7 @@
 
     def test_vararg_callback(self):
         py.test.skip("callback with '...'")
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         def cb(i, va_list):
             j = ffi.va_arg(va_list, "int")
             k = ffi.va_arg(va_list, "long long")
@@ -1316,7 +1318,7 @@
         assert res == 20 + 300 + 5000
 
     def test_callback_decorator(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         #
         @ffi.callback("long(long, long)", error=42)
         def cb(a, b):
@@ -1327,8 +1329,8 @@
         assert cb((1 << (sz*8-1)) - 1, -10) == 42
 
     def test_unique_types(self):
-        ffi1 = FFI(backend=self.Backend())
-        ffi2 = FFI(backend=self.Backend())
+        ffi1 = FFI()
+        ffi2 = FFI()
         assert ffi1.typeof("char") is ffi2.typeof("char ")
         assert ffi1.typeof("long") is ffi2.typeof("signed long int")
         assert ffi1.typeof("double *") is ffi2.typeof("double*")
@@ -1347,7 +1349,7 @@
         assert ffi1.typeof("struct foo*") is ffi1.typeof("struct foo *")
 
     def test_anonymous_enum(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("typedef enum { Value0 = 0 } e, *pe;\n"
                  "typedef enum { Value1 = 1 } e1;")
         assert ffi.getctype("e*") == 'e *'
@@ -1355,7 +1357,7 @@
         assert ffi.getctype("e1*") == 'e1 *'
 
     def test_opaque_enum(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         ffi.cdef("enum foo;")
         from cffi import __version_info__
         if __version_info__ < (1, 8):
@@ -1366,20 +1368,20 @@
             "which integer type it is meant to be (unsigned/signed, int/long)")
 
     def test_new_ctype(self):
-        ffi = FFI(backend=self.Backend())
+        ffi = FFI()
         p = ffi.new("int *")
         py.test.raises(TypeError, ffi.new, p)
         p = ffi.new(ffi.typeof("int *"), 42)
         assert p[0] == 42
 


More information about the pypy-commit mailing list