[pypy-svn] r79531 - pypy/branch/fast-forward/lib_pypy/_ctypes

afa at codespeak.net afa at codespeak.net
Fri Nov 26 00:36:32 CET 2010


Author: afa
Date: Fri Nov 26 00:36:31 2010
New Revision: 79531

Modified:
   pypy/branch/fast-forward/lib_pypy/_ctypes/function.py
Log:
Implement functptr.errcheck:
called after the function call, can modify the result or
raise an exception.


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 00:36:31 2010
@@ -35,6 +35,7 @@
 
     _argtypes_ = None
     _restype_ = None
+    _errcheck_ = None
     _flags_ = 0
     _ffiargshape = 'P'
     _ffishape = 'P'
@@ -72,6 +73,19 @@
         del self._restype_
     restype = property(_getrestype, _setrestype, _delrestype)
 
+    def _geterrcheck(self):
+        return getattr(self, '_errcheck_', None)
+    def _seterrcheck(self, errcheck):
+        if not callable(errcheck):
+            raise TypeError("The errcheck attribute must be callable")
+        self._errcheck_ = errcheck
+    def _delerrcheck(self):
+        try:
+            del self._errcheck_
+        except AttributeError:
+            pass
+    errcheck = property(_geterrcheck, _seterrcheck, _delerrcheck)
+
     def _ffishapes(self, args, restype):
         argtypes = [arg._ffiargshape for arg in args]
         if restype is not None:
@@ -168,7 +182,21 @@
         restype = self._restype_
         funcptr = self._getfuncptr(argtypes, restype, thisarg)
         resbuffer = funcptr(*[arg._buffer for _, arg in argsandobjs])
-        return self._build_result(restype, resbuffer, argtypes, argsandobjs)
+        result = self._build_result(restype, resbuffer, argtypes, argsandobjs)
+
+        # The 'errcheck' protocol
+        if self._errcheck_:
+            v = self._errcheck_(result, self, args)
+            # If the errcheck funtion failed, let it throw
+            # If the errcheck function returned callargs unchanged,
+            # continue normal processing.
+            # If the errcheck function returned something else,
+            # use that as result.
+            if v is not args:
+                result = v
+
+        return result
+
 
     def _getfuncptr(self, argtypes, restype, thisarg=None):
         if self._ptr is not None and argtypes is self._argtypes_:



More information about the Pypy-commit mailing list