[pypy-svn] r79557 - pypy/branch/fast-forward/lib_pypy/_ctypes
afa at codespeak.net
afa at codespeak.net
Fri Nov 26 15:07:14 CET 2010
Author: afa
Date: Fri Nov 26 15:07:12 2010
New Revision: 79557
Modified:
pypy/branch/fast-forward/lib_pypy/_ctypes/basics.py
pypy/branch/fast-forward/lib_pypy/_ctypes/function.py
Log:
Fix the argument conversion:
- first try "argtype.from_param"
- then _as_parameter_
- then default guesses
Modified: pypy/branch/fast-forward/lib_pypy/_ctypes/basics.py
==============================================================================
--- pypy/branch/fast-forward/lib_pypy/_ctypes/basics.py (original)
+++ pypy/branch/fast-forward/lib_pypy/_ctypes/basics.py Fri Nov 26 15:07:12 2010
@@ -46,15 +46,6 @@
else:
return self.from_param(as_parameter)
- def _CData_input(self, value):
- """Used when data enters into ctypes from user code. 'value' is
- some user-specified Python object, which is converted into a _rawffi
- array of length 1 containing the same value according to the
- type 'self'.
- """
- cobj = self.from_param(value)
- return cobj, cobj._get_buffer_for_param()
-
def _CData_value(self, value):
cobj = self.from_param(value)
# we don't care here if this stuff will live afterwards, as we're
Modified: pypy/branch/fast-forward/lib_pypy/_ctypes/function.py
==============================================================================
--- pypy/branch/fast-forward/lib_pypy/_ctypes/function.py (original)
+++ pypy/branch/fast-forward/lib_pypy/_ctypes/function.py Fri Nov 26 15:07:12 2010
@@ -54,7 +54,15 @@
return self._argtypes_
def _setargtypes(self, argtypes):
self._ptr = None
- self._argtypes_ = argtypes
+ if argtypes is None:
+ self._argtypes_ = None
+ else:
+ for i, argtype in enumerate(argtypes):
+ if not hasattr(argtype, 'from_param'):
+ raise TypeError(
+ "item %d in _argtypes_ has no from_param method" % (
+ i + 1,))
+ self._argtypes_ = argtypes
argtypes = property(_getargtypes, _setargtypes)
def _getrestype(self):
@@ -179,13 +187,15 @@
thisarg = None
if argtypes is None:
- argtypes = self._guess_argtypes(args)
- argtypes, argsandobjs = self._wrap_args(argtypes, args)
+ argtypes = []
+ args = self._convert_args(argtypes, args)
+ argtypes = [type(arg) for arg in args]
restype = self._restype_
funcptr = self._getfuncptr(argtypes, restype, thisarg)
- resbuffer = funcptr(*[arg._buffer for _, arg in argsandobjs])
- result = self._build_result(restype, resbuffer, argtypes, argsandobjs)
+ resbuffer = funcptr(*[arg._get_buffer_for_param()._buffer
+ for arg in args])
+ result = self._build_result(restype, resbuffer, argtypes, args)
# The 'errcheck' protocol
if self._errcheck_:
@@ -243,31 +253,33 @@
raise
@staticmethod
- def _guess_argtypes(args):
+ def _conv_param(argtype, arg, index):
from ctypes import c_char_p, c_wchar_p, c_void_p, c_int
- res = []
- for arg in args:
- if hasattr(arg, '_as_parameter_'):
- arg = arg._as_parameter_
- if isinstance(arg, str):
- res.append(c_char_p)
- elif isinstance(arg, unicode):
- res.append(c_wchar_p)
- elif isinstance(arg, _CData):
- res.append(type(arg))
- elif arg is None:
- res.append(c_void_p)
- #elif arg == 0:
- # res.append(c_void_p)
- elif isinstance(arg, (int, long)):
- res.append(c_int)
- else:
- raise TypeError("Don't know how to handle %s" % (arg,))
- return res
+ if argtype is not None:
+ arg = argtype.from_param(arg)
+ if hasattr(arg, '_as_parameter_'):
+ arg = arg._as_parameter_
+
+ if isinstance(arg, _CData):
+ # The usual case when argtype is defined
+ cobj = arg
+ elif isinstance(arg, str):
+ cobj = c_char_p(arg)
+ elif isinstance(arg, unicode):
+ cobj = c_wchar_p(arg)
+ elif arg is None:
+ cobj = c_void_p()
+ elif isinstance(arg, (int, long)):
+ cobj = c_int(arg)
+ else:
+ raise TypeError("Don't know how to handle %s" % (arg,))
+
+ return cobj
- def _wrap_args(self, argtypes, args):
+ def _convert_args(self, argtypes, args):
wrapped_args = []
consumed = 0
+
for i, argtype in enumerate(argtypes):
defaultvalue = None
if i > 0 and self._paramflags is not None:
@@ -294,7 +306,7 @@
val = defaultvalue
if val is None:
val = 0
- wrapped = argtype._CData_input(val)
+ wrapped = self._conv_param(argtype, val, consumed)
wrapped_args.append(wrapped)
continue
else:
@@ -309,23 +321,22 @@
raise TypeError("Not enough arguments")
try:
- wrapped = argtype._CData_input(arg)
- except (UnicodeError, TypeError), e:
+ wrapped = self._conv_param(argtype, arg, consumed)
+ except (UnicodeError, TypeError, ValueError), e:
raise ArgumentError(str(e))
wrapped_args.append(wrapped)
consumed += 1
if len(wrapped_args) < len(args):
extra = args[len(wrapped_args):]
- extra_types = self._guess_argtypes(extra)
- for arg, argtype in zip(extra, extra_types):
+ argtypes = list(argtypes)
+ for i, arg in enumerate(extra):
try:
- wrapped = argtype._CData_input(arg)
- except (UnicodeError, TypeError), e:
+ wrapped = self._conv_param(None, arg, i)
+ except (UnicodeError, TypeError, ValueError), e:
raise ArgumentError(str(e))
wrapped_args.append(wrapped)
- argtypes = list(argtypes) + extra_types
- return argtypes, wrapped_args
+ return wrapped_args
def _build_result(self, restype, resbuffer, argtypes, argsandobjs):
"""Build the function result:
@@ -338,7 +349,7 @@
if self._com_index:
if resbuffer[0] & 0x80000000:
raise get_com_error(resbuffer[0],
- self._com_iid, argsandobjs[0][0])
+ self._com_iid, argsandobjs[0])
else:
retval = int(resbuffer[0])
elif restype is not None:
@@ -357,8 +368,8 @@
results = []
if self._paramflags:
- for argtype, (obj, _), paramflag in zip(argtypes[1:], argsandobjs[1:],
- self._paramflags):
+ for argtype, obj, paramflag in zip(argtypes[1:], argsandobjs[1:],
+ self._paramflags):
if len(paramflag) == 2:
idlflag, name = paramflag
elif len(paramflag) == 3:
More information about the Pypy-commit
mailing list