diff options
author | Armin Rigo <arigo@tunes.org> | 2015-07-09 10:17:21 +0200 |
---|---|---|
committer | Armin Rigo <arigo@tunes.org> | 2015-07-09 10:17:21 +0200 |
commit | 0a3a703930232d4046647d756fece564a90ef7cd (patch) | |
tree | c2d15d4c8a51f833dd0bfdcdbb59923c0c8bd011 | |
parent | edbdf6ea93f08983f4f21d066e697996210c4c38 (diff) | |
download | cffi-0a3a703930232d4046647d756fece564a90ef7cd.tar.gz |
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
-rw-r--r-- | c/_cffi_backend.c | 25 | ||||
-rw-r--r-- | c/test_c.py | 23 |
2 files changed, 42 insertions, 6 deletions
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c index 5c5a52e..ab26098 100644 --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -1060,12 +1060,25 @@ static wchar_t _convert_to_wchar_t(PyObject *init) 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 index 59fe157..37dd4a3 100644 --- a/c/test_c.py +++ b/c/test_c.py @@ -3413,6 +3413,29 @@ def test_dereference_null_ptr(): 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" |