1from ctypes import *
2import array
3import gc
4import unittest
5
6class X(Structure):
7    _fields_ = [("c_int", c_int)]
8    init_called = False
9    def __init__(self):
10        self._init_called = True
11
12class Test(unittest.TestCase):
13    def test_fom_buffer(self):
14        a = array.array("i", range(16))
15        x = (c_int * 16).from_buffer(a)
16
17        y = X.from_buffer(a)
18        self.assertEqual(y.c_int, a[0])
19        self.assertFalse(y.init_called)
20
21        self.assertEqual(x[:], a.tolist())
22
23        a[0], a[-1] = 200, -200
24        self.assertEqual(x[:], a.tolist())
25
26        self.assertTrue(a in x._objects.values())
27
28        self.assertRaises(ValueError,
29                          c_int.from_buffer, a, -1)
30
31        expected = x[:]
32        del a; gc.collect(); gc.collect(); gc.collect()
33        self.assertEqual(x[:], expected)
34
35        self.assertRaises(TypeError,
36                          (c_char * 16).from_buffer, "a" * 16)
37
38    def test_fom_buffer_with_offset(self):
39        a = array.array("i", range(16))
40        x = (c_int * 15).from_buffer(a, sizeof(c_int))
41
42        self.assertEqual(x[:], a.tolist()[1:])
43        self.assertRaises(ValueError, lambda: (c_int * 16).from_buffer(a, sizeof(c_int)))
44        self.assertRaises(ValueError, lambda: (c_int * 1).from_buffer(a, 16 * sizeof(c_int)))
45
46    def test_from_buffer_copy(self):
47        a = array.array("i", range(16))
48        x = (c_int * 16).from_buffer_copy(a)
49
50        y = X.from_buffer_copy(a)
51        self.assertEqual(y.c_int, a[0])
52        self.assertFalse(y.init_called)
53
54        self.assertEqual(x[:], range(16))
55
56        a[0], a[-1] = 200, -200
57        self.assertEqual(x[:], range(16))
58
59        self.assertEqual(x._objects, None)
60
61        self.assertRaises(ValueError,
62                          c_int.from_buffer, a, -1)
63
64        del a; gc.collect(); gc.collect(); gc.collect()
65        self.assertEqual(x[:], range(16))
66
67        x = (c_char * 16).from_buffer_copy("a" * 16)
68        self.assertEqual(x[:], "a" * 16)
69
70    def test_fom_buffer_copy_with_offset(self):
71        a = array.array("i", range(16))
72        x = (c_int * 15).from_buffer_copy(a, sizeof(c_int))
73
74        self.assertEqual(x[:], a.tolist()[1:])
75        self.assertRaises(ValueError,
76                          (c_int * 16).from_buffer_copy, a, sizeof(c_int))
77        self.assertRaises(ValueError,
78                          (c_int * 1).from_buffer_copy, a, 16 * sizeof(c_int))
79
80if __name__ == '__main__':
81    unittest.main()
82