1 import unittest 2 from ctypes import * 3 4 from ctypes.test import need_symbol 5 6 formats = "bBhHiIlLqQfd" 7 8 formats = c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint, \ 9 c_long, c_ulonglong, c_float, c_double, c_longdouble 10 11 class ArrayTestCase(unittest.TestCase): 12 def test_simple(self): 13 # create classes holding simple numeric types, and check 14 # various properties. 15 16 init = range(15, 25) 17 18 for fmt in formats: 19 alen = len(init) 20 int_array = ARRAY(fmt, alen) 21 22 ia = int_array(*init) 23 # length of instance ok? 24 self.assertEqual(len(ia), alen) 25 26 # slot values ok? 27 values = [ia[i] for i in range(alen)] 28 self.assertEqual(values, init) 29 30 # out-of-bounds accesses should be caught 31 with self.assertRaises(IndexError): ia[alen] 32 with self.assertRaises(IndexError): ia[-alen-1] 33 34 # change the items 35 from operator import setitem 36 new_values = range(42, 42+alen) 37 [setitem(ia, n, new_values[n]) for n in range(alen)] 38 values = [ia[i] for i in range(alen)] 39 self.assertEqual(values, new_values) 40 41 # are the items initialized to 0? 42 ia = int_array() 43 values = [ia[i] for i in range(alen)] 44 self.assertEqual(values, [0] * alen) 45 46 # Too many initializers should be caught 47 self.assertRaises(IndexError, int_array, *range(alen*2)) 48 49 CharArray = ARRAY(c_char, 3) 50 51 ca = CharArray("a", "b", "c") 52 53 # Should this work? It doesn't: 54 # CharArray("abc") 55 self.assertRaises(TypeError, CharArray, "abc") 56 57 self.assertEqual(ca[0], "a") 58 self.assertEqual(ca[1], "b") 59 self.assertEqual(ca[2], "c") 60 self.assertEqual(ca[-3], "a") 61 self.assertEqual(ca[-2], "b") 62 self.assertEqual(ca[-1], "c") 63 64 self.assertEqual(len(ca), 3) 65 66 # slicing is now supported, but not extended slicing (3-argument)! 67 from operator import getslice, delitem 68 self.assertRaises(TypeError, getslice, ca, 0, 1, -1) 69 70 # cannot delete items 71 self.assertRaises(TypeError, delitem, ca, 0) 72 73 def test_numeric_arrays(self): 74 75 alen = 5 76 77 numarray = ARRAY(c_int, alen) 78 79 na = numarray() 80 values = [na[i] for i in range(alen)] 81 self.assertEqual(values, [0] * alen) 82 83 na = numarray(*[c_int()] * alen) 84 values = [na[i] for i in range(alen)] 85 self.assertEqual(values, [0]*alen) 86 87 na = numarray(1, 2, 3, 4, 5) 88 values = [i for i in na] 89 self.assertEqual(values, [1, 2, 3, 4, 5]) 90 91 na = numarray(*map(c_int, (1, 2, 3, 4, 5))) 92 values = [i for i in na] 93 self.assertEqual(values, [1, 2, 3, 4, 5]) 94 95 def test_classcache(self): 96 self.assertIsNot(ARRAY(c_int, 3), ARRAY(c_int, 4)) 97 self.assertIs(ARRAY(c_int, 3), ARRAY(c_int, 3)) 98 99 def test_from_address(self): 100 # Failed with 0.9.8, reported by JUrner 101 p = create_string_buffer("foo") 102 sz = (c_char * 3).from_address(addressof(p)) 103 self.assertEqual(sz[:], "foo") 104 self.assertEqual(sz[::], "foo") 105 self.assertEqual(sz[::-1], "oof") 106 self.assertEqual(sz[::3], "f") 107 self.assertEqual(sz[1:4:2], "o") 108 self.assertEqual(sz.value, "foo") 109 110 @need_symbol('create_unicode_buffer') 111 def test_from_addressW(self): 112 p = create_unicode_buffer("foo") 113 sz = (c_wchar * 3).from_address(addressof(p)) 114 self.assertEqual(sz[:], "foo") 115 self.assertEqual(sz[::], "foo") 116 self.assertEqual(sz[::-1], "oof") 117 self.assertEqual(sz[::3], "f") 118 self.assertEqual(sz[1:4:2], "o") 119 self.assertEqual(sz.value, "foo") 120 121 def test_cache(self): 122 # Array types are cached internally in the _ctypes extension, 123 # in a WeakValueDictionary. Make sure the array type is 124 # removed from the cache when the itemtype goes away. This 125 # test will not fail, but will show a leak in the testsuite. 126 127 # Create a new type: 128 class my_int(c_int): 129 pass 130 # Create a new array type based on it: 131 t1 = my_int * 1 132 t2 = my_int * 1 133 self.assertIs(t1, t2) 134 135 if __name__ == '__main__': 136 unittest.main() 137