diff options
Diffstat (limited to 'lib/python2.7/ctypes/test/test_prototypes.py')
-rw-r--r-- | lib/python2.7/ctypes/test/test_prototypes.py | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/lib/python2.7/ctypes/test/test_prototypes.py b/lib/python2.7/ctypes/test/test_prototypes.py new file mode 100644 index 0000000..09ba655 --- /dev/null +++ b/lib/python2.7/ctypes/test/test_prototypes.py @@ -0,0 +1,221 @@ +from ctypes import * +import unittest + +# IMPORTANT INFO: +# +# Consider this call: +# func.restype = c_char_p +# func(c_char_p("123")) +# It returns +# "123" +# +# WHY IS THIS SO? +# +# argument tuple (c_char_p("123"), ) is destroyed after the function +# func is called, but NOT before the result is actually built. +# +# If the arglist would be destroyed BEFORE the result has been built, +# the c_char_p("123") object would already have a zero refcount, +# and the pointer passed to (and returned by) the function would +# probably point to deallocated space. +# +# In this case, there would have to be an additional reference to the argument... + +import _ctypes_test +testdll = CDLL(_ctypes_test.__file__) + +# Return machine address `a` as a (possibly long) non-negative integer. +# Starting with Python 2.5, id(anything) is always non-negative, and +# the ctypes addressof() inherits that via PyLong_FromVoidPtr(). +def positive_address(a): + if a >= 0: + return a + # View the bits in `a` as unsigned instead. + import struct + num_bits = struct.calcsize("P") * 8 # num bits in native machine address + a += 1L << num_bits + assert a >= 0 + return a + +def c_wbuffer(init): + n = len(init) + 1 + return (c_wchar * n)(*init) + +class CharPointersTestCase(unittest.TestCase): + + def setUp(self): + func = testdll._testfunc_p_p + func.restype = c_long + func.argtypes = None + + def test_paramflags(self): + # function returns c_void_p result, + # and has a required parameter named 'input' + prototype = CFUNCTYPE(c_void_p, c_void_p) + func = prototype(("_testfunc_p_p", testdll), + ((1, "input"),)) + + try: + func() + except TypeError, details: + self.assertEqual(str(details), "required argument 'input' missing") + else: + self.fail("TypeError not raised") + + self.assertEqual(func(None), None) + self.assertEqual(func(input=None), None) + + + def test_int_pointer_arg(self): + func = testdll._testfunc_p_p + func.restype = c_long + self.assertEqual(0, func(0)) + + ci = c_int(0) + + func.argtypes = POINTER(c_int), + self.assertEqual(positive_address(addressof(ci)), + positive_address(func(byref(ci)))) + + func.argtypes = c_char_p, + self.assertRaises(ArgumentError, func, byref(ci)) + + func.argtypes = POINTER(c_short), + self.assertRaises(ArgumentError, func, byref(ci)) + + func.argtypes = POINTER(c_double), + self.assertRaises(ArgumentError, func, byref(ci)) + + def test_POINTER_c_char_arg(self): + func = testdll._testfunc_p_p + func.restype = c_char_p + func.argtypes = POINTER(c_char), + + self.assertEqual(None, func(None)) + self.assertEqual("123", func("123")) + self.assertEqual(None, func(c_char_p(None))) + self.assertEqual("123", func(c_char_p("123"))) + + self.assertEqual("123", func(c_buffer("123"))) + ca = c_char("a") + self.assertEqual("a", func(pointer(ca))[0]) + self.assertEqual("a", func(byref(ca))[0]) + + def test_c_char_p_arg(self): + func = testdll._testfunc_p_p + func.restype = c_char_p + func.argtypes = c_char_p, + + self.assertEqual(None, func(None)) + self.assertEqual("123", func("123")) + self.assertEqual(None, func(c_char_p(None))) + self.assertEqual("123", func(c_char_p("123"))) + + self.assertEqual("123", func(c_buffer("123"))) + ca = c_char("a") + self.assertEqual("a", func(pointer(ca))[0]) + self.assertEqual("a", func(byref(ca))[0]) + + def test_c_void_p_arg(self): + func = testdll._testfunc_p_p + func.restype = c_char_p + func.argtypes = c_void_p, + + self.assertEqual(None, func(None)) + self.assertEqual("123", func("123")) + self.assertEqual("123", func(c_char_p("123"))) + self.assertEqual(None, func(c_char_p(None))) + + self.assertEqual("123", func(c_buffer("123"))) + ca = c_char("a") + self.assertEqual("a", func(pointer(ca))[0]) + self.assertEqual("a", func(byref(ca))[0]) + + func(byref(c_int())) + func(pointer(c_int())) + func((c_int * 3)()) + + try: + func.restype = c_wchar_p + except NameError: + pass + else: + self.assertEqual(None, func(c_wchar_p(None))) + self.assertEqual(u"123", func(c_wchar_p(u"123"))) + + def test_instance(self): + func = testdll._testfunc_p_p + func.restype = c_void_p + + class X: + _as_parameter_ = None + + func.argtypes = c_void_p, + self.assertEqual(None, func(X())) + + func.argtypes = None + self.assertEqual(None, func(X())) + +try: + c_wchar +except NameError: + pass +else: + class WCharPointersTestCase(unittest.TestCase): + + def setUp(self): + func = testdll._testfunc_p_p + func.restype = c_int + func.argtypes = None + + + def test_POINTER_c_wchar_arg(self): + func = testdll._testfunc_p_p + func.restype = c_wchar_p + func.argtypes = POINTER(c_wchar), + + self.assertEqual(None, func(None)) + self.assertEqual(u"123", func(u"123")) + self.assertEqual(None, func(c_wchar_p(None))) + self.assertEqual(u"123", func(c_wchar_p(u"123"))) + + self.assertEqual(u"123", func(c_wbuffer(u"123"))) + ca = c_wchar("a") + self.assertEqual(u"a", func(pointer(ca))[0]) + self.assertEqual(u"a", func(byref(ca))[0]) + + def test_c_wchar_p_arg(self): + func = testdll._testfunc_p_p + func.restype = c_wchar_p + func.argtypes = c_wchar_p, + + c_wchar_p.from_param(u"123") + + self.assertEqual(None, func(None)) + self.assertEqual("123", func(u"123")) + self.assertEqual(None, func(c_wchar_p(None))) + self.assertEqual("123", func(c_wchar_p("123"))) + + # XXX Currently, these raise TypeErrors, although they shouldn't: + self.assertEqual("123", func(c_wbuffer("123"))) + ca = c_wchar("a") + self.assertEqual("a", func(pointer(ca))[0]) + self.assertEqual("a", func(byref(ca))[0]) + +class ArrayTest(unittest.TestCase): + def test(self): + func = testdll._testfunc_ai8 + func.restype = POINTER(c_int) + func.argtypes = c_int * 8, + + func((c_int * 8)(1, 2, 3, 4, 5, 6, 7, 8)) + + # This did crash before: + + def func(): pass + CFUNCTYPE(None, c_int * 3)(func) + +################################################################ + +if __name__ == '__main__': + unittest.main() |