/Lib/ctypes/test/test_prototypes.py
http://unladen-swallow.googlecode.com/ · Python · 221 lines · 146 code · 47 blank · 28 comment · 11 complexity · 42652a9e5466dc7208b096e86da1953e MD5 · raw file
- 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.failUnlessEqual(str(details), "required argument 'input' missing")
- else:
- self.fail("TypeError not raised")
- self.failUnlessEqual(func(None), None)
- self.failUnlessEqual(func(input=None), None)
- def test_int_pointer_arg(self):
- func = testdll._testfunc_p_p
- func.restype = c_long
- self.failUnlessEqual(0, func(0))
- ci = c_int(0)
- func.argtypes = POINTER(c_int),
- self.failUnlessEqual(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.failUnlessEqual(None, func(None))
- self.failUnlessEqual("123", func("123"))
- self.failUnlessEqual(None, func(c_char_p(None)))
- self.failUnlessEqual("123", func(c_char_p("123")))
- self.failUnlessEqual("123", func(c_buffer("123")))
- ca = c_char("a")
- self.failUnlessEqual("a", func(pointer(ca))[0])
- self.failUnlessEqual("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.failUnlessEqual(None, func(None))
- self.failUnlessEqual("123", func("123"))
- self.failUnlessEqual(None, func(c_char_p(None)))
- self.failUnlessEqual("123", func(c_char_p("123")))
- self.failUnlessEqual("123", func(c_buffer("123")))
- ca = c_char("a")
- self.failUnlessEqual("a", func(pointer(ca))[0])
- self.failUnlessEqual("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.failUnlessEqual(None, func(None))
- self.failUnlessEqual("123", func("123"))
- self.failUnlessEqual("123", func(c_char_p("123")))
- self.failUnlessEqual(None, func(c_char_p(None)))
- self.failUnlessEqual("123", func(c_buffer("123")))
- ca = c_char("a")
- self.failUnlessEqual("a", func(pointer(ca))[0])
- self.failUnlessEqual("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.failUnlessEqual(None, func(c_wchar_p(None)))
- self.failUnlessEqual(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.failUnlessEqual(None, func(X()))
- func.argtypes = None
- self.failUnlessEqual(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.failUnlessEqual(None, func(None))
- self.failUnlessEqual(u"123", func(u"123"))
- self.failUnlessEqual(None, func(c_wchar_p(None)))
- self.failUnlessEqual(u"123", func(c_wchar_p(u"123")))
- self.failUnlessEqual(u"123", func(c_wbuffer(u"123")))
- ca = c_wchar("a")
- self.failUnlessEqual(u"a", func(pointer(ca))[0])
- self.failUnlessEqual(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.failUnlessEqual(None, func(None))
- self.failUnlessEqual("123", func(u"123"))
- self.failUnlessEqual(None, func(c_wchar_p(None)))
- self.failUnlessEqual("123", func(c_wchar_p("123")))
- # XXX Currently, these raise TypeErrors, although they shouldn't:
- self.failUnlessEqual("123", func(c_wbuffer("123")))
- ca = c_wchar("a")
- self.failUnlessEqual("a", func(pointer(ca))[0])
- self.failUnlessEqual("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()