[pypy-svn] r53137 - in pypy/dist/pypy/lib: _ctypes app_test/ctypes
fijal at codespeak.net
fijal at codespeak.net
Sun Mar 30 08:16:58 CEST 2008
Author: fijal
Date: Sun Mar 30 08:16:57 2008
New Revision: 53137
Modified:
pypy/dist/pypy/lib/_ctypes/function.py
pypy/dist/pypy/lib/app_test/ctypes/test_cast.py
pypy/dist/pypy/lib/app_test/ctypes/test_cfuncs.py
pypy/dist/pypy/lib/app_test/ctypes/test_checkretval.py
pypy/dist/pypy/lib/app_test/ctypes/test_returnfuncptrs.py
pypy/dist/pypy/lib/app_test/ctypes/test_simplesubclasses.py
pypy/dist/pypy/lib/app_test/ctypes/test_values.py
Log:
* support for address parameters for CFUNCTYPE
* few minor fixes.
Modified: pypy/dist/pypy/lib/_ctypes/function.py
==============================================================================
--- pypy/dist/pypy/lib/_ctypes/function.py (original)
+++ pypy/dist/pypy/lib/_ctypes/function.py Sun Mar 30 08:16:57 2008
@@ -1,8 +1,9 @@
-import types
from _ctypes.basics import _CData, _CDataMeta, ArgumentError, keepalive_key
import _rawffi
+# XXX this file needs huge refactoring I fear
+
class CFuncPtrType(_CDataMeta):
# XXX write down here defaults and such things
@@ -24,6 +25,9 @@
_ffishape = 'P'
_fficompositesize = None
_needs_free = False
+ callable = None
+ _ptr = None
+ _buffer = None
def _getargtypes(self):
return self._argtypes_
@@ -37,30 +41,34 @@
if restype is int:
from ctypes import c_int
restype = c_int
- if not isinstance(restype, _CDataMeta) and not restype is None:
+ if not isinstance(restype, _CDataMeta) and not restype is None and \
+ not callable(restype):
raise TypeError("Expected ctypes type, got %s" % (restype,))
self._restype_ = restype
- restype = property(_getrestype, _setrestype)
+ restype = property(_getrestype, _setrestype)
+
+ def _ffishapes(self, args, restype):
+ argtypes = [arg._ffiargshape for arg in args]
+ if restype is not None:
+ restype = restype._ffiargshape
+ else:
+ restype = 'O' # void
+ return argtypes, restype
def __init__(self, argument=None):
- self.callable = None
self.name = None
self._objects = {keepalive_key(0):self}
- if isinstance(argument, int):
- self._buffer = _rawffi.Array('P').fromaddress(argument, 1)
- # XXX finish this one, we need to be able to jump there somehow
+ self._needs_free = True
+ if isinstance(argument, (int, long)):
+ ffiargs, ffires = self._ffishapes(self._argtypes_, self._restype_)
+ self._ptr = _rawffi.FuncPtr(argument, ffiargs, ffires)
+ self._buffer = self._ptr.byptr()
elif callable(argument):
self.callable = argument
- argtypes = [arg._ffiargshape for arg in self._argtypes_]
- restype = self._restype_
- if restype is not None:
- restype = restype._ffiargshape
- else:
- restype = 'O' # void
+ ffiargs, ffires = self._ffishapes(self._argtypes_, self._restype_)
self._ptr = _rawffi.CallbackPtr(self._wrap_callable(argument,
self.argtypes),
- argtypes, restype)
- self._needs_free = True
+ ffiargs, ffires)
self._buffer = self._ptr.byptr()
elif isinstance(argument, tuple) and len(argument) == 2:
import ctypes
@@ -68,11 +76,12 @@
if isinstance(self.dll, str):
self.dll = ctypes.CDLL(self.dll)
# we need to check dll anyway
- self._getfuncptr([], ctypes.c_int)
+ ptr = self._getfuncptr([], ctypes.c_int)
+ self._buffer = ptr.byptr()
elif argument is None:
+ # this is needed for casts
self._buffer = _rawffi.Array('P')(1)
- self._needs_free = True
- return # needed for test..
+ return
else:
raise TypeError("Unknown constructor %s" % (argument,))
@@ -86,7 +95,10 @@
def __call__(self, *args):
if self.callable is not None:
- return self.callable(*args)
+ res = self.callable(*args)
+ if self._restype_ is not None:
+ return res
+ return
argtypes = self._argtypes_
if argtypes is None:
argtypes = self._guess_argtypes(args)
@@ -102,14 +114,21 @@
args = self._wrap_args(argtypes, args)
resbuffer = funcptr(*[arg._buffer for obj, arg in args])
if restype is not None:
+ if not isinstance(restype, _CDataMeta):
+ return restype(resbuffer[0])
return restype._CData_retval(resbuffer)
def _getfuncptr(self, argtypes, restype):
- if restype is None:
+ if self._ptr is not None:
+ return self._ptr
+ if restype is None or not isinstance(restype, _CDataMeta):
import ctypes
restype = ctypes.c_int
argshapes = [arg._ffiargshape for arg in argtypes]
resshape = restype._ffiargshape
+ if self._buffer is not None:
+ self._ptr = _rawffi.FuncPtr(self._buffer[0], argshapes, resshape)
+ return self._ptr
return self.dll._handle.ptr(self.name, argshapes, resshape)
def _guess_argtypes(self, args):
@@ -144,7 +163,7 @@
if self._needs_free:
self._buffer.free()
self._buffer = None
- if hasattr(self, '_ptr'):
+ if isinstance(self._ptr, _rawffi.CallbackPtr):
self._ptr.free()
self._ptr = None
- self._needs_free = False
+ self._needs_free = False
Modified: pypy/dist/pypy/lib/app_test/ctypes/test_cast.py
==============================================================================
--- pypy/dist/pypy/lib/app_test/ctypes/test_cast.py (original)
+++ pypy/dist/pypy/lib/app_test/ctypes/test_cast.py Sun Mar 30 08:16:57 2008
@@ -2,6 +2,10 @@
import sys, py
from support import BaseCTypesTestChecker
+def setup_module(mod):
+ import conftest
+ mod.lib = CDLL(str(conftest.sofile))
+
class TestCast(BaseCTypesTestChecker):
def test_array2pointer(self):
@@ -77,5 +81,7 @@
def test_cast_functype(self):
# make sure we can cast function type
- P = CFUNCTYPE(c_int)
- cast(1, P)
+ my_sqrt = lib.my_sqrt
+ sqrt = cast(cast(my_sqrt, c_void_p), CFUNCTYPE(c_double, c_double))
+ assert sqrt(4.0) == 2.0
+
Modified: pypy/dist/pypy/lib/app_test/ctypes/test_cfuncs.py
==============================================================================
--- pypy/dist/pypy/lib/app_test/ctypes/test_cfuncs.py (original)
+++ pypy/dist/pypy/lib/app_test/ctypes/test_cfuncs.py Sun Mar 30 08:16:57 2008
@@ -163,7 +163,6 @@
assert self.S() == 42
def test_callwithresult(self):
- py.test.skip("function as restype unsupported")
def process_result(result):
return result * 2
self._dll.tf_i.restype = process_result
Modified: pypy/dist/pypy/lib/app_test/ctypes/test_checkretval.py
==============================================================================
--- pypy/dist/pypy/lib/app_test/ctypes/test_checkretval.py (original)
+++ pypy/dist/pypy/lib/app_test/ctypes/test_checkretval.py Sun Mar 30 08:16:57 2008
@@ -16,7 +16,7 @@
class TestRetval:
def test_checkretval(self):
- py.test.skip("restype being a function not implemented")
+ py.test.skip("_check_retval_ is not supported")
assert 42 == dll._testfunc_p_p(42)
Modified: pypy/dist/pypy/lib/app_test/ctypes/test_returnfuncptrs.py
==============================================================================
--- pypy/dist/pypy/lib/app_test/ctypes/test_returnfuncptrs.py (original)
+++ pypy/dist/pypy/lib/app_test/ctypes/test_returnfuncptrs.py Sun Mar 30 08:16:57 2008
@@ -9,7 +9,6 @@
class TestReturnFuncPtr:
def test_with_prototype(self):
- py.test.skip("returning functions doesn't work")
# The _ctypes_test shared lib/dll exports quite some functions for testing.
# The get_strchr function returns a *pointer* to the C strchr function.
get_strchr = dll.get_strchr
@@ -21,7 +20,6 @@
raises(TypeError, strchr, "abcdef")
def test_without_prototype(self):
- py.test.skip("constructing functions from address doesn't work")
get_strchr = dll.get_strchr
# the default 'c_int' would not work on systems where sizeof(int) != sizeof(void *)
get_strchr.restype = c_void_p
Modified: pypy/dist/pypy/lib/app_test/ctypes/test_simplesubclasses.py
==============================================================================
--- pypy/dist/pypy/lib/app_test/ctypes/test_simplesubclasses.py (original)
+++ pypy/dist/pypy/lib/app_test/ctypes/test_simplesubclasses.py Sun Mar 30 08:16:57 2008
@@ -15,7 +15,6 @@
assert not MyInt(42) == MyInt(43)
def test_ignore_retval(self):
- py.test.skip("XXX different callback behavior")
# Test if the return value of a callback is ignored
# if restype is None
proto = CFUNCTYPE(None)
@@ -27,7 +26,7 @@
def test_int_callback(self):
- py.test.skip("XXX different callback behavior")
+ py.test.skip("XXX subclassing not implemented")
args = []
def func(arg):
args.append(arg)
Modified: pypy/dist/pypy/lib/app_test/ctypes/test_values.py
==============================================================================
--- pypy/dist/pypy/lib/app_test/ctypes/test_values.py (original)
+++ pypy/dist/pypy/lib/app_test/ctypes/test_values.py Sun Mar 30 08:16:57 2008
@@ -26,7 +26,7 @@
class TestWin_Values(BaseCTypesTestChecker):
"""This test only works when python itself is a dll/shared library"""
def setup_class(cls):
- py.test.skip("not implemented")
+ py.test.skip("only when cpython itself is a dll")
def test_optimizeflag(self):
# This test accesses the Py_OptimizeFlag intger, which is
More information about the Pypy-commit
mailing list