Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r62233:6f52561333cb Date: 2013-03-08 15:20 +0100 http://bitbucket.org/pypy/pypy/changeset/6f52561333cb/
Log: hg backout 1d661d485129 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 @@ -92,15 +92,20 @@ cdata1 = self._cdata other = space.interpclass_w(w_other) if isinstance(other, W_CData): + if requires_ordering: + if (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")) cdata2 = other._cdata + elif (misc.is_zero(space, w_other) and + not isinstance(self.ctype, W_CTypePrimitive)): + cdata2 = lltype.nullptr(rffi.CCHARP.TO) else: return space.w_NotImplemented if requires_ordering: - if (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")) cdata1 = rffi.cast(lltype.Unsigned, cdata1) cdata2 = rffi.cast(lltype.Unsigned, cdata2) return space.newbool(op(cdata1, cdata2)) diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -154,6 +154,10 @@ space = self.space ob = space.interpclass_w(w_ob) if not isinstance(ob, cdataobj.W_CData): + if misc.is_zero(space, w_ob): + NULL = lltype.nullptr(rffi.CCHARP.TO) + rffi.cast(rffi.CCHARPP, cdata)[0] = NULL + return raise self._convert_error("cdata pointer", w_ob) other = ob.ctype if not isinstance(other, W_CTypePtrBase): @@ -257,7 +261,15 @@ def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space - if (space.isinstance_w(w_init, space.w_list) or + if misc.is_zero(space, w_init): + # Convert 0 to NULL. Note that passing 0 is not ambigous, + # despite the potential confusion: as a 'T*' argument, 0 means + # NULL, but as a 'T[]' argument it would mean "array of size 0" + # --- except that we specifically refuse to interpret numbers + # as the array size when passing arguments. + rffi.cast(rffi.CCHARPP, cdata)[0] = lltype.nullptr(rffi.CCHARP.TO) + return 3 + elif (space.isinstance_w(w_init, space.w_list) or space.isinstance_w(w_init, space.w_tuple)): length = space.int_w(space.len(w_init)) elif space.isinstance_w(w_init, space.w_basestring): diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -203,6 +203,11 @@ neg_msg = "can't convert negative number to unsigned" ovf_msg = "long too big to convert" +def is_zero(space, w_ob): + return ((space.isinstance_w(w_ob, space.w_int) or + space.isinstance_w(w_ob, space.w_long)) + and not space.is_true(w_ob)) + # ____________________________________________________________ class _NotStandardObject(Exception): 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 @@ -387,8 +387,19 @@ assert (x != None) is True assert (x == ["hello"]) is False assert (x != ["hello"]) is True - y = cast(p, 0) - assert (y == None) is False + +def test_cmp_pointer_with_0(): + p = new_pointer_type(new_primitive_type("int")) + x = cast(p, 0) + assert (x == 0) is True + assert (x != 0) is False + assert (0 == x) is True + assert (0 != x) is False + y = cast(p, 42) + assert (y == 0) is False + assert (y != 0) is True + assert (0 == y) is False + assert (0 != y) is True def test_invalid_indexing(): p = new_primitive_type("int") @@ -768,7 +779,7 @@ assert s.a2 == 456 assert s.a3 == 0 assert s.p4 == cast(BVoidP, 0) - assert s.p4 != 0 + assert s.p4 == 0 # s = newp(BStructPtr, {'a2': 41122, 'a3': -123}) assert s.a1 == 0 @@ -781,11 +792,14 @@ p = newp(BIntPtr, 14141) s = newp(BStructPtr, [12, 34, 56, p]) assert s.p4 == p - assert s.p4 + s.p4 = 0 + assert s.p4 == 0 # s = newp(BStructPtr, [12, 34, 56, cast(BVoidP, 0)]) + assert s.p4 == 0 + # + s = newp(BStructPtr, [12, 34, 56, 0]) assert s.p4 == cast(BVoidP, 0) - assert not s.p4 # py.test.raises(TypeError, newp, BStructPtr, [12, 34, 56, None]) @@ -1003,10 +1017,11 @@ f = cast(BFunc23, _testfunc(23)) res = f(b"foo") assert res == 1000 * ord(b'f') - res = f(cast(BVoidP, 0)) # NULL + res = f(0) # NULL + assert res == -42 + res = f(long(0)) # NULL assert res == -42 py.test.raises(TypeError, f, None) - py.test.raises(TypeError, f, 0) py.test.raises(TypeError, f, 0.0) def test_call_function_23_bis(): _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit