[pypy-commit] pypy ffi-backend: Next test.

arigo noreply at buildbot.pypy.org
Thu Jun 21 13:16:20 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: ffi-backend
Changeset: r55747:f49f7a936634
Date: 2012-06-20 18:35 +0200
http://bitbucket.org/pypy/pypy/changeset/f49f7a936634/

Log:	Next test.

diff --git a/pypy/module/_ffi_backend/cdataobj.py b/pypy/module/_ffi_backend/cdataobj.py
--- a/pypy/module/_ffi_backend/cdataobj.py
+++ b/pypy/module/_ffi_backend/cdataobj.py
@@ -24,6 +24,9 @@
     def repr(self):
         return self.space.wrap("<cdata '%s'>" % self.ctype.name)
 
+    def nonzero(self):
+        return self.space.wrap(bool(self.cdata))
+
     def int(self):
         w_result = self.ctype.int(self.cdata)
         keepalive_until_here(self)
@@ -36,6 +39,11 @@
             w_result = space.newlong(space.int_w(w_result))
         return w_result
 
+    def float(self):
+        w_result = self.ctype.float(self.cdata)
+        keepalive_until_here(self)
+        return w_result
+
     def read_raw_signed_data(self):
         result = misc.read_raw_signed_data(self.cdata, self.ctype.size)
         keepalive_until_here(self)
@@ -50,6 +58,15 @@
         misc.write_raw_integer_data(self.cdata, source, self.ctype.size)
         keepalive_until_here(self)
 
+    def read_raw_float_data(self):
+        result = misc.read_raw_float_data(self.cdata, self.ctype.size)
+        keepalive_until_here(self)
+        return result
+
+    def write_raw_float_data(self, source):
+        misc.write_raw_float_data(self.cdata, source, self.ctype.size)
+        keepalive_until_here(self)
+
     def convert_to_object(self):
         w_obj = self.ctype.convert_to_object(self.cdata)
         keepalive_until_here(self)
@@ -70,8 +87,10 @@
 W_CData.typedef = TypeDef(
     '_ffi_backend.CData',
     __repr__ = interp2app(W_CData.repr),
+    __nonzero__ = interp2app(W_CData.nonzero),
     __int__ = interp2app(W_CData.int),
     __long__ = interp2app(W_CData.long),
+    __float__ = interp2app(W_CData.float),
     )
 W_CData.acceptable_as_base_class = False
 
diff --git a/pypy/module/_ffi_backend/ctypeobj.py b/pypy/module/_ffi_backend/ctypeobj.py
--- a/pypy/module/_ffi_backend/ctypeobj.py
+++ b/pypy/module/_ffi_backend/ctypeobj.py
@@ -28,6 +28,11 @@
         raise operationerrfmt(space.w_TypeError,
                               "int() not supported on cdata '%s'", self.name)
 
+    def float(self, cdata):
+        space = self.space
+        raise operationerrfmt(space.w_TypeError,
+                              "float() not supported on cdata '%s'", self.name)
+
     def convert_to_object(self, cdata):
         raise NotImplementedError
 
@@ -88,6 +93,34 @@
             return self.space.wrap(value)    # r_ulonglong => 'long' object
 
 
+class W_CTypePrimitiveFloat(W_CTypePrimitive):
+
+    def cast(self, w_ob):
+        space = self.space
+        if cdataobj.check_cdata(space, w_ob):
+            xxx
+        elif space.isinstance_w(w_ob, space.w_str):
+            xxx
+        elif space.is_w(w_ob, space.w_None):
+            value = 0.0
+        else:
+            value = space.float_w(w_ob)
+        w_cdata = cdataobj.W_CDataOwn(space, self.size, self)
+        w_cdata.write_raw_float_data(value)
+        return w_cdata
+
+    def int(self, cdata):
+        w_value = self.float(cdata)
+        return self.space.int(w_value)
+
+    def float(self, cdata):
+        return self.convert_to_object(cdata)
+
+    def convert_to_object(self, cdata):
+        value = misc.read_raw_float_data(cdata, self.size)
+        return self.space.wrap(value)
+
+
 W_CType.typedef = TypeDef(
     '_ffi_backend.CTypeDescr',
     __repr__ = interp2app(W_CType.repr),
diff --git a/pypy/module/_ffi_backend/misc.py b/pypy/module/_ffi_backend/misc.py
--- a/pypy/module/_ffi_backend/misc.py
+++ b/pypy/module/_ffi_backend/misc.py
@@ -1,3 +1,4 @@
+from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.rlib.rarithmetic import r_ulonglong
 from pypy.rlib.unroll import unrolling_iterable
@@ -18,18 +19,28 @@
     (rffi.ULONG, rffi.ULONGP),
     (rffi.ULONGLONG, rffi.ULONGLONGP)])
 
