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.
This commit is contained in:
parent
2329b64c20
commit
5becdbee96
|
@ -147,6 +147,41 @@ class SimpleTypesTestCase(unittest.TestCase):
|
||||||
## def test_performance(self):
|
## def test_performance(self):
|
||||||
## check_perf()
|
## 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__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -25,6 +25,10 @@ Core and builtins
|
||||||
Library
|
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,
|
- string.Template() now correctly handles tuple-values. Previously,
|
||||||
multi-value tuples would raise an exception and single-value tuples would
|
multi-value tuples would raise an exception and single-value tuples would
|
||||||
be treated as the value they contain, instead.
|
be treated as the value they contain, instead.
|
||||||
|
|
|
@ -1633,9 +1633,8 @@ converters_from_argtypes(PyObject *ob)
|
||||||
|
|
||||||
for (i = 0; i < nArgs; ++i) {
|
for (i = 0; i < nArgs; ++i) {
|
||||||
PyObject *tp = PyTuple_GET_ITEM(ob, i);
|
PyObject *tp = PyTuple_GET_ITEM(ob, i);
|
||||||
StgDictObject *dict = PyType_stgdict(tp);
|
|
||||||
PyObject *cnv = PyObject_GetAttrString(tp, "from_param");
|
PyObject *cnv = PyObject_GetAttrString(tp, "from_param");
|
||||||
if (!dict || !cnv)
|
if (!cnv)
|
||||||
goto argtypes_error_1;
|
goto argtypes_error_1;
|
||||||
PyTuple_SET_ITEM(converters, i, cnv);
|
PyTuple_SET_ITEM(converters, i, cnv);
|
||||||
}
|
}
|
||||||
|
@ -1646,7 +1645,7 @@ converters_from_argtypes(PyObject *ob)
|
||||||
Py_XDECREF(converters);
|
Py_XDECREF(converters);
|
||||||
Py_DECREF(ob);
|
Py_DECREF(ob);
|
||||||
PyErr_Format(PyExc_TypeError,
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue