[pypy-commit] cffi default: Change ffi.new() to take a pointer-to-X instead of directly X,

arigo noreply at buildbot.pypy.org
Tue Jul 17 00:27:22 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r660:6ffd20a29037
Date: 2012-07-16 14:00 +0200
http://bitbucket.org/cffi/cffi/changeset/6ffd20a29037/

Log:	Change ffi.new() to take a pointer-to-X instead of directly X, in
	order to match directly the returned type.

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -2036,7 +2036,9 @@
         }
     }
     else {
-        PyErr_SetString(PyExc_TypeError, "expected a pointer or array ctype");
+        PyErr_Format(PyExc_TypeError,
+                     "expected a pointer or array ctype, got '%s'",
+                     ct->ct_name);
         return NULL;
     }
 
diff --git a/cffi/api.py b/cffi/api.py
--- a/cffi/api.py
+++ b/cffi/api.py
@@ -141,30 +141,29 @@
         return self._backend.offsetof(cdecl, fieldname)
 
     def new(self, cdecl, init=None):
-        """Allocate an instance 'x' of the named C type, and return a
-        <cdata 'cdecl *'> object representing '&x'.  Such an object
-        behaves like a pointer to the allocated memory.  When the
-        <cdata> object goes out of scope, the memory is freed.
+        """Allocate an instance according to the specified C type and
+        return a pointer to it.  The specified C type must be either a
+        pointer or an array: ``new('X *')`` allocates an X and returns
+        a pointer to it, whereas ``new('X[n]')`` allocates an array of
+        n X'es and returns an array referencing it (which works
+        mostly like a pointer, like in C).  You can also use
+        ``new('X[]', n)`` to allocate an array of a non-constant
+        length n.
 
         The memory is initialized following the rules of declaring a
         global variable in C: by default it is zero-initialized, but
         an explicit initializer can be given which can be used to
         fill all or part of the memory.
 
