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