[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