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_from_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.assertRaises(BufferError, a.append, 100) 27 self.assertRaises(BufferError, a.pop) 28 29 del x; del y; gc.collect(); gc.collect(); gc.collect() 30 a.append(100) 31 a.pop() 32 x = (c_int * 16).from_buffer(a) 33 34 self.assertIn(a, [obj.obj if isinstance(obj, memoryview) else obj 35 for obj in x._objects.values()]) 36 37 expected = x[:] 38 del a; gc.collect(); gc.collect(); gc.collect() 39 self.assertEqual(x[:], expected) 40 41 with self.assertRaisesRegex(TypeError, "not writable"): 42 (c_char * 16).from_buffer(b"a" * 16) 43 with self.assertRaisesRegex(TypeError, "not writable"): 44 (c_char * 16).from_buffer(memoryview(b"a" * 16)) 45 with self.assertRaisesRegex(TypeError, "not C contiguous"): 46 (c_char * 16).from_buffer(memoryview(bytearray(b"a" * 16))[::-1]) 47 msg = "bytes-like object is required" 48 with self.assertRaisesRegex(TypeError, msg): 49 (c_char * 16).from_buffer("a" * 16) 50 51 def test_fortran_contiguous(self): 52 try: 53 import _testbuffer 54 except ImportError as err: 55 self.skipTest(str(err)) 56 flags = _testbuffer.ND_WRITABLE | _testbuffer.ND_FORTRAN 57 array = _testbuffer.ndarray( 58 [97] * 16, format="B", shape=[4, 4], flags=flags) 59 with self.assertRaisesRegex(TypeError, "not C contiguous"): 60 (c_char * 16).from_buffer(array) 61 array = memoryview(array) 62 self.assertTrue(array.f_contiguous) 63 self.assertFalse(array.c_contiguous) 64 with self.assertRaisesRegex(TypeError, "not C contiguous"): 65 (c_char * 16).from_buffer(array) 66 67 def test_from_buffer_with_offset(self): 68 a = array.array("i", range(16)) 69 x = (c_int * 15).from_buffer(a, sizeof(c_int)) 70 71 self.assertEqual(x[:], a.tolist()[1:]) 72 with self.assertRaises(ValueError): 73 c_int.from_buffer(a, -1) 74 with self.assertRaises(ValueError): 75 (c_int * 16).from_buffer(a, sizeof(c_int)) 76 with self.assertRaises(ValueError): 77 (c_int * 1).from_buffer(a, 16 * sizeof(c_int)) 78 79 def test_from_buffer_memoryview(self): 80 a = [c_char.from_buffer(memoryview(bytearray(b'a')))] 81 a.append(a) 82 del a 83 gc.collect() # Should not crash 84 85 def test_from_buffer_copy(self): 86 a = array.array("i", range(16)) 87 x = (c_int * 16).from_buffer_copy(a) 88 89 y = X.from_buffer_copy(a) 90 self.assertEqual(y.c_int, a[0]) 91 self.assertFalse(y.init_called) 92 93 self.assertEqual(x[:], list(range(16))) 94 95 a[0], a[-1] = 200, -200 96 self.assertEqual(x[:], list(range(16))) 97 98 a.append(100) 99 self.assertEqual(x[:], list(range(16))) 100 101 self.assertEqual(x._objects, None) 102 103 del a; gc.collect(); gc.collect(); gc.collect() 104 self.assertEqual(x[:], list(range(16))) 105 106 x = (c_char * 16).from_buffer_copy(b"a" * 16) 107 self.assertEqual(x[:], b"a" * 16) 108 with self.assertRaises(TypeError): 109 (c_char * 16).from_buffer_copy("a" * 16) 110 111 def test_from_buffer_copy_with_offset(self): 112 a = array.array("i", range(16)) 113 x = (c_int * 15).from_buffer_copy(a, sizeof(c_int)) 114 115 self.assertEqual(x[:], a.tolist()[1:]) 116 with self.assertRaises(ValueError): 117 c_int.from_buffer_copy(a, -1) 118 with self.assertRaises(ValueError): 119 (c_int * 16).from_buffer_copy(a, sizeof(c_int)) 120 with self.assertRaises(ValueError): 121 (c_int * 1).from_buffer_copy(a, 16 * sizeof(c_int)) 122 123 def test_abstract(self): 124 from ctypes import _Pointer, _SimpleCData, _CFuncPtr 125 126 self.assertRaises(TypeError, Array.from_buffer, bytearray(10)) 127 self.assertRaises(TypeError, Structure.from_buffer, bytearray(10)) 128 self.assertRaises(TypeError, Union.from_buffer, bytearray(10)) 129 self.assertRaises(TypeError, _CFuncPtr.from_buffer, bytearray(10)) 130 self.assertRaises(TypeError, _Pointer.from_buffer, bytearray(10)) 131 self.assertRaises(TypeError, _SimpleCData.from_buffer, bytearray(10)) 132 133 self.assertRaises(TypeError, Array.from_buffer_copy, b"123") 134 self.assertRaises(TypeError, Structure.from_buffer_copy, b"123") 135 self.assertRaises(TypeError, Union.from_buffer_copy, b"123") 136 self.assertRaises(TypeError, _CFuncPtr.from_buffer_copy, b"123") 137 self.assertRaises(TypeError, _Pointer.from_buffer_copy, b"123") 138 self.assertRaises(TypeError, _SimpleCData.from_buffer_copy, b"123") 139 140if __name__ == '__main__': 141 unittest.main() 142