]> granicus.if.org Git - python/commitdiff
Patch #1517790: It is now possible to use custom objects in the ctypes
authorThomas Heller <theller@ctypes.org>
Thu, 6 Jul 2006 08:48:35 +0000 (08:48 +0000)
committerThomas Heller <theller@ctypes.org>
Thu, 6 Jul 2006 08:48:35 +0000 (08:48 +0000)
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
Misc/NEWS
Modules/_ctypes/_ctypes.c

index 9537400e62787b56c8385554eb598d7748073958..1b7f0dc86b464cead82bfdb4fbf894b7a29eac5e 100644 (file)
@@ -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__':
index b3fc3e1c36cfbc01c2a4cb3e39e9b1d73eea2579..a3e01ea1abcc72d4ecb48e14e4ab667de16266a6 100644 (file)
--- 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.
index a36166db71359b46593848c196c6372e26a98f3a..17bb1e830983a710696d6e3135f7d4b6fa9170c3 100644 (file)
@@ -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;
 }