• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import unittest
2from ctypes import *
3from ctypes.test import need_symbol
4
5import _ctypes_test
6
7class SlicesTestCase(unittest.TestCase):
8    def test_getslice_cint(self):
9        a = (c_int * 100)(*range(1100, 1200))
10        b = list(range(1100, 1200))
11        self.assertEqual(a[0:2], b[0:2])
12        self.assertEqual(a[0:2:], b[0:2:])
13        self.assertEqual(len(a), len(b))
14        self.assertEqual(a[5:7], b[5:7])
15        self.assertEqual(a[5:7:], b[5:7:])
16        self.assertEqual(a[-1], b[-1])
17        self.assertEqual(a[:], b[:])
18        self.assertEqual(a[::], b[::])
19        self.assertEqual(a[10::-1], b[10::-1])
20        self.assertEqual(a[30:20:-1], b[30:20:-1])
21        self.assertEqual(a[:12:6], b[:12:6])
22        self.assertEqual(a[2:6:4], b[2:6:4])
23
24        a[0:5] = range(5, 10)
25        self.assertEqual(a[0:5], list(range(5, 10)))
26        self.assertEqual(a[0:5:], list(range(5, 10)))
27        self.assertEqual(a[4::-1], list(range(9, 4, -1)))
28
29    def test_setslice_cint(self):
30        a = (c_int * 100)(*range(1100, 1200))
31        b = list(range(1100, 1200))
32
33        a[32:47] = list(range(32, 47))
34        self.assertEqual(a[32:47], list(range(32, 47)))
35        a[32:47] = range(132, 147)
36        self.assertEqual(a[32:47:], list(range(132, 147)))
37        a[46:31:-1] = range(232, 247)
38        self.assertEqual(a[32:47:1], list(range(246, 231, -1)))
39
40        a[32:47] = range(1132, 1147)
41        self.assertEqual(a[:], b)
42        a[32:47:7] = range(3)
43        b[32:47:7] = range(3)
44        self.assertEqual(a[:], b)
45        a[33::-3] = range(12)
46        b[33::-3] = range(12)
47        self.assertEqual(a[:], b)
48
49        from operator import setitem
50
51        # TypeError: int expected instead of str instance
52        self.assertRaises(TypeError, setitem, a, slice(0, 5), "abcde")
53        # TypeError: int expected instead of str instance
54        self.assertRaises(TypeError, setitem, a, slice(0, 5),
55                          ["a", "b", "c", "d", "e"])
56        # TypeError: int expected instead of float instance
57        self.assertRaises(TypeError, setitem, a, slice(0, 5),
58                          [1, 2, 3, 4, 3.14])
59        # ValueError: Can only assign sequence of same size
60        self.assertRaises(ValueError, setitem, a, slice(0, 5), range(32))
61
62    def test_char_ptr(self):
63        s = b"abcdefghijklmnopqrstuvwxyz"
64
65        dll = CDLL(_ctypes_test.__file__)
66        dll.my_strdup.restype = POINTER(c_char)
67        dll.my_free.restype = None
68        res = dll.my_strdup(s)
69        self.assertEqual(res[:len(s)], s)
70        self.assertEqual(res[:3], s[:3])
71        self.assertEqual(res[:len(s):], s)
72        self.assertEqual(res[len(s)-1:-1:-1], s[::-1])
73        self.assertEqual(res[len(s)-1:5:-7], s[:5:-7])
74        self.assertEqual(res[0:-1:-1], s[0::-1])
75
76        import operator
77        self.assertRaises(ValueError, operator.getitem,
78                          res, slice(None, None, None))
79        self.assertRaises(ValueError, operator.getitem,
80                          res, slice(0, None, None))
81        self.assertRaises(ValueError, operator.getitem,
82                          res, slice(None, 5, -1))
83        self.assertRaises(ValueError, operator.getitem,
84                          res, slice(-5, None, None))
85
86        self.assertRaises(TypeError, operator.setitem,
87                          res, slice(0, 5), "abcde")
88        dll.my_free(res)
89
90        dll.my_strdup.restype = POINTER(c_byte)
91        res = dll.my_strdup(s)
92        self.assertEqual(res[:len(s)], list(range(ord("a"), ord("z")+1)))
93        self.assertEqual(res[:len(s):], list(range(ord("a"), ord("z")+1)))
94        dll.my_free(res)
95
96    def test_char_ptr_with_free(self):
97        dll = CDLL(_ctypes_test.__file__)
98        s = b"abcdefghijklmnopqrstuvwxyz"
99
100        class allocated_c_char_p(c_char_p):
101            pass
102
103        dll.my_free.restype = None
104        def errcheck(result, func, args):
105            retval = result.value
106            dll.my_free(result)
107            return retval
108
109        dll.my_strdup.restype = allocated_c_char_p
110        dll.my_strdup.errcheck = errcheck
111        try:
112            res = dll.my_strdup(s)
113            self.assertEqual(res, s)
114        finally:
115            del dll.my_strdup.errcheck
116
117
118    def test_char_array(self):
119        s = b"abcdefghijklmnopqrstuvwxyz\0"
120
121        p = (c_char * 27)(*s)
122        self.assertEqual(p[:], s)
123        self.assertEqual(p[::], s)
124        self.assertEqual(p[::-1], s[::-1])
125        self.assertEqual(p[5::-2], s[5::-2])
126        self.assertEqual(p[2:5:-3], s[2:5:-3])
127
128
129    @need_symbol('c_wchar')
130    def test_wchar_ptr(self):
131        s = "abcdefghijklmnopqrstuvwxyz\0"
132
133        dll = CDLL(_ctypes_test.__file__)
134        dll.my_wcsdup.restype = POINTER(c_wchar)
135        dll.my_wcsdup.argtypes = POINTER(c_wchar),
136        dll.my_free.restype = None
137        res = dll.my_wcsdup(s[:-1])
138        self.assertEqual(res[:len(s)], s)
139        self.assertEqual(res[:len(s):], s)
140        self.assertEqual(res[len(s)-1:-1:-1], s[::-1])
141        self.assertEqual(res[len(s)-1:5:-7], s[:5:-7])
142
143        import operator
144        self.assertRaises(TypeError, operator.setitem,
145                          res, slice(0, 5), "abcde")
146        dll.my_free(res)
147
148        if sizeof(c_wchar) == sizeof(c_short):
149            dll.my_wcsdup.restype = POINTER(c_short)
150        elif sizeof(c_wchar) == sizeof(c_int):
151            dll.my_wcsdup.restype = POINTER(c_int)
152        elif sizeof(c_wchar) == sizeof(c_long):
153            dll.my_wcsdup.restype = POINTER(c_long)
154        else:
155            self.skipTest('Pointers to c_wchar are not supported')
156        res = dll.my_wcsdup(s[:-1])
157        tmpl = list(range(ord("a"), ord("z")+1))
158        self.assertEqual(res[:len(s)-1], tmpl)
159        self.assertEqual(res[:len(s)-1:], tmpl)
160        self.assertEqual(res[len(s)-2:-1:-1], tmpl[::-1])
161        self.assertEqual(res[len(s)-2:5:-7], tmpl[:5:-7])
162        dll.my_free(res)
163
164################################################################
165
166if __name__ == "__main__":
167    unittest.main()
168