PageRenderTime 23ms CodeModel.GetById 10ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/Lib/ctypes/test/test_parameters.py

http://unladen-swallow.googlecode.com/
Python | 188 lines | 124 code | 42 blank | 22 comment | 7 complexity | 308159aac0b3af90ca8be5d32c20d8a1 MD5 | raw file
  1import 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)
 21
 22
 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.assertEqual(LPINT.from_param(None), None)
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    def test_noctypes_argtype(self):
151        import _ctypes_test
152        from ctypes import CDLL, c_void_p, ArgumentError
153
154        func = CDLL(_ctypes_test.__file__)._testfunc_p_p
155        func.restype = c_void_p
156        # TypeError: has no from_param method
157        self.assertRaises(TypeError, setattr, func, "argtypes", (object,))
158
159        class Adapter(object):
160            def from_param(cls, obj):
161                return None
162
163        func.argtypes = (Adapter(),)
164        self.failUnlessEqual(func(None), None)
165        self.failUnlessEqual(func(object()), None)
166
167        class Adapter(object):
168            def from_param(cls, obj):
169                return obj
170
171        func.argtypes = (Adapter(),)
172        # don't know how to convert parameter 1
173        self.assertRaises(ArgumentError, func, object())
174        self.failUnlessEqual(func(c_void_p(42)), 42)
175
176        class Adapter(object):
177            def from_param(cls, obj):
178                raise ValueError(obj)
179
180        func.argtypes = (Adapter(),)
181        # ArgumentError: argument 1: ValueError: 99
182        self.assertRaises(ArgumentError, func, 99)
183
184
185################################################################
186
187if __name__ == '__main__':
188    unittest.main()