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