[pypy-commit] pypy ffi-backend: Test and fix

arigo noreply at buildbot.pypy.org
Sat Jul 7 13:55:47 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: ffi-backend
Changeset: r55964:3916eb5d340c
Date: 2012-07-07 13:55 +0200
http://bitbucket.org/pypy/pypy/changeset/3916eb5d340c/

Log:	Test and fix

diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py
--- a/pypy/module/_cffi_backend/cdataobj.py
+++ b/pypy/module/_cffi_backend/cdataobj.py
@@ -1,3 +1,4 @@
+import operator
 from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.gateway import interp2app, unwrap_spec
@@ -5,6 +6,7 @@
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.rlib.objectmodel import keepalive_until_here
 from pypy.rlib import objectmodel, rgc
+from pypy.tool.sourcetools import func_with_new_name
 
 from pypy.module._cffi_backend import misc
 
@@ -63,19 +65,35 @@
     def str(self):
         return self.ctype.str(self)
 
-    def _cmp(self, w_other, compare_for_ne):
-        space = self.space
-        cdata1 = self._cdata
-        other = space.interpclass_w(w_other)
-        if isinstance(other, W_CData):
-            cdata2 = other._cdata
-        else:
-            return space.w_NotImplemented
-        result = (cdata1 == cdata2) ^ compare_for_ne
-        return space.newbool(result)
+    def _make_comparison(name):
+        op = getattr(operator, name)
+        requires_ordering = name not in ('eq', 'ne')
+        #
+        def _cmp(self, w_other):
+            from pypy.module._cffi_backend.ctypeprim import W_CTypePrimitive
+            space = self.space
+            cdata1 = self._cdata
+            other = space.interpclass_w(w_other)
+            if isinstance(other, W_CData):
+                cdata2 = other._cdata
+            else:
+                return space.w_NotImplemented
 
-    def eq(self, w_other): return self._cmp(w_other, False)
-    def ne(self, w_other): return self._cmp(w_other, True)
+            if requires_ordering and (
+                    isinstance(self.ctype, W_CTypePrimitive) or
+                    isinstance(other.ctype, W_CTypePrimitive)):
+                raise OperationError(space.w_TypeError,
+                    space.wrap("cannot do comparison on a primitive cdata"))
+            return space.newbool(op(cdata1, cdata2))
+        #
+        return func_with_new_name(_cmp, name)
+
+    lt = _make_comparison('lt')
+    le = _make_comparison('le')
+    eq = _make_comparison('eq')
+    ne = _make_comparison('ne')
+    gt = _make_comparison('gt')
+    ge = _make_comparison('ge')
 
     def hash(self):
         h = (objectmodel.compute_identity_hash(self.ctype) ^
@@ -287,8 +305,12 @@
     __float__ = interp2app(W_CData.float),
     __len__ = interp2app(W_CData.len),
     __str__ = interp2app(W_CData.str),
+    __lt__ = interp2app(W_CData.lt),
+    __le__ = interp2app(W_CData.le),
     __eq__ = interp2app(W_CData.eq),
     __ne__ = interp2app(W_CData.ne),
+    __gt__ = interp2app(W_CData.gt),
+    __ge__ = interp2app(W_CData.ge),
     __hash__ = interp2app(W_CData.hash),
     __getitem__ = interp2app(W_CData.getitem),
     __setitem__ = interp2app(W_CData.setitem),
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -1320,3 +1320,29 @@
     #
     py.test.raises(TypeError, iter, cast(BInt, 5))
     py.test.raises(TypeError, iter, cast(BIntP, 123456))
+
+def test_cmp():
+    BInt = new_primitive_type("int")
+    BIntP = new_pointer_type(BInt)
+    BVoidP = new_pointer_type(new_void_type())
+    p = newp(BIntP, 123)
+    q = cast(BInt, 124)
+    py.test.raises(TypeError, "p < q")
+    py.test.raises(TypeError, "p <= q")
+    assert (p == q) is False
+    assert (p != q) is True
+    py.test.raises(TypeError, "p > q")
+    py.test.raises(TypeError, "p >= q")
+    r = cast(BVoidP, p)
+    assert (p <  r) is False
+    assert (p <= r) is True
+    assert (p == r) is True
+    assert (p != r) is False
+    assert (p >  r) is False
+    assert (p >= r) is True
+    s = newp(BIntP, 125)
+    assert (p == s) is False
+    assert (p != s) is True
+    assert (p < s) is (p <= s) is (s > p) is (s >= p)
+    assert (p > s) is (p >= s) is (s < p) is (s <= p)
+    assert (p < s) ^ (p > s)


More information about the pypy-commit mailing list