| from ctypes import * |
| import array |
| import gc |
| import unittest |
| |
| class X(Structure): |
| _fields_ = [("c_int", c_int)] |
| init_called = False |
| def __init__(self): |
| self._init_called = True |
| |
| class Test(unittest.TestCase): |
| def test_from_buffer(self): |
| a = array.array("i", range(16)) |
| x = (c_int * 16).from_buffer(a) |
| |
| y = X.from_buffer(a) |
| self.assertEqual(y.c_int, a[0]) |
| self.assertFalse(y.init_called) |
| |
| self.assertEqual(x[:], a.tolist()) |
| |
| a[0], a[-1] = 200, -200 |
| self.assertEqual(x[:], a.tolist()) |
| |
| self.assertRaises(BufferError, a.append, 100) |
| self.assertRaises(BufferError, a.pop) |
| |
| del x; del y; gc.collect(); gc.collect(); gc.collect() |
| a.append(100) |
| a.pop() |
| x = (c_int * 16).from_buffer(a) |
| |
| self.assertIn(a, [obj.obj if isinstance(obj, memoryview) else obj |
| for obj in x._objects.values()]) |
| |
| expected = x[:] |
| del a; gc.collect(); gc.collect(); gc.collect() |
| self.assertEqual(x[:], expected) |
| |
| with self.assertRaises(TypeError): |
| (c_char * 16).from_buffer(b"a" * 16) |
| with self.assertRaises(TypeError): |
| (c_char * 16).from_buffer("a" * 16) |
| |
| def test_from_buffer_with_offset(self): |
| a = array.array("i", range(16)) |
| x = (c_int * 15).from_buffer(a, sizeof(c_int)) |
| |
| self.assertEqual(x[:], a.tolist()[1:]) |
| with self.assertRaises(ValueError): |
| c_int.from_buffer(a, -1) |
| with self.assertRaises(ValueError): |
| (c_int * 16).from_buffer(a, sizeof(c_int)) |
| with self.assertRaises(ValueError): |
| (c_int * 1).from_buffer(a, 16 * sizeof(c_int)) |
| |
| def test_from_buffer_copy(self): |
| a = array.array("i", range(16)) |
| x = (c_int * 16).from_buffer_copy(a) |
| |
| y = X.from_buffer_copy(a) |
| self.assertEqual(y.c_int, a[0]) |
| self.assertFalse(y.init_called) |
| |
| self.assertEqual(x[:], list(range(16))) |
| |
| a[0], a[-1] = 200, -200 |
| self.assertEqual(x[:], list(range(16))) |
| |
| a.append(100) |
| self.assertEqual(x[:], list(range(16))) |
| |
| self.assertEqual(x._objects, None) |
| |
| del a; gc.collect(); gc.collect(); gc.collect() |
| self.assertEqual(x[:], list(range(16))) |
| |
| x = (c_char * 16).from_buffer_copy(b"a" * 16) |
| self.assertEqual(x[:], b"a" * 16) |
| with self.assertRaises(TypeError): |
| (c_char * 16).from_buffer_copy("a" * 16) |
| |
| def test_from_buffer_copy_with_offset(self): |
| a = array.array("i", range(16)) |
| x = (c_int * 15).from_buffer_copy(a, sizeof(c_int)) |
| |
| self.assertEqual(x[:], a.tolist()[1:]) |
| with self.assertRaises(ValueError): |
| c_int.from_buffer_copy(a, -1) |
| with self.assertRaises(ValueError): |
| (c_int * 16).from_buffer_copy(a, sizeof(c_int)) |
| with self.assertRaises(ValueError): |
| (c_int * 1).from_buffer_copy(a, 16 * sizeof(c_int)) |
| |
| if __name__ == '__main__': |
| unittest.main() |