summaryrefslogtreecommitdiff
path: root/Lib/ctypes/test/test_prototypes.py
diff options
context:
space:
mode:
authorThomas Heller <theller@ctypes.org>2006-03-08 19:56:54 +0000
committerThomas Heller <theller@ctypes.org>2006-03-08 19:56:54 +0000
commitce77365783e28c237556b16ce06171b685fc1b52 (patch)
treebd992e86d39c6deaa90699ac4dfc2601fb54a285 /Lib/ctypes/test/test_prototypes.py
parent0c76198ac5e921e5c289bcedb04b898e6d2eeb45 (diff)
downloadcpython-ce77365783e28c237556b16ce06171b685fc1b52.tar.gz
Copy ctypes-0.9.9.4 Python modules from external into the trunk.
Diffstat (limited to 'Lib/ctypes/test/test_prototypes.py')
-rw-r--r--Lib/ctypes/test/test_prototypes.py184
1 files changed, 184 insertions, 0 deletions
diff --git a/Lib/ctypes/test/test_prototypes.py b/Lib/ctypes/test/test_prototypes.py
new file mode 100644
index 0000000000..ffb113bd76
--- /dev/null
+++ b/Lib/ctypes/test/test_prototypes.py
@@ -0,0 +1,184 @@
+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.load(_ctypes_test.__file__)
+
+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_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(addressof(ci), 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
+
+## class X:
+## _as_parameter_ = 0
+
+## self.failUnlessEqual(0, 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()