+_prim_float_types = unrolling_iterable([
+    (rffi.FLOAT, rffi.FLOATP),
+    (rffi.DOUBLE, rffi.DOUBLEP)])
+
 def read_raw_signed_data(target, size):
     for TP, TPP in _prim_signed_types:
         if size == rffi.sizeof(TP):
-            return rffi.cast(rffi.LONGLONG, rffi.cast(TPP, target)[0])
+            return rffi.cast(lltype.SignedLongLong, rffi.cast(TPP, target)[0])
     raise NotImplementedError("bad integer size")
 
 def read_raw_unsigned_data(target, size):
     for TP, TPP in _prim_unsigned_types:
         if size == rffi.sizeof(TP):
-            return rffi.cast(rffi.ULONGLONG, rffi.cast(TPP, target)[0])
+            return rffi.cast(lltype.UnsignedLongLong, rffi.cast(TPP,target)[0])
     raise NotImplementedError("bad integer size")
 
+def read_raw_float_data(target, size):
+    for TP, TPP in _prim_float_types:
+        if size == rffi.sizeof(TP):
+            return rffi.cast(lltype.Float, rffi.cast(TPP, target)[0])
+    raise NotImplementedError("bad float size")
+
 def write_raw_integer_data(target, source, size):
     for TP, TPP in _prim_unsigned_types:
         if size == rffi.sizeof(TP):
@@ -37,6 +48,13 @@
             return
     raise NotImplementedError("bad integer size")
 
+def write_raw_float_data(target, source, size):
+    for TP, TPP in _prim_float_types:
+        if size == rffi.sizeof(TP):
+            rffi.cast(TPP, target)[0] = rffi.cast(TP, source)
+            return
+    raise NotImplementedError("bad float size")
+
 # ____________________________________________________________
 
 
@@ -91,8 +109,8 @@
 def as_unsigned_long_long(space, w_ob, strict):
     # (possibly) convert and cast a Python object to an unsigned long long.
     # This accepts a Python int too, and does convertions from other types of
-    # objects.  If 'overflow', complains with OverflowError; if 'not overflow',
-    # mask the result.
+    # objects.  If 'strict', complains with OverflowError; if 'not strict',
+    # mask the result and round floats.
     if space.is_w(space.type(w_ob), space.w_int):   # shortcut
         value = space.int_w(w_ob)
         if strict and value < 0:
diff --git a/pypy/module/_ffi_backend/newtype.py b/pypy/module/_ffi_backend/newtype.py
--- a/pypy/module/_ffi_backend/newtype.py
+++ b/pypy/module/_ffi_backend/newtype.py
@@ -31,7 +31,8 @@
 eptype("unsigned int",       rffi.INT,      ctypeobj.W_CTypePrimitiveUnsigned)
 eptype("unsigned long",      rffi.LONG,     ctypeobj.W_CTypePrimitiveUnsigned)
 eptype("unsigned long long", rffi.LONGLONG, ctypeobj.W_CTypePrimitiveUnsigned)
-
+eptype("float",  rffi.FLOAT,  ctypeobj.W_CTypePrimitiveFloat)
+eptype("double", rffi.DOUBLE, ctypeobj.W_CTypePrimitiveFloat)
 
 @unwrap_spec(name=str)
 def new_primitive_type(space, name):
diff --git a/pypy/module/_ffi_backend/test/test_c.py b/pypy/module/_ffi_backend/test/test_c.py
--- a/pypy/module/_ffi_backend/test/test_c.py
+++ b/pypy/module/_ffi_backend/test/test_c.py
@@ -92,10 +92,12 @@
             assert long(cast(p, -1)) == max
 
     def test_no_float_on_int_types(self):
-        p = new_primitive_type('long')
-        py.test.raises(TypeError, float, cast(p, 42))
+        p = self.b.new_primitive_type('long')
+        raises(TypeError, float, self.b.cast(p, 42))
 
     def test_float_types(self):
+        new_primitive_type = self.b.new_primitive_type
+        cast = self.b.cast
         INF = 1E200 * 1E200
         for name in ["float", "double"]:
             p = new_primitive_type(name)
@@ -109,8 +111,8 @@
             assert type(int(cast(p, 1E22))) is long
             assert type(long(cast(p, 61.91))) is long
             assert type(long(cast(p, 1E22))) is long
-            py.test.raises(OverflowError, int, cast(p, INF))
-            py.test.raises(OverflowError, int, cast(p, -INF))
+            raises(OverflowError, int, cast(p, INF))
+            raises(OverflowError, int, cast(p, -INF))
             assert float(cast(p, 1.25)) == 1.25
             assert float(cast(p, INF)) == INF
             assert float(cast(p, -INF)) == -INF


More information about the pypy-commit mailing list