Author: Armin Rigo <ar...@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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit