[pypy-commit] cffi default: Test and fix: from callbacks with 'void' as the result type, you should
arigo
noreply at buildbot.pypy.org
Thu Jul 5 19:08:11 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r581:5380328af7ce
Date: 2012-07-05 19:07 +0200
http://bitbucket.org/cffi/cffi/changeset/5380328af7ce/
Log: Test and fix: from callbacks with 'void' as the result type, you
should really return None and not anything else.
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -3141,9 +3141,15 @@
if (py_res == NULL)
goto error;
- if (SIGNATURE(0)->ct_size > 0)
+ if (SIGNATURE(0)->ct_size > 0) {
if (convert_from_object(result, SIGNATURE(0), py_res) < 0)
goto error;
+ }
+ else if (py_res != Py_None) {
+ PyErr_SetString(PyExc_TypeError, "callback with the return type 'void'"
+ " must return None");
+ goto error;
+ }
done:
Py_XDECREF(py_args);
Py_XDECREF(py_res);
diff --git a/cffi/backend_ctypes.py b/cffi/backend_ctypes.py
--- a/cffi/backend_ctypes.py
+++ b/cffi/backend_ctypes.py
@@ -284,6 +284,9 @@
return None
@staticmethod
def _to_ctypes(novalue):
+ if novalue is not None:
+ raise TypeError("None expected, got %s object" %
+ (type(novalue).__name__,))
return None
CTypesVoid._fix_class()
return CTypesVoid
@@ -734,7 +737,7 @@
# .value: http://bugs.python.org/issue1574593
else:
res2 = None
- print repr(res2)
+ #print repr(res2)
return res2
if issubclass(BResult, CTypesGenericPtr):
# The only pointers callbacks can return are void*s:
diff --git a/testing/test_function.py b/testing/test_function.py
--- a/testing/test_function.py
+++ b/testing/test_function.py
@@ -1,6 +1,6 @@
import py
from cffi import FFI
-import math, os, sys
+import math, os, sys, StringIO
from cffi.backend_ctypes import CTypesBackend
@@ -195,6 +195,25 @@
res = fd.getvalue()
assert res == 'world\n'
+ def test_callback_returning_void(self):
+ ffi = FFI(backend=self.Backend())
+ for returnvalue in [None, 42]:
+ def cb():
+ return returnvalue
+ fptr = ffi.callback("void(*)(void)", cb)
+ old_stderr = sys.stderr
+ try:
+ sys.stderr = StringIO.StringIO()
+ returned = fptr()
+ printed = sys.stderr.getvalue()
+ finally:
+ sys.stderr = old_stderr
+ assert returned is None
+ if returnvalue is None:
+ assert printed == ''
+ else:
+ assert "None" in printed
+
def test_passing_array(self):
ffi = FFI(backend=self.Backend())
ffi.cdef("""
More information about the pypy-commit
mailing list