/Lib/ctypes/test/test_parameters.py
http://unladen-swallow.googlecode.com/ · Python · 188 lines · 124 code · 42 blank · 22 comment · 16 complexity · 308159aac0b3af90ca8be5d32c20d8a1 MD5 · raw file
- import unittest, sys
- class SimpleTypesTestCase(unittest.TestCase):
- def setUp(self):
- import ctypes
- try:
- from _ctypes import set_conversion_mode
- except ImportError:
- pass
- else:
- self.prev_conv_mode = set_conversion_mode("ascii", "strict")
- def tearDown(self):
- try:
- from _ctypes import set_conversion_mode
- except ImportError:
- pass
- else:
- set_conversion_mode(*self.prev_conv_mode)
- def test_subclasses(self):
- from ctypes import c_void_p, c_char_p
- # ctypes 0.9.5 and before did overwrite from_param in SimpleType_new
- class CVOIDP(c_void_p):
- def from_param(cls, value):
- return value * 2
- from_param = classmethod(from_param)
- class CCHARP(c_char_p):
- def from_param(cls, value):
- return value * 4
- from_param = classmethod(from_param)
- self.failUnlessEqual(CVOIDP.from_param("abc"), "abcabc")
- self.failUnlessEqual(CCHARP.from_param("abc"), "abcabcabcabc")
- try:
- from ctypes import c_wchar_p
- except ImportError:
- return
- class CWCHARP(c_wchar_p):
- def from_param(cls, value):
- return value * 3
- from_param = classmethod(from_param)
- self.failUnlessEqual(CWCHARP.from_param("abc"), "abcabcabc")
- # XXX Replace by c_char_p tests
- def test_cstrings(self):
- from ctypes import c_char_p, byref
- # c_char_p.from_param on a Python String packs the string
- # into a cparam object
- s = "123"
- self.failUnless(c_char_p.from_param(s)._obj is s)
- # new in 0.9.1: convert (encode) unicode to ascii
- self.failUnlessEqual(c_char_p.from_param(u"123")._obj, "123")
- self.assertRaises(UnicodeEncodeError, c_char_p.from_param, u"123\377")
- self.assertRaises(TypeError, c_char_p.from_param, 42)
- # calling c_char_p.from_param with a c_char_p instance
- # returns the argument itself:
- a = c_char_p("123")
- self.failUnless(c_char_p.from_param(a) is a)
- def test_cw_strings(self):
- from ctypes import byref
- try:
- from ctypes import c_wchar_p
- except ImportError:
- ## print "(No c_wchar_p)"
- return
- s = u"123"
- if sys.platform == "win32":
- self.failUnless(c_wchar_p.from_param(s)._obj is s)
- self.assertRaises(TypeError, c_wchar_p.from_param, 42)
- # new in 0.9.1: convert (decode) ascii to unicode
- self.failUnlessEqual(c_wchar_p.from_param("123")._obj, u"123")
- self.assertRaises(UnicodeDecodeError, c_wchar_p.from_param, "123\377")
- pa = c_wchar_p.from_param(c_wchar_p(u"123"))
- self.failUnlessEqual(type(pa), c_wchar_p)
- def test_int_pointers(self):
- from ctypes import c_short, c_uint, c_int, c_long, POINTER, pointer
- LPINT = POINTER(c_int)
- ## p = pointer(c_int(42))
- ## x = LPINT.from_param(p)
- x = LPINT.from_param(pointer(c_int(42)))
- self.failUnlessEqual(x.contents.value, 42)
- self.failUnlessEqual(LPINT(c_int(42)).contents.value, 42)
- self.assertEqual(LPINT.from_param(None), None)
- if c_int != c_long:
- self.assertRaises(TypeError, LPINT.from_param, pointer(c_long(42)))
- self.assertRaises(TypeError, LPINT.from_param, pointer(c_uint(42)))
- self.assertRaises(TypeError, LPINT.from_param, pointer(c_short(42)))
- def test_byref_pointer(self):
- # The from_param class method of POINTER(typ) classes accepts what is
- # returned by byref(obj), it type(obj) == typ
- from ctypes import c_short, c_uint, c_int, c_long, pointer, POINTER, byref
- LPINT = POINTER(c_int)
- LPINT.from_param(byref(c_int(42)))
- self.assertRaises(TypeError, LPINT.from_param, byref(c_short(22)))
- if c_int != c_long:
- self.assertRaises(TypeError, LPINT.from_param, byref(c_long(22)))
- self.assertRaises(TypeError, LPINT.from_param, byref(c_uint(22)))
- def test_byref_pointerpointer(self):
- # See above
- from ctypes import c_short, c_uint, c_int, c_long, pointer, POINTER, byref
- LPLPINT = POINTER(POINTER(c_int))
- LPLPINT.from_param(byref(pointer(c_int(42))))
- self.assertRaises(TypeError, LPLPINT.from_param, byref(pointer(c_short(22))))
- if c_int != c_long:
- self.assertRaises(TypeError, LPLPINT.from_param, byref(pointer(c_long(22))))
- self.assertRaises(TypeError, LPLPINT.from_param, byref(pointer(c_uint(22))))
- def test_array_pointers(self):
- from ctypes import c_short, c_uint, c_int, c_long, POINTER
- INTARRAY = c_int * 3
- ia = INTARRAY()
- self.failUnlessEqual(len(ia), 3)
- self.failUnlessEqual([ia[i] for i in range(3)], [0, 0, 0])
- # Pointers are only compatible with arrays containing items of
- # the same type!
- LPINT = POINTER(c_int)
- LPINT.from_param((c_int*3)())
- self.assertRaises(TypeError, LPINT.from_param, c_short*3)
- self.assertRaises(TypeError, LPINT.from_param, c_long*3)
- self.assertRaises(TypeError, LPINT.from_param, c_uint*3)
- ## def test_performance(self):
- ## check_perf()
- def test_noctypes_argtype(self):
- import _ctypes_test
- from ctypes import CDLL, c_void_p, ArgumentError
- func = CDLL(_ctypes_test.__file__)._testfunc_p_p
- func.restype = c_void_p
- # TypeError: has no from_param method
- self.assertRaises(TypeError, setattr, func, "argtypes", (object,))
- class Adapter(object):
- def from_param(cls, obj):
- return None
- func.argtypes = (Adapter(),)
- self.failUnlessEqual(func(None), None)
- self.failUnlessEqual(func(object()), None)
- class Adapter(object):
- def from_param(cls, obj):
- return obj
- func.argtypes = (Adapter(),)
- # don't know how to convert parameter 1
- self.assertRaises(ArgumentError, func, object())
- self.failUnlessEqual(func(c_void_p(42)), 42)
- class Adapter(object):
- def from_param(cls, obj):
- raise ValueError(obj)
- func.argtypes = (Adapter(),)
- # ArgumentError: argument 1: ValueError: 99
- self.assertRaises(ArgumentError, func, 99)
- ################################################################
- if __name__ == '__main__':
- unittest.main()