blob: 9537400e62787b56c8385554eb598d7748073958 [file] [log] [blame]
Thomas Hellerbabddfc2006-03-08 19:56:54 +00001import unittest, sys
2
3class SimpleTypesTestCase(unittest.TestCase):
4
5 def setUp(self):
6 import ctypes
7 try:
8 from _ctypes import set_conversion_mode
9 except ImportError:
10 pass
11 else:
12 self.prev_conv_mode = set_conversion_mode("ascii", "strict")
13
14 def tearDown(self):
15 try:
16 from _ctypes import set_conversion_mode
17 except ImportError:
18 pass
19 else:
20 set_conversion_mode(*self.prev_conv_mode)
Tim Peterse8d09e52006-03-09 01:15:05 +000021
Thomas Hellerbabddfc2006-03-08 19:56:54 +000022
23 def test_subclasses(self):
24 from ctypes import c_void_p, c_char_p
25 # ctypes 0.9.5 and before did overwrite from_param in SimpleType_new
26 class CVOIDP(c_void_p):
27 def from_param(cls, value):
28 return value * 2
29 from_param = classmethod(from_param)
30
31 class CCHARP(c_char_p):
32 def from_param(cls, value):
33 return value * 4
34 from_param = classmethod(from_param)
35
36 self.failUnlessEqual(CVOIDP.from_param("abc"), "abcabc")
37 self.failUnlessEqual(CCHARP.from_param("abc"), "abcabcabcabc")
38
39 try:
40 from ctypes import c_wchar_p
41 except ImportError:
42 return
43
44 class CWCHARP(c_wchar_p):
45 def from_param(cls, value):
46 return value * 3
47 from_param = classmethod(from_param)
48
49 self.failUnlessEqual(CWCHARP.from_param("abc"), "abcabcabc")
50
51 # XXX Replace by c_char_p tests
52 def test_cstrings(self):
53 from ctypes import c_char_p, byref
54
55 # c_char_p.from_param on a Python String packs the string
56 # into a cparam object
57 s = "123"
58 self.failUnless(c_char_p.from_param(s)._obj is s)
59
60 # new in 0.9.1: convert (encode) unicode to ascii
61 self.failUnlessEqual(c_char_p.from_param(u"123")._obj, "123")
62 self.assertRaises(UnicodeEncodeError, c_char_p.from_param, u"123\377")
63
64 self.assertRaises(TypeError, c_char_p.from_param, 42)
65
66 # calling c_char_p.from_param with a c_char_p instance
67 # returns the argument itself:
68 a = c_char_p("123")
69 self.failUnless(c_char_p.from_param(a) is a)
70
71 def test_cw_strings(self):
72 from ctypes import byref
73 try:
74 from ctypes import c_wchar_p
75 except ImportError:
76## print "(No c_wchar_p)"
77 return
78 s = u"123"
79 if sys.platform == "win32":
80 self.failUnless(c_wchar_p.from_param(s)._obj is s)
81 self.assertRaises(TypeError, c_wchar_p.from_param, 42)
82
83 # new in 0.9.1: convert (decode) ascii to unicode
84 self.failUnlessEqual(c_wchar_p.from_param("123")._obj, u"123")
85 self.assertRaises(UnicodeDecodeError, c_wchar_p.from_param, "123\377")
86
87 pa = c_wchar_p.from_param(c_wchar_p(u"123"))
88 self.failUnlessEqual(type(pa), c_wchar_p)
89
90 def test_int_pointers(self):
91 from ctypes import c_short, c_uint, c_int, c_long, POINTER, pointer
92 LPINT = POINTER(c_int)
93
94## p = pointer(c_int(42))
95## x = LPINT.from_param(p)
96 x = LPINT.from_param(pointer(c_int(42)))
97 self.failUnlessEqual(x.contents.value, 42)
98 self.failUnlessEqual(LPINT(c_int(42)).contents.value, 42)
99
100 self.failUnlessEqual(LPINT.from_param(None), 0)
101
102 if c_int != c_long:
103 self.assertRaises(TypeError, LPINT.from_param, pointer(c_long(42)))
104 self.assertRaises(TypeError, LPINT.from_param, pointer(c_uint(42)))
105 self.assertRaises(TypeError, LPINT.from_param, pointer(c_short(42)))
106
107 def test_byref_pointer(self):
108 # The from_param class method of POINTER(typ) classes accepts what is
109 # returned by byref(obj), it type(obj) == typ
110 from ctypes import c_short, c_uint, c_int, c_long, pointer, POINTER, byref
111 LPINT = POINTER(c_int)
112
113 LPINT.from_param(byref(c_int(42)))
114
115 self.assertRaises(TypeError, LPINT.from_param, byref(c_short(22)))
116 if c_int != c_long:
117 self.assertRaises(TypeError, LPINT.from_param, byref(c_long(22)))
118 self.assertRaises(TypeError, LPINT.from_param, byref(c_uint(22)))
119
120 def test_byref_pointerpointer(self):
121 # See above
122 from ctypes import c_short, c_uint, c_int, c_long, pointer, POINTER, byref
123
124 LPLPINT = POINTER(POINTER(c_int))
125 LPLPINT.from_param(byref(pointer(c_int(42))))
126
127 self.assertRaises(TypeError, LPLPINT.from_param, byref(pointer(c_short(22))))
128 if c_int != c_long:
129 self.assertRaises(TypeError, LPLPINT.from_param, byref(pointer(c_long(22))))
130 self.assertRaises(TypeError, LPLPINT.from_param, byref(pointer(c_uint(22))))
131
132 def test_array_pointers(self):
133 from ctypes import c_short, c_uint, c_int, c_long, POINTER
134 INTARRAY = c_int * 3
135 ia = INTARRAY()
136 self.failUnlessEqual(len(ia), 3)
137 self.failUnlessEqual([ia[i] for i in range(3)], [0, 0, 0])
138
139 # Pointers are only compatible with arrays containing items of
140 # the same type!
141 LPINT = POINTER(c_int)
142 LPINT.from_param((c_int*3)())
143 self.assertRaises(TypeError, LPINT.from_param, c_short*3)
144 self.assertRaises(TypeError, LPINT.from_param, c_long*3)
145 self.assertRaises(TypeError, LPINT.from_param, c_uint*3)
146
147## def test_performance(self):
148## check_perf()
149
150################################################################
151
152if __name__ == '__main__':
153 unittest.main()