[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