Commits

Armin Rigo committed c42e0c4

Passing None as an ``item *`` argument to a function.

Comments (0)

Files changed (4)

c/_cffi_backend.c

 
     ctitem = ctptr->ct_itemdescr;
     /* XXX some code duplication, how to avoid it? */
-    if (PyBytes_Check(init)) {
+    if (init == Py_None) {
+        *output_data = NULL;
+        return 0;
+    }
+    else 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) ||
 
 static int _testfunc23(char *p)
 {
-    return 1000 * p[0];
+    if (p)
+        return 1000 * p[0];
+    return -42;
 }
 
 static PyObject *b__testfunc(PyObject *self, PyObject *args)
     f = cast(BFunc23, _testfunc(23))
     res = f(b"foo")
     assert res == 1000 * ord(b'f')
+    res = f(None)
+    assert res == -42
 
 def test_call_function_23_bis():
     # declaring the function as int(unsigned char*)

doc/source/index.rst

    you need to specify it in a list of length 1; for example, a ``struct
    foo *`` argument might be passed as ``[[field1, field2...]]``.
 
+.. versionadded:: 0.6
+   You can also pass None to ``item *`` arguments (meaning NULL).
+
 As an optimization, the CPython version of CFFI assumes that a function
 with a ``char *`` argument to which you pass a Python string will not
 actually modify the array of characters passed in, and so passes directly

testing/test_verify.py

     assert lib.sum3chars((b'\x10', b'\x20', b'\x30')) == b'\x60'
     p = ffi.new("char[]", b'\x10\x20\x30')
     assert lib.sum3chars(p) == b'\x60'
+
+def test_passing_None():
+    ffi = FFI()
+    ffi.cdef("int seeme1(char *); int seeme2(int *);")
+    lib = ffi.verify("""
+        int seeme1(char *x) {
+            return (x == NULL);
+        }
+        int seeme2(int *x) {
+            return (x == NULL);
+        }
+    """)
+    assert lib.seeme1("foo") == 0
+    assert lib.seeme1(None) == 1
+    assert lib.seeme2([42, 43]) == 0
+    assert lib.seeme2(None) == 1
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.