Home | History | Annotate | Download | only in test
      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