-        The returned <cdata> object has ownership of the value of
-        type 'cdecl' that it points to.  This means that the raw data
-        can be used as long as this object is kept alive, but must
-        not be used for a longer time.  Be careful about that when
-        copying the pointer to the memory somewhere else, e.g. into
-        another structure.
+        When the returned <cdata> object goes out of scope, the memory
+        is freed.  In other words the returned <cdata> object has
+        ownership of the value of type 'cdecl' that it points to.  This
+        means that the raw data can be used as long as this object is
+        kept alive, but must not be used for a longer time.  Be careful
+        about that when copying the pointer to the memory somewhere
+        else, e.g. into another structure.
         """
-        try:
-            BType = self._new_types[cdecl]
-        except KeyError:
-            type = self._parser.parse_type(cdecl, force_pointer=True)
-            BType = self._get_cached_btype(type)
-            self._new_types[cdecl] = BType
-        #
+        BType = self.typeof(cdecl)
         return self._backend.newp(BType, init)
 
     def cast(self, cdecl, source):
diff --git a/cffi/backend_ctypes.py b/cffi/backend_ctypes.py
--- a/cffi/backend_ctypes.py
+++ b/cffi/backend_ctypes.py
@@ -7,6 +7,11 @@
     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
@@ -131,6 +136,10 @@
 class CTypesGenericArray(CTypesData):
     __slots__ = []
 
+    @classmethod
+    def _newp(cls, init):
+        return cls(init)
+
     def __iter__(self):
         for i in xrange(len(self)):
             yield self[i]
@@ -144,6 +153,10 @@
     _automatic_casts = False
 
     @classmethod
+    def _newp(cls, init):
+        return cls(init)
+
+    @classmethod
     def _cast_from(cls, source):
         if source is None:
             address = 0
@@ -890,7 +903,7 @@
         return BType._offsetof(fieldname)
 
     def newp(self, BType, source):
-        return BType(source)
+        return BType._newp(source)
 
     def cast(self, BType, source):
         return BType._cast_from(source)
diff --git a/cffi/cparser.py b/cffi/cparser.py
--- a/cffi/cparser.py
+++ b/cffi/cparser.py
@@ -133,12 +133,11 @@
                 else:
                     self._declare('variable ' + decl.name, tp)
 
-    def parse_type(self, cdecl, force_pointer=False,
-                   consider_function_as_funcptr=False):
+    def parse_type(self, cdecl, consider_function_as_funcptr=False):
         ast, macros = self._parse('void __dummy(%s);' % cdecl)
         assert not macros
         typenode = ast.ext[-1].type.args.params[0].type
-        return self._get_type(typenode, force_pointer=force_pointer,
+        return self._get_type(typenode,
                      consider_function_as_funcptr=consider_function_as_funcptr)
 
     def _declare(self, name, obj):
@@ -160,7 +159,7 @@
         return model.PointerType(type)
 
     def _get_type(self, typenode, convert_array_to_pointer=False,
-                  force_pointer=False, name=None, partial_length_ok=False,
+                  name=None, partial_length_ok=False,
                   consider_function_as_funcptr=False):
         # first, dereference typedefs, if we have it already parsed, we're good
         if (isinstance(typenode, pycparser.c_ast.TypeDecl) and
@@ -172,8 +171,6 @@
                 if convert_array_to_pointer:
                     return type.item
             else:
-                if force_pointer:
-                    return self._get_type_pointer(type)
                 if (consider_function_as_funcptr and
                         isinstance(type, model.RawFunctionType)):
                     return type.as_function_pointer()
@@ -190,9 +187,6 @@
                     typenode.dim, partial_length_ok=partial_length_ok)
             return model.ArrayType(self._get_type(typenode.type), length)
         #
-        if force_pointer:
-            return self._get_type_pointer(self._get_type(typenode))
-        #
         if isinstance(typenode, pycparser.c_ast.PtrDecl):
             # pointer type
             const = (isinstance(typenode.type, pycparser.c_ast.TypeDecl)
diff --git a/doc/source/index.rst b/doc/source/index.rst
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -64,7 +64,7 @@
 
 * pycparser 2.06 or 2.07: http://code.google.com/p/pycparser/
 
-* libffi (you need ``libffi-dev``); on Windows, it is included already.
+* libffi (you need ``libffi-dev``); the Windows version is included with CFFI.
 
 Download and Installation:
 
@@ -279,13 +279,14 @@
 Cleaning up the __pycache__ directory
 -------------------------------------
 
-During development, every time you call ``verify()`` with different
-strings of C source code (either the ``cdef()`` strings or the string
-passed to ```verify()`` itself), then it will create a new module file
-name, based on the MD5 hash of these strings.  This creates more files
-in the ``__pycache__`` directory.  It is recommended that you clean it
-up from time to time.  A nice way to do that is to add, in your test
-suite, a call to ``cffi.verifier.cleanup_tmpdir()``.
+During development, every time you change the C sources that you pass to
+``cdef()`` or ``verify()``, then the latter will create a new module
+file name, based on the MD5 hash of these strings.  This creates more
+and more files in the ``__pycache__`` directory.  It is recommended that
+you clean it up from time to time.  A nice way to do that is to add, in
+your test suite, a call to ``cffi.verifier.cleanup_tmpdir()``.
+Alternatively, you can just completely remove the ``__pycache__``
+directory.
 
 
 
@@ -477,20 +478,30 @@
 ``cdata``, which are printed for example as
 ``<cdata 'struct foo_s *' 0xa3290d8>``.
 
-``ffi.new(ctype, [initializer])``: this function builds a new cdata
-object of the given ``ctype``.  The ctype is usually some constant
-string describing the C type.  This is similar to a malloc: it allocates
-the memory needed to store an object of the given C type, and returns a
-pointer to it.  The memory is initially filled with zeros.  An
-initializer can be given too, as described later.
+``ffi.new(ctype, [initializer])``: this function builds and returns a
+new cdata object of the given ``ctype``.  The ctype is usually some
+constant string describing the C type.  It must be a pointer or array
+type.  If it is a pointer, e.g. ``"int *"`` or ``struct foo *``, then
+it allocates the memory for one ``int`` or ``struct foo``.  If it is
+an array, e.g. ``int[10]``, then it allocates the memory for ten
+``int``.  In both cases the returned cdata is of type ``ctype``.
+
+The memory is initially filled with zeros.  An initializer can be given
+too, as described later.
 
 Example::
 
-    >>> ffi.new("int")
+    >>> ffi.new("char *")
+    <cdata 'char *' owning 1 bytes>
+    >>> ffi.new("int *")
     <cdata 'int *' owning 4 bytes>
     >>> ffi.new("int[10]")
     <cdata 'int[10]' owning 40 bytes>
 
+.. versionchanged:: 0.2
+   Note that this changed from CFFI version 0.1: what used to be
+   ``ffi.new("int")`` is now ``ffi.new("int *")``.
+
 Unlike C, the returned pointer object has *ownership* on the allocated
 memory: when this exact object is garbage-collected, then the memory is
 freed.  If, at the level of C, you store a pointer to the memory
@@ -535,7 +546,7 @@
     ffi.cdef("void somefunction(int *);")
     lib = ffi.verify("#include <foo.h>")
 
-    x = ffi.new("int")        # allocate one int, and return a pointer to it
+    x = ffi.new("int *")      # allocate one int, and return a pointer to it
     x[0] = 42                 # fill it
     lib.somefunction(x)       # call the C function
     print x[0]                # read the possibly-changed value
@@ -558,10 +569,10 @@
     typedef struct { int x, y; } foo_t;
 
     foo_t v = { 1, 2 };            // C syntax
-    v = ffi.new("foo_t", [1, 2])   # CFFI equivalent
+    v = ffi.new("foo_t *", [1, 2]) # CFFI equivalent
 
-    foo_t v = { .y=1, .x=2 };               // C99 syntax
-    v = ffi.new("foo_t", {'y': 1, 'x': 2})  # CFFI equivalent
+    foo_t v = { .y=1, .x=2 };                // C99 syntax
+    v = ffi.new("foo_t *", {'y': 1, 'x': 2}) # CFFI equivalent
 
 Like C, arrays of chars can also be initialized from a string, in
 which case a terminating null character is appended implicitly::
@@ -907,8 +918,8 @@
   ``__pycache__``.
   
 - ``cleanup_tmpdir()``: cleans up the temporary directory by removing all
-  files in it called ``_cffi_*.{c,so}`` as well as the ``build``
-  subdirectory.
+  files in it called ``_cffi_*.{c,so}`` as well as all files in the
+  ``build`` subdirectory.
 
 
 
diff --git a/testing/backend_tests.py b/testing/backend_tests.py
--- a/testing/backend_tests.py
+++ b/testing/backend_tests.py
@@ -66,22 +66,28 @@
         assert q != p
         assert int(q) == int(p)
         assert hash(q) != hash(p)   # unlikely
-        py.test.raises(OverflowError, ffi.new, c_decl, min - 1)
-        py.test.raises(OverflowError, ffi.new, c_decl, max + 1)
-        py.test.raises(OverflowError, ffi.new, c_decl, long(min - 1))
-        py.test.raises(OverflowError, ffi.new, c_decl, long(max + 1))
-        assert ffi.new(c_decl, min)[0] == min
-        assert ffi.new(c_decl, max)[0] == max
-        assert ffi.new(c_decl, long(min))[0] == min
-        assert ffi.new(c_decl, long(max))[0] == max
+        c_decl_ptr = '%s *' % c_decl
+        py.test.raises(OverflowError, ffi.new, c_decl_ptr, min - 1)
+        py.test.raises(OverflowError, ffi.new, c_decl_ptr, max + 1)
+        py.test.raises(OverflowError, ffi.new, c_decl_ptr, long(min - 1))
+        py.test.raises(OverflowError, ffi.new, c_decl_ptr, long(max + 1))
+        assert ffi.new(c_decl_ptr, min)[0] == min
+        assert ffi.new(c_decl_ptr, max)[0] == max
+        assert ffi.new(c_decl_ptr, long(min))[0] == min
+        assert ffi.new(c_decl_ptr, long(max))[0] == max
+
+    def test_new_unsupported_type(self):
+        ffi = FFI(backend=self.Backend())
+        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())
-        p = ffi.new("int")     # similar to ffi.new("int[1]")
+        p = ffi.new("int *")     # similar to ffi.new("int[1]")
         assert p[0] == 0
         p[0] = -123
         assert p[0] == -123
-        p = ffi.new("int", -42)
+        p = ffi.new("int *", -42)
         assert p[0] == -42
         assert repr(p) == "<cdata 'int *' owning %d bytes>" % SIZE_OF_INT
 
@@ -144,7 +150,7 @@
 
     def test_pointer_init(self):
         ffi = FFI(backend=self.Backend())
-        n = ffi.new("int", 24)
+        n = ffi.new("int *", 24)
         a = ffi.new("int *[10]", [ffi.NULL, ffi.NULL, n, n, ffi.NULL])
         for i in range(10):
             if i not in (2, 3):
@@ -154,14 +160,14 @@
     def test_cannot_cast(self):
         ffi = FFI(backend=self.Backend())
         a = ffi.new("short int[10]")
-        e = py.test.raises(TypeError, ffi.new, "long int *", a)
+        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())
         a = ffi.new("int[4]", [100, 102, 104, 106])
-        p = ffi.new("int *", a)
+        p = ffi.new("int **", a)
         assert p[0] == ffi.cast("int *", a)
         assert p[0][2] == 104
         p = ffi.cast("int *", a)
@@ -198,10 +204,10 @@
         assert repr(p) == "<cdata 'int *' NULL>"
         assert repr(ffi.typeof(p)) == typerepr % "int *"
         #
-        p = ffi.new("int")
+        p = ffi.new("int*")
         assert repr(p) == "<cdata 'int *' owning %d bytes>" % SIZE_OF_INT
         assert repr(ffi.typeof(p)) == typerepr % "int *"
-        p = ffi.new("int*")
+        p = ffi.new("int**")
         assert repr(p) == "<cdata 'int * *' owning %d bytes>" % SIZE_OF_PTR
         assert repr(ffi.typeof(p)) == typerepr % "int * *"
         p = ffi.new("int [2]")
@@ -211,7 +217,7 @@
         assert repr(p) == "<cdata 'int *[2][3]' owning %d bytes>" % (
             6*SIZE_OF_PTR)
         assert repr(ffi.typeof(p)) == typerepr % "int *[2][3]"
-        p = ffi.new("struct foo")
+        p = ffi.new("struct foo *")
         assert repr(p) == "<cdata 'struct foo *' owning %d bytes>" % (
             3*SIZE_OF_SHORT)
         assert repr(ffi.typeof(p)) == typerepr % "struct foo *"
@@ -219,7 +225,7 @@
         q = ffi.cast("short", -123)
         assert repr(q) == "<cdata 'short' -123>"
         assert repr(ffi.typeof(q)) == typerepr % "short"
-        p = ffi.new("int")
+        p = ffi.new("int*")
         q = ffi.cast("short*", p)
         assert repr(q).startswith("<cdata 'short *' 0x")
         assert repr(ffi.typeof(q)) == typerepr % "short *"
@@ -227,7 +233,7 @@
         q = ffi.cast("int*", p)
         assert repr(q).startswith("<cdata 'int *' 0x")
         assert repr(ffi.typeof(q)) == typerepr % "int *"
-        p = ffi.new("struct foo")
+        p = ffi.new("struct foo*")
         q = ffi.cast("struct foo *", p)
         assert repr(q).startswith("<cdata 'struct foo *' 0x")
         assert repr(ffi.typeof(q)) == typerepr % "struct foo *"
@@ -252,7 +258,7 @@
 
     def test_new_array_of_pointer_1(self):
         ffi = FFI(backend=self.Backend())
-        n = ffi.new("int", 99)
+        n = ffi.new("int*", 99)
         p = ffi.new("int*[4]")
         p[3] = n
         a = p[3]
@@ -270,13 +276,13 @@
 
     def test_char(self):
         ffi = FFI(backend=self.Backend())
-        assert ffi.new("char", "\xff")[0] == '\xff'
-        assert ffi.new("char")[0] == '\x00'
+        assert ffi.new("char*", "\xff")[0] == '\xff'
+        assert ffi.new("char*")[0] == '\x00'
         assert int(ffi.cast("char", 300)) == 300 - 256
         assert bool(ffi.cast("char", 0))
-        py.test.raises(TypeError, ffi.new, "char", 32)
-        py.test.raises(TypeError, ffi.new, "char", u"x")
-        py.test.raises(TypeError, ffi.new, "char", "foo")
+        py.test.raises(TypeError, ffi.new, "char*", 32)
+        py.test.raises(TypeError, ffi.new, "char*", u"x")
+        py.test.raises(TypeError, ffi.new, "char*", "foo")
         #
         p = ffi.new("char[]", ['a', 'b', '\x9c'])
         assert len(p) == 3
@@ -306,17 +312,17 @@
     def test_wchar_t(self):
         ffi = FFI(backend=self.Backend())
         self.check_wchar_t(ffi)
-        assert ffi.new("wchar_t", u'x')[0] == u'x'
-        assert ffi.new("wchar_t", unichr(1234))[0] == unichr(1234)
+        assert ffi.new("wchar_t*", u'x')[0] == u'x'
+        assert ffi.new("wchar_t*", unichr(1234))[0] == unichr(1234)
         if SIZE_OF_WCHAR > 2:
-            assert ffi.new("wchar_t", u'\U00012345')[0] == u'\U00012345'
+            assert ffi.new("wchar_t*", u'\U00012345')[0] == u'\U00012345'
         else:
-            py.test.raises(TypeError, ffi.new, "wchar_t", u'\U00012345')
-        assert ffi.new("wchar_t")[0] == u'\x00'
+            py.test.raises(TypeError, ffi.new, "wchar_t*", u'\U00012345')
+        assert ffi.new("wchar_t*")[0] == u'\x00'
         assert int(ffi.cast("wchar_t", 300)) == 300
         assert bool(ffi.cast("wchar_t", 0))
-        py.test.raises(TypeError, ffi.new, "wchar_t", 32)
-        py.test.raises(TypeError, ffi.new, "wchar_t", "foo")
+        py.test.raises(TypeError, ffi.new, "wchar_t*", 32)
+        py.test.raises(TypeError, ffi.new, "wchar_t*", "foo")
         #
         p = ffi.new("wchar_t[]", [u'a', u'b', unichr(1234)])
         assert len(p) == 3
@@ -362,7 +368,7 @@
         assert p[0] == ffi.NULL
         assert repr(p[0]) == "<cdata 'int *' NULL>"
         #
-        n = ffi.new("int", 99)
+        n = ffi.new("int*", 99)
         p = ffi.new("int*[]", [n])
         assert p[0][0] == 99
         py.test.raises(TypeError, "p[0] = None")
@@ -377,14 +383,14 @@
         p[1] += 17.75
         assert p[1] == 15.25
         #
-        p = ffi.new("float", 15.75)
+        p = ffi.new("float*", 15.75)
         assert p[0] == 15.75
         py.test.raises(TypeError, int, p)
         py.test.raises(TypeError, float, p)
         p[0] = 0.0
         assert bool(p) is True
         #
-        p = ffi.new("float", 1.1)
+        p = ffi.new("float*", 1.1)
         f = p[0]
         assert f != 1.1      # because of rounding effect
         assert abs(f - 1.1) < 1E-7
@@ -397,13 +403,13 @@
     def test_struct_simple(self):
         ffi = FFI(backend=self.Backend())
         ffi.cdef("struct foo { int a; short b, c; };")
-        s = ffi.new("struct foo")
+        s = ffi.new("struct foo*")
         assert s.a == s.b == s.c == 0
         s.b = -23
         assert s.b == -23
         py.test.raises(OverflowError, "s.b = 32768")
         #
-        s = ffi.new("struct foo", [-2, -3])
+        s = ffi.new("struct foo*", [-2, -3])
         assert s.a == -2
         assert s.b == -3
         assert s.c == 0
@@ -411,21 +417,21 @@
         assert repr(s) == "<cdata 'struct foo *' owning %d bytes>" % (
             SIZE_OF_INT + 2 * SIZE_OF_SHORT)
         #
-        py.test.raises(ValueError, ffi.new, "struct foo", [1, 2, 3, 4])
+        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.cdef("struct foo { int a; short b, c; };")
-        s = ffi.new("struct foo", {'b': 123, 'c': 456})
+        s = ffi.new("struct foo*", {'b': 123, 'c': 456})
         assert s.a == 0
         assert s.b == 123
         assert s.c == 456
-        py.test.raises(KeyError, ffi.new, "struct foo", {'d': 456})
+        py.test.raises(KeyError, ffi.new, "struct foo*", {'d': 456})
 
     def test_struct_pointer(self):
         ffi = FFI(backend=self.Backend())
         ffi.cdef("struct foo { int a; short b, c; };")
-        s = ffi.new("struct foo")
+        s = ffi.new("struct foo*")
         assert s[0].a == s[0].b == s[0].c == 0
         s[0].b = -23
         assert s[0].b == s.b == -23
@@ -434,17 +440,17 @@
 
     def test_struct_opaque(self):
         ffi = FFI(backend=self.Backend())
-        py.test.raises(TypeError, ffi.new, "struct baz")
-        p = ffi.new("struct baz *")    # this works
+        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.cdef("struct foo { int a; short b, c; };")
-        s = ffi.new("struct foo")
+        s = ffi.new("struct foo *")
         s.a = -42
         assert s[0].a == -42
-        p = ffi.new("struct foo *", s)
+        p = ffi.new("struct foo **", s)
         assert p[0].a == -42
         assert p[0][0].a == -42
         p[0].a = -43
@@ -463,7 +469,7 @@
     def test_constructor_struct_of_array(self):
         ffi = FFI(backend=self.Backend())
         ffi.cdef("struct foo { int a[2]; char b[3]; };")
-        s = ffi.new("struct foo", [[10, 11], ['a', 'b', 'c']])
+        s = ffi.new("struct foo *", [[10, 11], ['a', 'b', 'c']])
         assert s.a[1] == 11
         assert s.b[2] == 'c'
         s.b[1] = 'X'
@@ -474,8 +480,8 @@
     def test_recursive_struct(self):
         ffi = FFI(backend=self.Backend())
         ffi.cdef("struct foo { int value; struct foo *next; };")
-        s = ffi.new("struct foo")
-        t = ffi.new("struct foo")
+        s = ffi.new("struct foo*")
+        t = ffi.new("struct foo*")
         s.value = 123
         s.next = t
         t.value = 456
@@ -485,36 +491,36 @@
     def test_union_simple(self):
         ffi = FFI(backend=self.Backend())
         ffi.cdef("union foo { int a; short b, c; };")
-        u = ffi.new("union foo")
+        u = ffi.new("union foo*")
         assert u.a == u.b == u.c == 0
         u.b = -23
         assert u.b == -23
         assert u.a != 0
         py.test.raises(OverflowError, "u.b = 32768")
         #
-        u = ffi.new("union foo", [-2])
+        u = ffi.new("union foo*", [-2])
         assert u.a == -2
         py.test.raises((AttributeError, TypeError), "del u.a")
         assert repr(u) == "<cdata 'union foo *' owning %d bytes>" % SIZE_OF_INT
 
     def test_union_opaque(self):
         ffi = FFI(backend=self.Backend())
-        py.test.raises(TypeError, ffi.new, "union baz")
-        u = ffi.new("union baz *")   # this works
+        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.cdef("union foo { char a; int b; };")
-        py.test.raises(TypeError, ffi.new, "union foo", 'A')
-        py.test.raises(TypeError, ffi.new, "union foo", 5)
-        py.test.raises(ValueError, ffi.new, "union foo", ['A', 5])
-        u = ffi.new("union foo", ['A'])
+        py.test.raises(TypeError, ffi.new, "union foo*", 'A')
+        py.test.raises(TypeError, ffi.new, "union foo*", 5)
+        py.test.raises(ValueError, ffi.new, "union foo*", ['A', 5])
+        u = ffi.new("union foo*", ['A'])
         assert u.a == 'A'
-        py.test.raises(TypeError, ffi.new, "union foo", [5])
-        u = ffi.new("union foo", {'b': 12345})
+        py.test.raises(TypeError, ffi.new, "union foo*", [5])
+        u = ffi.new("union foo*", {'b': 12345})
         assert u.b == 12345
-        u = ffi.new("union foo", [])
+        u = ffi.new("union foo*", [])
         assert u.a == '\x00'
         assert u.b == 0
 
@@ -537,7 +543,7 @@
 
     def test_sizeof_cdata(self):
         ffi = FFI(backend=self.Backend())
-        assert ffi.sizeof(ffi.new("short")) == SIZE_OF_PTR
+        assert ffi.sizeof(ffi.new("short*")) == SIZE_OF_PTR
         assert ffi.sizeof(ffi.cast("short", 123)) == SIZE_OF_SHORT
         #
         a = ffi.new("int[]", [10, 11, 12, 13, 14])
@@ -546,15 +552,15 @@
 
     def test_str_from_char_pointer(self):
         ffi = FFI(backend=self.Backend())
-        assert str(ffi.new("char", "x")) == "x"
-        assert str(ffi.new("char", "\x00")) == ""
+        assert str(ffi.new("char*", "x")) == "x"
+        assert str(ffi.new("char*", "\x00")) == ""
 
     def test_unicode_from_wchar_pointer(self):
         ffi = FFI(backend=self.Backend())
         self.check_wchar_t(ffi)
-        assert unicode(ffi.new("wchar_t", u"x")) == u"x"
-        assert unicode(ffi.new("wchar_t", u"\x00")) == u""
-        x = ffi.new("wchar_t", u"\x00")
+        assert unicode(ffi.new("wchar_t*", u"x")) == u"x"
+        assert unicode(ffi.new("wchar_t*", u"\x00")) == u""
+        x = ffi.new("wchar_t*", u"\x00")
         assert str(x) == repr(x)
 
     def test_string_from_char_array(self):
@@ -601,7 +607,7 @@
         ffi = FFI(backend=self.Backend())
         ffi.cdef("struct foo { const char *name; };")
         t = ffi.new("const char[]", "testing")
-        s = ffi.new("struct foo", [t])
+        s = ffi.new("struct foo*", [t])
         assert type(s.name) is not str
         assert str(s.name) == "testing"
         py.test.raises(TypeError, "s.name = None")
@@ -614,7 +620,7 @@
         self.check_wchar_t(ffi)
         ffi.cdef("struct foo { const wchar_t *name; };")
         t = ffi.new("const wchar_t[]", u"testing")
-        s = ffi.new("struct foo", [t])
+        s = ffi.new("struct foo*", [t])
         assert type(s.name) not in (str, unicode)
         assert unicode(s.name) == u"testing"
         s.name = ffi.NULL
@@ -622,17 +628,17 @@
 
     def test_voidp(self):
         ffi = FFI(backend=self.Backend())
-        py.test.raises(TypeError, ffi.new, "void")
-        p = ffi.new("void *")
+        py.test.raises(TypeError, ffi.new, "void*")
+        p = ffi.new("void **")
         assert p[0] == ffi.NULL
         a = ffi.new("int[]", [10, 11, 12])
-        p = ffi.new("void *", a)
+        p = ffi.new("void **", a)
         vp = p[0]
         py.test.raises(TypeError, "vp[0]")
-        py.test.raises(TypeError, ffi.new, "short *", a)
+        py.test.raises(TypeError, ffi.new, "short **", a)
         #
         ffi.cdef("struct foo { void *p; int *q; short *r; };")
-        s = ffi.new("struct foo")
+        s = ffi.new("struct foo *")
         s.p = a    # works
         s.q = a    # works
         py.test.raises(TypeError, "s.r = a")    # fails
@@ -655,7 +661,7 @@
         assert repr(p).startswith(
             "<cdata 'int(*)(int)' calling <function cb at 0x")
         assert ffi.typeof(p) is ffi.typeof("int(*)(int)")
-        q = ffi.new("int(*)(int)", p)
+        q = ffi.new("int(**)(int)", p)
         assert repr(q) == "<cdata 'int(* *)(int)' owning %d bytes>" % (
             SIZE_OF_PTR)
         py.test.raises(TypeError, "q(43)")
@@ -679,7 +685,7 @@
         res = p()
         assert res is not None
         assert res == ffi.NULL
-        int_ptr = ffi.new('int')
+        int_ptr = ffi.new('int*')
         void_ptr = ffi.cast('void*', int_ptr)
         def cb():
             return void_ptr
@@ -694,7 +700,7 @@
         p = ffi.callback("int*(*)()", cb)
         res = p()
         assert res == ffi.NULL
-        int_ptr = ffi.new('int')
+        int_ptr = ffi.new('int*')
         def cb():
             return int_ptr
         p = ffi.callback("int*(*)()", cb)
@@ -840,7 +846,7 @@
     def test_enum_in_struct(self):
         ffi = FFI(backend=self.Backend())
         ffi.cdef("enum foo { A, B, C, D }; struct bar { enum foo e; };")
-        s = ffi.new("struct bar")
+        s = ffi.new("struct bar *")
         s.e = 0
         assert s.e == "A"
         s.e = "D"
@@ -880,7 +886,7 @@
 
     def test_pointer_to_array(self):
         ffi = FFI(backend=self.Backend())
-        p = ffi.new("int(*)[5]")
+        p = ffi.new("int(**)[5]")
         assert repr(p) == "<cdata 'int(* *)[5]' owning %d bytes>" % SIZE_OF_PTR
 
     def test_iterate_array(self):
@@ -891,8 +897,8 @@
         #
         py.test.raises(TypeError, iter, ffi.cast("char *", a))
         py.test.raises(TypeError, list, ffi.cast("char *", a))
-        py.test.raises(TypeError, iter, ffi.new("int"))
-        py.test.raises(TypeError, list, ffi.new("int"))
+        py.test.raises(TypeError, iter, ffi.new("int *"))
+        py.test.raises(TypeError, list, ffi.new("int *"))
 
     def test_offsetof(self):
         ffi = FFI(backend=self.Backend())
@@ -912,7 +918,7 @@
         ffi = FFI(backend=self.Backend())
         ffi.cdef("struct foo { int a:10, b:20, c:3; };")
         assert ffi.sizeof("struct foo") == 8
-        s = ffi.new("struct foo")
+        s = ffi.new("struct foo *")
         s.a = 511
         py.test.raises(OverflowError, "s.a = 512")
         py.test.raises(OverflowError, "s[0].a = 512")
@@ -932,8 +938,8 @@
         ffi = FFI(backend=self.Backend())
         ffi.cdef("typedef struct { int a; } foo_t;")
         ffi.cdef("typedef struct { char b, c; } bar_t;")
-        f = ffi.new("foo_t", [12345])
-        b = ffi.new("bar_t", ["B", "C"])
+        f = ffi.new("foo_t *", [12345])
+        b = ffi.new("bar_t *", ["B", "C"])
         assert f.a == 12345
         assert b.b == "B"
         assert b.c == "C"
@@ -943,7 +949,7 @@
         for name in ['foo_s', '']:    # anonymous or not
             ffi = FFI(backend=self.Backend())
             ffi.cdef("typedef struct %s { int a; } foo_t, *foo_p;" % name)
-            f = ffi.new("foo_t", [12345])
+            f = ffi.new("foo_t *", [12345])
             ps = ffi.new("foo_p[]", [f])
 
     def test_pointer_arithmetic(self):
@@ -1023,7 +1029,7 @@
 
     def test_ffi_buffer_ptr(self):
         ffi = FFI(backend=self.Backend())
-        a = ffi.new("short", 100)
+        a = ffi.new("short *", 100)
         b = ffi.buffer(a)
         assert type(b) is buffer
         assert len(str(b)) == 2
@@ -1051,7 +1057,7 @@
 
     def test_ffi_buffer_ptr_size(self):
         ffi = FFI(backend=self.Backend())
-        a = ffi.new("short", 0x4243)
+        a = ffi.new("short *", 0x4243)
         b = ffi.buffer(a, 1)
         assert type(b) is buffer
         assert len(str(b)) == 1
@@ -1090,7 +1096,7 @@
         py.test.skip("later?")
         ffi = FFI(backend=self.Backend())
         ffi.cdef("struct foo_s { int len; short data[]; };")
-        p = ffi.new("struct foo_s", 10)     # a single integer is the length
+        p = ffi.new("struct foo_s *", 10)     # a single integer is the length
         assert p.len == 0
         assert p.data[9] == 0
         py.test.raises(IndexError, "p.data[10]")
diff --git a/testing/test_function.py b/testing/test_function.py
--- a/testing/test_function.py
+++ b/testing/test_function.py
@@ -265,7 +265,7 @@
             char *inet_ntoa(struct in_addr in);
         """)
         ffi.C = ffi.dlopen(None)
