Author: Armin Rigo <[email protected]>
Branch: static-callback
Changeset: r2391:90daaaedaab6
Date: 2015-11-13 18:06 +0100
http://bitbucket.org/cffi/cffi/changeset/90daaaedaab6/

Log:    More tests, make the name optional in ffi.call_python()

diff --git a/c/call_python.c b/c/call_python.c
--- a/c/call_python.c
+++ b/c/call_python.c
@@ -12,12 +12,20 @@
     CTypeDescrObject *ct;
     FFIObject *ffi;
     builder_c_t *types_builder;
+    PyObject *name = NULL;
 
     if (!PyArg_ParseTuple(outer_args, "OzOO", &ffi, &s, &error, &onerror))
         return NULL;
 
     if (s == NULL) {
-        abort();
+        PyObject *name = PyObject_GetAttrString(fn, "__name__");
+        if (name == NULL)
+            return NULL;
+        s = PyString_AsString(name);
+        if (s == NULL) {
+            Py_DECREF(name);
+            return NULL;
+        }
     }
 
     types_builder = &ffi->types_builder;
@@ -27,6 +35,7 @@
     g = &types_builder->ctx.globals[index];
     if (_CFFI_GETOP(g->type_op) != _CFFI_OP_CALL_PYTHON)
         goto not_found;
+    Py_XDECREF(name);
 
     ct = realize_c_type(types_builder, types_builder->ctx.types,
                         _CFFI_GETARG(g->type_op));
@@ -53,7 +62,9 @@
     return x;
 
  not_found:
-    abort();
+    PyErr_Format(FFIError, "ffi.call_python('%s'): name not found as a "
+                           "CFFI_CALL_PYTHON line from the cdef", s);
+    Py_XDECREF(name);
     return NULL;
 }
 
diff --git a/testing/cffi1/test_recompiler.py b/testing/cffi1/test_recompiler.py
--- a/testing/cffi1/test_recompiler.py
+++ b/testing/cffi1/test_recompiler.py
@@ -1509,14 +1509,54 @@
 
     @ffi.call_python("bar")
     def my_bar(x, y):
-        seen.append((x, y))
+        seen.append(("Bar", x, y))
         return x * y
     assert my_bar == lib.bar
     seen = []
     res = lib.bar(6, 7)
-    assert seen == [(6, 7)]
+    assert seen == [("Bar", 6, 7)]
     assert res == 42
 
+    @ffi.call_python()
+    def baz(x, y):
+        seen.append(("Baz", x, y))
+    seen = []
+    res = baz(50L, 8L)
+    assert res is None
+    assert seen == [("Baz", 50, 8)]
+    assert type(seen[0][1]) is type(seen[0][2]) is int
+    assert baz == lib.baz
+
+def test_call_python_bogus_name():
+    ffi = FFI()
+    ffi.cdef("int abc;")
+    lib = verify(ffi, 'test_call_python_bogus_name', "int abc;")
+    def fn():
+        pass
+    py.test.raises(ffi.error, ffi.call_python("unknown_name"), fn)
+    py.test.raises(ffi.error, ffi.call_python("abc"), fn)
+    assert lib.abc == 0
+    e = py.test.raises(ffi.error, ffi.call_python("abc"), fn)
+    assert str(e.value) == ("ffi.call_python('abc'): name not found as a "
+                            "CFFI_CALL_PYTHON line from the cdef")
+    e = py.test.raises(ffi.error, ffi.call_python(), fn)
+    assert str(e.value) == ("ffi.call_python('fn'): name not found as a "
+                            "CFFI_CALL_PYTHON line from the cdef")
+    #
+    py.test.raises(TypeError, ffi.call_python(42), fn)
+    py.test.raises((TypeError, AttributeError), ffi.call_python(), "foo")
+    class X:
+        pass
+    x = X()
+    x.__name__ = x
+    py.test.raises(TypeError, ffi.call_python(), x)
+
+def test_call_python_void_must_return_none():
+    xxxx
+
+def test_call_python_redefine():
+    xxxx
+
 def test_call_python_2():
     ffi = FFI()
     ffi.cdef("""
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to