From 5becdbee96abef0ec5d5009618d7c3316678168e Mon Sep 17 00:00:00 2001 From: Thomas Heller Date: Thu, 6 Jul 2006 08:48:35 +0000 Subject: Patch #1517790: It is now possible to use custom objects in the ctypes foreign function argtypes sequence as long as they provide a from_param method, no longer is it required that the object is a ctypes type. --- Lib/ctypes/test/test_parameters.py | 35 +++++++++++++++++++++++++++++++++++ Misc/NEWS | 4 ++++ Modules/_ctypes/_ctypes.c | 5 ++--- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/Lib/ctypes/test/test_parameters.py b/Lib/ctypes/test/test_parameters.py index 9537400..1b7f0dc 100644 --- a/Lib/ctypes/test/test_parameters.py +++ b/Lib/ctypes/test/test_parameters.py @@ -147,6 +147,41 @@ class SimpleTypesTestCase(unittest.TestCase): ## def test_performance(self): ## check_perf() + def test_noctypes_argtype(self): + import _ctypes_test + from ctypes import CDLL, c_void_p, ArgumentError + + func = CDLL(_ctypes_test.__file__)._testfunc_p_p + func.restype = c_void_p + # TypeError: has no from_param method + self.assertRaises(TypeError, setattr, func, "argtypes", (object,)) + + class Adapter(object): + def from_param(cls, obj): + return None + + func.argtypes = (Adapter(),) + self.failUnlessEqual(func(None), None) + self.failUnlessEqual(func(object()), None) + + class Adapter(object): + def from_param(cls, obj): + return obj + + func.argtypes = (Adapter(),) + # don't know how to convert parameter 1 + self.assertRaises(ArgumentError, func, object()) + self.failUnlessEqual(func(c_void_p(42)), 42) + + class Adapter(object): + def from_param(cls, obj): + raise ValueError(obj) + + func.argtypes = (Adapter(),) + # ArgumentError: argument 1: ValueError: 99 + self.assertRaises(ArgumentError, func, 99) + + ################################################################ if __name__ == '__main__': diff --git a/Misc/NEWS b/Misc/NEWS index b3fc3e1..a3e01ea 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -25,6 +25,10 @@ Core and builtins Library ------- +- Patch #1517790: It is now possible to use custom objects in the ctypes + foreign function argtypes sequence as long as they provide a from_param + method, no longer is it required that the object is a ctypes type. + - string.Template() now correctly handles tuple-values. Previously, multi-value tuples would raise an exception and single-value tuples would be treated as the value they contain, instead. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index a36166d..17bb1e8 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -1633,9 +1633,8 @@ converters_from_argtypes(PyObject *ob) for (i = 0; i < nArgs; ++i) { PyObject *tp = PyTuple_GET_ITEM(ob, i); - StgDictObject *dict = PyType_stgdict(tp); PyObject *cnv = PyObject_GetAttrString(tp, "from_param"); - if (!dict || !cnv) + if (!cnv) goto argtypes_error_1; PyTuple_SET_ITEM(converters, i, cnv); } @@ -1646,7 +1645,7 @@ converters_from_argtypes(PyObject *ob) Py_XDECREF(converters); Py_DECREF(ob); PyErr_Format(PyExc_TypeError, - "item %d in _argtypes_ is not a valid C type", i+1); + "item %d in _argtypes_ has no from_param method", i+1); return NULL; } -- cgit v0.12