1 # coding: latin-1 2 import unittest 3 import ctypes 4 5 try: 6 ctypes.c_wchar 7 except AttributeError: 8 pass 9 else: 10 import _ctypes_test 11 dll = ctypes.CDLL(_ctypes_test.__file__) 12 wcslen = dll.my_wcslen 13 wcslen.argtypes = [ctypes.c_wchar_p] 14 15 16 class UnicodeTestCase(unittest.TestCase): 17 def setUp(self): 18 self.prev_conv_mode = ctypes.set_conversion_mode("ascii", "strict") 19 20 def tearDown(self): 21 ctypes.set_conversion_mode(*self.prev_conv_mode) 22 23 def test_ascii_strict(self): 24 ctypes.set_conversion_mode("ascii", "strict") 25 # no conversions take place with unicode arguments 26 self.assertEqual(wcslen(u"abc"), 3) 27 self.assertEqual(wcslen(u"ab\u2070"), 3) 28 # string args are converted 29 self.assertEqual(wcslen("abc"), 3) 30 self.assertRaises(ctypes.ArgumentError, wcslen, "ab") 31 32 def test_ascii_replace(self): 33 ctypes.set_conversion_mode("ascii", "replace") 34 self.assertEqual(wcslen(u"abc"), 3) 35 self.assertEqual(wcslen(u"ab\u2070"), 3) 36 self.assertEqual(wcslen("abc"), 3) 37 self.assertEqual(wcslen("ab"), 3) 38 39 def test_ascii_ignore(self): 40 ctypes.set_conversion_mode("ascii", "ignore") 41 self.assertEqual(wcslen(u"abc"), 3) 42 self.assertEqual(wcslen(u"ab\u2070"), 3) 43 # ignore error mode skips non-ascii characters 44 self.assertEqual(wcslen("abc"), 3) 45 self.assertEqual(wcslen(""), 0) 46 47 def test_latin1_strict(self): 48 ctypes.set_conversion_mode("latin-1", "strict") 49 self.assertEqual(wcslen(u"abc"), 3) 50 self.assertEqual(wcslen(u"ab\u2070"), 3) 51 self.assertEqual(wcslen("abc"), 3) 52 self.assertEqual(wcslen(""), 4) 53 54 def test_buffers(self): 55 ctypes.set_conversion_mode("ascii", "strict") 56 buf = ctypes.create_unicode_buffer("abc") 57 self.assertEqual(len(buf), 3+1) 58 59 ctypes.set_conversion_mode("ascii", "replace") 60 buf = ctypes.create_unicode_buffer("ab") 61 self.assertEqual(buf[:], u"ab\uFFFD\uFFFD\uFFFD\0") 62 self.assertEqual(buf[::], u"ab\uFFFD\uFFFD\uFFFD\0") 63 self.assertEqual(buf[::-1], u"\0\uFFFD\uFFFD\uFFFDba") 64 self.assertEqual(buf[::2], u"a\uFFFD\uFFFD") 65 self.assertEqual(buf[6:5:-1], u"") 66 67 ctypes.set_conversion_mode("ascii", "ignore") 68 buf = ctypes.create_unicode_buffer("ab") 69 # is that correct? not sure. But with 'ignore', you get what you pay for.. 70 self.assertEqual(buf[:], u"ab\0\0\0\0") 71 self.assertEqual(buf[::], u"ab\0\0\0\0") 72 self.assertEqual(buf[::-1], u"\0\0\0\0ba") 73 self.assertEqual(buf[::2], u"a\0\0") 74 self.assertEqual(buf[6:5:-1], u"") 75 76 import _ctypes_test 77 func = ctypes.CDLL(_ctypes_test.__file__)._testfunc_p_p 78 79 class StringTestCase(UnicodeTestCase): 80 def setUp(self): 81 self.prev_conv_mode = ctypes.set_conversion_mode("ascii", "strict") 82 func.argtypes = [ctypes.c_char_p] 83 func.restype = ctypes.c_char_p 84 85 def tearDown(self): 86 ctypes.set_conversion_mode(*self.prev_conv_mode) 87 func.argtypes = None 88 func.restype = ctypes.c_int 89 90 def test_ascii_replace(self): 91 ctypes.set_conversion_mode("ascii", "strict") 92 self.assertEqual(func("abc"), "abc") 93 self.assertEqual(func(u"abc"), "abc") 94 self.assertRaises(ctypes.ArgumentError, func, u"ab") 95 96 def test_ascii_ignore(self): 97 ctypes.set_conversion_mode("ascii", "ignore") 98 self.assertEqual(func("abc"), "abc") 99 self.assertEqual(func(u"abc"), "abc") 100 self.assertEqual(func(u""), "") 101 102 def test_ascii_replace(self): 103 ctypes.set_conversion_mode("ascii", "replace") 104 self.assertEqual(func("abc"), "abc") 105 self.assertEqual(func(u"abc"), "abc") 106 self.assertEqual(func(u""), "????") 107 108 def test_buffers(self): 109 ctypes.set_conversion_mode("ascii", "strict") 110 buf = ctypes.create_string_buffer(u"abc") 111 self.assertEqual(len(buf), 3+1) 112 113 ctypes.set_conversion_mode("ascii", "replace") 114 buf = ctypes.create_string_buffer(u"ab") 115 self.assertEqual(buf[:], "ab???\0") 116 self.assertEqual(buf[::], "ab???\0") 117 self.assertEqual(buf[::-1], "\0???ba") 118 self.assertEqual(buf[::2], "a??") 119 self.assertEqual(buf[6:5:-1], "") 120 121 ctypes.set_conversion_mode("ascii", "ignore") 122 buf = ctypes.create_string_buffer(u"ab") 123 # is that correct? not sure. But with 'ignore', you get what you pay for.. 124 self.assertEqual(buf[:], "ab\0\0\0\0") 125 self.assertEqual(buf[::], "ab\0\0\0\0") 126 self.assertEqual(buf[::-1], "\0\0\0\0ba") 127 128 if __name__ == '__main__': 129 unittest.main() 130