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

Reply via email to