Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r2217:2001880ed1c7
Date: 2015-07-09 10:17 +0200
http://bitbucket.org/cffi/cffi/changeset/2001880ed1c7/

Log:    Issue #213: in case we'd give the error message "initializer for
        ctype 'A' must be a pointer to same type, not cdata 'B'", but with
        A=B, then give instead a different error message to try to clear up
        the confusion

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -1060,12 +1060,25 @@
 static int _convert_error(PyObject *init, const char *ct_name,
                           const char *expected)
 {
-    if (CData_Check(init))
-        PyErr_Format(PyExc_TypeError,
-                     "initializer for ctype '%s' must be a %s, "
-                     "not cdata '%s'",
-                     ct_name, expected,
-                     ((CDataObject *)init)->c_type->ct_name);
+    if (CData_Check(init)) {
+        const char *ct_name_2 = ((CDataObject *)init)->c_type->ct_name;
+        if (strcmp(ct_name, ct_name_2) != 0)
+            PyErr_Format(PyExc_TypeError,
+                         "initializer for ctype '%s' must be a %s, "
+                         "not cdata '%s'",
+                         ct_name, expected, ct_name_2);
+        else {
+            /* in case we'd give the error message "initializer for
+               ctype 'A' must be a pointer to same type, not cdata
+               'B'", but with A=B, then give instead a different error
+               message to try to clear up the confusion */
+            PyErr_Format(PyExc_TypeError,
+                         "initializer for ctype '%s' appears indeed to be 
'%s',"
+                         " but the types are different (check that you are not"
+                         " e.g. mixing up different ffi instances)",
+                         ct_name, ct_name_2);
+        }
+    }
     else
         PyErr_Format(PyExc_TypeError,
                      "initializer for ctype '%s' must be a %s, "
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -3413,6 +3413,29 @@
     py.test.raises(RuntimeError, "p[42]")
     py.test.raises(RuntimeError, "p[42] = -1")
 
+def test_mixup():
+    BStruct1 = new_struct_type("foo")
+    BStruct2 = new_struct_type("foo")   # <= same name as BStruct1
+    BStruct3 = new_struct_type("bar")
+    BStruct1Ptr = new_pointer_type(BStruct1)
+    BStruct2Ptr = new_pointer_type(BStruct2)
+    BStruct3Ptr = new_pointer_type(BStruct3)
+    BStruct1PtrPtr = new_pointer_type(BStruct1Ptr)
+    BStruct2PtrPtr = new_pointer_type(BStruct2Ptr)
+    BStruct3PtrPtr = new_pointer_type(BStruct3Ptr)
+    pp1 = newp(BStruct1PtrPtr)
+    pp2 = newp(BStruct2PtrPtr)
+    pp3 = newp(BStruct3PtrPtr)
+    pp1[0] = pp1[0]
+    e = py.test.raises(TypeError, "pp3[0] = pp1[0]")
+    assert str(e.value).startswith("initializer for ctype 'bar *' must be a ")
+    assert str(e.value).endswith(", not cdata 'foo *'")
+    e = py.test.raises(TypeError, "pp2[0] = pp1[0]")
+    assert str(e.value) == ("initializer for ctype 'foo *' appears indeed to "
+                            "be 'foo *', but the types are different (check "
+                            "that you are not e.g. mixing up different ffi "
+                            "instances)")
+
 def test_version():
     # this test is here mostly for PyPy
     assert __version__ == "1.2.0"
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to