-        ina = ffi.new("struct in_addr", [0x04040404])
+        ina = ffi.new("struct in_addr *", [0x04040404])
         a = ffi.C.inet_ntoa(ina[0])
         assert str(a) == '4.4.4.4'
 
diff --git a/testing/test_parsing.py b/testing/test_parsing.py
--- a/testing/test_parsing.py
+++ b/testing/test_parsing.py
@@ -123,15 +123,6 @@
     assert C.foo.BType == ('<func (<pointer to <pointer to '
                            '<int>a, <int>b>>), <int>, False>')
 
-def test_typedef_array_force_pointer():
-    ffi = FFI(backend=FakeBackend())
-    ffi.cdef("""
-        typedef int array_t[5];
-        """)
-    type = ffi._parser.parse_type("array_t", force_pointer=True)
-    BType = ffi._get_cached_btype(type)
-    assert str(BType) == '<array <pointer to <int>> x 5>'
-
 def test_typedef_array_convert_array_to_pointer():
     ffi = FFI(backend=FakeBackend())
     ffi.cdef("""
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -144,8 +144,8 @@
     ffi.cdef("int *foo(int *);")
     lib = ffi.verify("int *foo(int *a) { return a; }")
     assert lib.foo(ffi.NULL) == ffi.NULL
-    p = ffi.new("int", 42)
-    q = ffi.new("int", 42)
+    p = ffi.new("int *", 42)
+    q = ffi.new("int *", 42)
     assert lib.foo(p) == p
     assert lib.foo(q) != p
 
@@ -153,7 +153,7 @@
     ffi = FFI()
     ffi.cdef("int *foo(int *);")
     lib = ffi.verify("int *foo(int *a) { return a; }")
-    py.test.raises(TypeError, lib.foo, ffi.new("short", 42))
+    py.test.raises(TypeError, lib.foo, ffi.new("short *", 42))
 
 
 def test_verify_typedefs():
@@ -207,7 +207,7 @@
     """)
     py.test.raises(VerificationMissing, ffi.sizeof, 'struct foo_s')
     py.test.raises(VerificationMissing, ffi.offsetof, 'struct foo_s', 'x')
