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