[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