-    py.test.raises(VerificationMissing, ffi.new, 'struct foo_s')
+    py.test.raises(VerificationMissing, ffi.new, 'struct foo_s *')
     ffi.verify("""
     struct foo_s {
        int a, b, x, c, d, e;
@@ -268,7 +268,7 @@
     ffi.cdef("struct foo_s { int a[17]; ...; };")
     ffi.verify("struct foo_s { int x; int a[17]; int y; };")
     assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int')
-    s = ffi.new("struct foo_s")
+    s = ffi.new("struct foo_s *")
     assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int')
 
 def test_struct_array_guess_length():
@@ -276,7 +276,7 @@
     ffi.cdef("struct foo_s { int a[]; ...; };")    # <= no declared length
     ffi.verify("struct foo_s { int x; int a[17]; int y; };")
     assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int')
-    s = ffi.new("struct foo_s")
+    s = ffi.new("struct foo_s *")
     assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int')
 
 def test_struct_array_guess_length_2():
@@ -286,7 +286,7 @@
     lib = ffi.verify("struct foo_s { int x; int a[17]; int y; };\n"
                      "int bar(struct foo_s *f) { return f->a[14]; }\n")
     assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int')
-    s = ffi.new("struct foo_s")
+    s = ffi.new("struct foo_s *")
     s.a[14] = 4242
     assert lib.bar(s) == 4242
 
@@ -295,7 +295,7 @@
     ffi.cdef("struct foo_s { int a[...]; };")
     ffi.verify("struct foo_s { int x; int a[17]; int y; };")
     assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int')
-    s = ffi.new("struct foo_s")
+    s = ffi.new("struct foo_s *")
     assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int')
 
 def test_global_constants():
@@ -487,7 +487,7 @@
         typedef struct { int y, x; } foo_t;
         static int foo(foo_t *f) { return f->x * 7; }
     """)
