Author: Armin Rigo <[email protected]>
Branch: cffi-1.0
Changeset: r76989:6ab11b72aa4a
Date: 2015-05-02 22:09 +0200
http://bitbucket.org/pypy/pypy/changeset/6ab11b72aa4a/

Log:    ffi.new()

diff --git a/pypy/module/_cffi_backend/ffi_obj.py 
b/pypy/module/_cffi_backend/ffi_obj.py
--- a/pypy/module/_cffi_backend/ffi_obj.py
+++ b/pypy/module/_cffi_backend/ffi_obj.py
@@ -1,6 +1,6 @@
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.typedef import TypeDef
-from pypy.interpreter.gateway import interp2app, unwrap_spec
+from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
 from rpython.rlib import jit, rgc
 
 from pypy.module._cffi_backend import parse_c_type, realize_c_type
@@ -49,15 +49,47 @@
             return self.parse_string_to_type(space.str_w(w_x))
         yyyy
 
-    def descr_new(self):
-        XXX
 
-    def descr_typeof(self, w_x):
-        return self.ffi_type(w_x, ACCEPT_STRING | ACCEPT_CDATA)
+    def descr_init(self):
+        pass       # if any argument is passed, gets a TypeError
 
+    @unwrap_spec(w_init=WrappedDefault(None))
+    def descr_new(self, w_arg, w_init):
+        """\
+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.
 
-#@unwrap_spec()
-def W_FFIObject___new__(space, w_subtype):
+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.
+
+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."""
+        #
+        w_ctype = self.ffi_type(w_arg, ACCEPT_STRING | ACCEPT_CTYPE)
+        return w_ctype.newp(w_init)
+
+
+    def descr_typeof(self, w_arg):
+        """\
+Parse the C type given as a string and return the
+corresponding <ctype> object.
+It can also be used on 'cdata' instance to get its C type."""
+        #
+        return self.ffi_type(w_arg, ACCEPT_STRING | ACCEPT_CDATA)
+
+
+def W_FFIObject___new__(space, w_subtype, __args__):
     r = space.allocate_instance(W_FFIObject, w_subtype)
     r.__init__(space)
     return space.wrap(r)
@@ -65,6 +97,7 @@
 W_FFIObject.typedef = TypeDef(
         'CompiledFFI',
         __new__ = interp2app(W_FFIObject___new__),
+        __init__ = interp2app(W_FFIObject.descr_init),
         new = interp2app(W_FFIObject.descr_new),
         typeof = interp2app(W_FFIObject.descr_typeof),
         )
diff --git a/pypy/module/_cffi_backend/test/test_ffi_obj.py 
b/pypy/module/_cffi_backend/test/test_ffi_obj.py
--- a/pypy/module/_cffi_backend/test/test_ffi_obj.py
+++ b/pypy/module/_cffi_backend/test/test_ffi_obj.py
@@ -25,7 +25,7 @@
 
     def test_ffi_no_argument(self):
         import _cffi_backend as _cffi1_backend
-        py.test.raises(TypeError, _cffi1_backend.FFI, 42)
+        raises(TypeError, _cffi1_backend.FFI, 42)
 
     def test_ffi_cache_type(self):
         import _cffi_backend as _cffi1_backend
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to