[pypy-commit] cffi default: Test and fix for an obscure case that raised SystemError instead of
arigo
noreply at buildbot.pypy.org
Fri Jul 27 14:27:35 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r710:419181fc231b
Date: 2012-07-27 14:27 +0200
http://bitbucket.org/cffi/cffi/changeset/419181fc231b/
Log: Test and fix for an obscure case that raised SystemError instead of
the proper TypeError.
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -3105,7 +3105,7 @@
/* then enough room for the result --- which means at least
sizeof(ffi_arg), according to the ffi docs */
i = fb->rtype->size;
- if (i < sizeof(ffi_arg))
+ if (i < (Py_ssize_t)sizeof(ffi_arg))
i = sizeof(ffi_arg);
exchange_offset += i;
}
@@ -3361,7 +3361,17 @@
/* work work work around a libffi irregularity: for integer return
types we have to fill at least a complete 'ffi_arg'-sized result
buffer. */
- if (ctype->ct_size < sizeof(ffi_arg)) {
+ if (ctype->ct_size < (Py_ssize_t)sizeof(ffi_arg)) {
+ if (ctype->ct_flags & CT_VOID) {
+ if (pyobj == Py_None) {
+ return 0;
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "callback with the return type 'void' must return None");
+ return -1;
+ }
+ }
if ((ctype->ct_flags & (CT_PRIMITIVE_SIGNED | CT_IS_ENUM))
== CT_PRIMITIVE_SIGNED) {
PY_LONG_LONG value;
@@ -3429,16 +3439,8 @@
py_res = PyEval_CallObject(py_ob, py_args);
if (py_res == NULL)
goto error;
-
- if (SIGNATURE(1)->ct_size > 0) {
- if (convert_from_object_fficallback(result, SIGNATURE(1), py_res) < 0)
- goto error;
- }
- else if (py_res != Py_None) {
- PyErr_SetString(PyExc_TypeError, "callback with the return type 'void'"
- " must return None");
+ if (convert_from_object_fficallback(result, SIGNATURE(1), py_res) < 0)
goto error;
- }
done:
Py_XDECREF(py_args);
Py_XDECREF(py_res);
@@ -3487,14 +3489,8 @@
ctresult = (CTypeDescrObject *)PyTuple_GET_ITEM(ct->ct_stuff, 1);
size = ctresult->ct_size;
- if (ctresult->ct_flags & (CT_PRIMITIVE_CHAR | CT_PRIMITIVE_SIGNED |
- CT_PRIMITIVE_UNSIGNED)) {
- if (size < sizeof(ffi_arg))
- size = sizeof(ffi_arg);
- }
- else if (size < 0) {
- size = 0;
- }
+ if (size < (Py_ssize_t)sizeof(ffi_arg))
+ size = sizeof(ffi_arg);
py_rawerr = PyString_FromStringAndSize(NULL, size);
if (py_rawerr == NULL)
return NULL;
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -926,6 +926,17 @@
assert s.a == -10
assert s.b == 1E-42
+def test_callback_returning_void():
+ BVoid = new_void_type()
+ BFunc = new_function_type((), BVoid, False)
+ def cb():
+ seen.append(42)
+ f = callback(BFunc, cb)
+ seen = []
+ f()
+ assert seen == [42]
+ py.test.raises(TypeError, callback, BFunc, cb, -42)
+
def test_enum_type():
BEnum = new_enum_type("foo", (), ())
assert repr(BEnum) == "<ctype 'enum foo'>"
More information about the pypy-commit
mailing list