Commits

Armin Rigo  committed 27c82dc Merge

Merge d0f6755466f7 into default:

Cancel again these changes: we can't pass 0 or None to mean NULL.
Just use NULL explicitly. (After discussion on IRC, notably with
Amaury -- thanks)

Removed some unrelated doc changes that describe something that was
planned but never implemented.

  • Participants
  • Parent commits 758d60d, d0f6755

Comments (0)

Files changed (4)

File c/_cffi_backend.c

         CTypeDescrObject *ctinit;
 
         if (!CData_Check(init)) {
-            if (PyIntOrLong_Check(init) && !PyObject_IsTrue(init)) {
-                /* convert 0 to NULL */
-                *(char **)data = NULL;
-                return 0;
-            }
             expected = "cdata pointer";
             goto cannot_convert;
         }
     char *v_cdata, *w_cdata;
 
     assert(CData_Check(v));
-    v_cdata = ((CDataObject *)v)->c_data;
-
     if (!CData_Check(w)) {
-        if (PyIntOrLong_Check(w) && !PyObject_IsTrue(w) &&
-            !(((CDataObject *)v)->c_type->ct_flags & CT_PRIMITIVE_ANY)) {
-            /* comparing a non-primitive with 0 */
-            w_cdata = NULL;
-            goto compare;
-        }
         pyres = Py_NotImplemented;
         goto done;
     }
          (((CDataObject *)w)->c_type->ct_flags & CT_PRIMITIVE_ANY)))
         goto Error;
 
+    v_cdata = ((CDataObject *)v)->c_data;
     w_cdata = ((CDataObject *)w)->c_data;
- compare:
+
     switch (op) {
     case Py_EQ: res = (v_cdata == w_cdata); break;
     case Py_NE: res = (v_cdata != w_cdata); break;
 
     ctitem = ctptr->ct_itemdescr;
     /* XXX some code duplication, how to avoid it? */
-    if (PyIntOrLong_Check(init) && !PyObject_IsTrue(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. */
-        *output_data = NULL;
-        return 0;
-    }
-    else if (PyBytes_Check(init)) {
+    if (PyBytes_Check(init)) {
         /* from a string: just returning the string here is fine.
            We assume that the C code won't modify the 'char *' data. */
         if ((ctptr->ct_flags & CT_CAST_ANYTHING) ||
     assert (x != None) is True
     assert (x == ["hello"]) is False
     assert (x != ["hello"]) is True
-
-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
+    y = cast(p, 0)
+    assert (y == None) is False
 
 def test_invalid_indexing():
     p = new_primitive_type("int")
     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
     p = newp(BIntPtr, 14141)
     s = newp(BStructPtr, [12, 34, 56, p])
     assert s.p4 == p
-    s.p4 = 0
-    assert s.p4 == 0
+    assert s.p4
     #
     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])
 
     f = cast(BFunc23, _testfunc(23))
     res = f(b"foo")
     assert res == 1000 * ord(b'f')
-    res = f(0)          # NULL
-    assert res == -42
-    res = f(long(0))    # NULL
+    res = f(cast(BVoidP, 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():

File doc/source/index.rst

 (It would be difficult because only structs and unions are internally
 stored as an indirect pointer to the data.)  If ``field`` is given,
 returns the address of that field in the structure.  The returned
-pointer is only valid as long as the original object is.  *New in
-version 0.4.*
+pointer is only valid as long as the original ``cdata`` object is; be
+sure to keep it alive if it was obtained directly from ``ffi.new()``.
+*New in version 0.4.*
 
 .. "versionadded:: 0.4" --- inlined in the previous paragraph
 
 |               | a compatible type (i.e.|                  |``+``, ``-``,   |
 |               | same type or ``char*`` |                  |bool()          |
 |               | or ``void*``, or as an |                  |                |
-|               | array instead) `(*)`;  |                  |                |
-|               | or ``0`` `(******)`    |                  |                |
+|               | array instead) `(*)`   |                  |                |
 +---------------+------------------------+                  |                |
 |  ``void *``,  | another <cdata> with   |                  |                |
 |  ``char *``   | any pointer or array   |                  |                |
-|               | type; or ``0``         |                  |                |
+|               | type                   |                  |                |
 +---------------+------------------------+                  +----------------+
 |  pointers to  | same as pointers       |                  | ``[]``, ``+``, |
 |  structure or |                        |                  | ``-``, bool(), |
    If you really want to get their value as a string, use
    ``ffi.string(ffi.cast("the_enum_type", x.field))``.
 
-.. versionadded:: 0.6
-   `(******)` ``0`` is interpreted like ``ffi.NULL`` in most places.
-   It is the way both gcc and MSVC work.  (Of course non-null integers
-   are not transparently interpreted as pointers; only ``0`` is.)
-
 
 Reference: verifier
 -------------------

File testing/test_verify.py

     p = ffi.new("char[]", b'\x10\x20\x30')
     assert lib.sum3chars(p) == b'\x60'
 
-def test_passing_0_for_NULL():
+def test_passing_string_or_NULL():
     ffi = FFI()
     ffi.cdef("int seeme1(char *); int seeme2(int *);")
     lib = ffi.verify("""
         }
     """)
     assert lib.seeme1(b"foo") == 0
-    assert lib.seeme1(0) == 1
-    assert lib.seeme1(long(0)) == 1
+    assert lib.seeme1(ffi.NULL) == 1
     assert lib.seeme2([42, 43]) == 0
-    assert lib.seeme2(0) == 1
-    assert lib.seeme2(long(0)) == 1
+    assert lib.seeme2(ffi.NULL) == 1
     py.test.raises(TypeError, lib.seeme1, None)
     py.test.raises(TypeError, lib.seeme2, None)
     py.test.raises(TypeError, lib.seeme1, 0.0)
     py.test.raises(TypeError, lib.seeme2, 0.0)
+    py.test.raises(TypeError, lib.seeme1, 0)
+    py.test.raises(TypeError, lib.seeme2, 0)
+    py.test.raises(TypeError, lib.seeme2, 0L)
 
 def test_typeof_function():
     ffi = FFI()