[pypy-commit] pypy default: fix test_callbacks by converting/unwrapping the arguments before calling the actual callback
antocuni
noreply at buildbot.pypy.org
Wed Jul 27 13:24:23 CEST 2011
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch:
Changeset: r46009:4d240d754afa
Date: 2011-07-27 11:58 +0200
http://bitbucket.org/pypy/pypy/changeset/4d240d754afa/
Log: fix test_callbacks by converting/unwrapping the arguments before
calling the actual callback
diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py
--- a/lib_pypy/_ctypes/function.py
+++ b/lib_pypy/_ctypes/function.py
@@ -296,13 +296,9 @@
"This function takes %d argument%s (%s given)"
% (len(self._argtypes_), plural, len(args)))
- # check that arguments are convertible
- ## XXX Not as long as ctypes.cast is a callback function with
- ## py_object arguments...
- ## self._convert_args(self._argtypes_, args, {})
-
+ newargs = self._convert_args_for_callback(argtypes, args)
try:
- res = self.callable(*args)
+ res = self.callable(*newargs)
except:
exc_info = sys.exc_info()
traceback.print_tb(exc_info[2], file=sys.stderr)
@@ -466,6 +462,16 @@
return cobj, cobj._to_ffi_param(), type(cobj)
+ def _convert_args_for_callback(self, argtypes, args):
+ assert len(argtypes) == len(args)
+ newargs = []
+ for argtype, arg in zip(argtypes, args):
+ param = argtype.from_param(arg)
+ if self._is_primitive(argtype):
+ param = param.value
+ newargs.append(param)
+ return newargs
+
def _convert_args(self, argtypes, args, kwargs, marker=object()):
newargs = []
outargs = []
@@ -556,6 +562,9 @@
newargtypes.append(newargtype)
return keepalives, newargs, newargtypes, outargs
+ @staticmethod
+ def _is_primitive(argtype):
+ return argtype.__bases__[0] is _SimpleCData
def _wrap_result(self, restype, result):
"""
@@ -564,7 +573,7 @@
"""
# hack for performance: if restype is a "simple" primitive type, don't
# allocate the buffer because it's going to be thrown away immediately
- if restype.__bases__[0] is _SimpleCData and not restype._is_pointer_like():
+ if self._is_primitive(restype) and not restype._is_pointer_like():
return result
#
shape = restype._ffishape
diff --git a/lib_pypy/_ctypes/primitive.py b/lib_pypy/_ctypes/primitive.py
--- a/lib_pypy/_ctypes/primitive.py
+++ b/lib_pypy/_ctypes/primitive.py
@@ -10,6 +10,8 @@
from _ctypes.builtin import ConvMode
from _ctypes.array import Array
from _ctypes.pointer import _Pointer, as_ffi_pointer
+#from _ctypes.function import CFuncPtr # this import is moved at the bottom
+ # because else it's circular
class NULL(object):
pass
@@ -86,7 +88,7 @@
return res
if isinstance(value, Array):
return value
- if isinstance(value, _Pointer):
+ if isinstance(value, (_Pointer, CFuncPtr)):
return cls.from_address(value._buffer.buffer)
if isinstance(value, (int, long)):
return cls(value)
@@ -338,3 +340,5 @@
def __nonzero__(self):
return self._buffer[0] not in (0, '\x00')
+
+from _ctypes.function import CFuncPtr
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_callbacks.py b/pypy/module/test_lib_pypy/ctypes_tests/test_callbacks.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_callbacks.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_callbacks.py
@@ -15,12 +15,12 @@
def check_type(self, typ, arg):
unwrapped_types = {
- c_float: float,
- c_double: float,
- c_char: str,
- c_char_p: str,
- c_uint: long,
- c_ulong: long,
+ c_float: (float,),
+ c_double: (float,),
+ c_char: (str,),
+ c_char_p: (str,),
+ c_uint: (int, long),
+ c_ulong: (int, long),
}
PROTO = self.functype.im_func(typ, typ)
@@ -33,7 +33,7 @@
assert result == arg
result2 = cfunc(typ(arg))
- assert type(result2) is unwrapped_types.get(typ, int)
+ assert type(result2) in unwrapped_types.get(typ, (int, long))
PROTO = self.functype.im_func(typ, c_byte, typ)
result = PROTO(self.callback)(-3, arg)
More information about the pypy-commit
mailing list