-    f = ffi.new("foo_t")
+    f = ffi.new("foo_t *")
     f.x = 6
     assert lib.foo(f) == 42
 
@@ -508,7 +508,7 @@
         }
         #define TOKEN_SIZE sizeof(token_t)
     """)
-    # we cannot let ffi.new("token_t") work, because we don't know ahead of
+    # we cannot let ffi.new("token_t *") work, because we don't know ahead of
     # time if it's ok to ask 'sizeof(token_t)' in the C code or not.
     # See test_unknown_type_2.  Workaround.
     tkmem = ffi.new("char[]", lib.TOKEN_SIZE)    # zero-initialized
@@ -565,7 +565,7 @@
             return s.a - s.b;
         }
     """)
-    s = ffi.new("struct foo_s", ['B', 1])
+    s = ffi.new("struct foo_s *", ['B', 1])
     assert lib.foo(50, s[0]) == ord('A')
 
 def test_autofilled_struct_as_argument():
@@ -581,7 +581,7 @@
             return s.a - (int)s.b;
         }
     """)
-    s = ffi.new("struct foo_s", [100, 1])
+    s = ffi.new("struct foo_s *", [100, 1])
     assert lib.foo(s[0]) == 99
 
 def test_autofilled_struct_as_argument_dynamic():


More information about the pypy-commit mailing list