|
| 1 | +import unittest |
| 2 | +from test.support import import_helper |
| 3 | + |
| 4 | +_testlimitedcapi = import_helper.import_module('_testlimitedcapi') |
| 5 | +_testbuffer = import_helper.import_module('_testbuffer') |
| 6 | +from _testbuffer import ndarray, ND_WRITABLE, ND_FORTRAN |
| 7 | + |
| 8 | + |
| 9 | +class CAPITest(unittest.TestCase): |
| 10 | + def test_object_copydata(self): |
| 11 | + # Test PyObject_CopyData() |
| 12 | + copydata = _testlimitedcapi.object_copydata |
| 13 | + |
| 14 | + dest = bytearray(b'xyz') |
| 15 | + self.assertEqual(copydata(dest, b'abc'), 0) |
| 16 | + self.assertEqual(dest, b'abc') |
| 17 | + |
| 18 | + dest = bytearray(5) |
| 19 | + self.assertEqual(copydata(dest, memoryview(b'abc')), 0) |
| 20 | + self.assertEqual(dest, b'abc\0\0') |
| 21 | + |
| 22 | + dest = bytearray() |
| 23 | + self.assertEqual(copydata(dest, b''), 0) |
| 24 | + self.assertEqual(dest, b'') |
| 25 | + |
| 26 | + # Non-contiguous source |
| 27 | + dest = bytearray(4) |
| 28 | + self.assertEqual(copydata(dest, memoryview(b'abcdefgh')[::2]), 0) |
| 29 | + self.assertEqual(dest, b'aceg') |
| 30 | + |
| 31 | + # Non-contiguous destination |
| 32 | + base = bytearray(b'........') |
| 33 | + self.assertEqual(copydata(memoryview(base)[::2], b'wxyz'), 0) |
| 34 | + self.assertEqual(base, b'w.x.y.z.') |
| 35 | + |
| 36 | + # Destination too small |
| 37 | + dest = bytearray(b'xy') |
| 38 | + self.assertRaises(BufferError, copydata, dest, b'abc') |
| 39 | + self.assertEqual(dest, b'xy') |
| 40 | + |
| 41 | + # Read-only destination |
| 42 | + self.assertRaises(BufferError, copydata, b'xyz', b'abc') |
| 43 | + |
| 44 | + self.assertRaises(TypeError, copydata, bytearray(3), 'abc') |
| 45 | + self.assertRaises(TypeError, copydata, [], b'') |
| 46 | + self.assertRaises(TypeError, copydata, 42, b'') |
| 47 | + |
| 48 | + # CRASHES copydata(NULL, b'abc') |
| 49 | + # CRASHES copydata(bytearray(3), NULL) |
| 50 | + |
| 51 | + def test_object_copydata_multidim(self): |
| 52 | + # Test PyObject_CopyData() with multi-dimensional buffers |
| 53 | + copydata = _testlimitedcapi.object_copydata |
| 54 | + items = list(range(12)) |
| 55 | + c_src = ndarray(items, shape=[3, 4], format='B') |
| 56 | + f_src = ndarray(items, shape=[3, 4], format='B', flags=ND_FORTRAN) |
| 57 | + |
| 58 | + for src in c_src, f_src: |
| 59 | + for flags in ND_WRITABLE, ND_WRITABLE|ND_FORTRAN: |
| 60 | + with self.subTest(src=src.flags, dest=flags): |
| 61 | + dest = ndarray([0]*12, shape=[3, 4], format='B', |
| 62 | + flags=flags) |
| 63 | + self.assertEqual(copydata(dest, src), 0) |
| 64 | + self.assertEqual(dest.tolist(), src.tolist()) |
| 65 | + |
| 66 | + # Multi-byte items |
| 67 | + src = ndarray([1, -2, 3, -4, 5, -6], shape=[2, 3], format='i') |
| 68 | + dest = ndarray([0]*6, shape=[2, 3], format='i', |
| 69 | + flags=ND_WRITABLE|ND_FORTRAN) |
| 70 | + self.assertEqual(copydata(dest, src), 0) |
| 71 | + self.assertEqual(dest.tolist(), [[1, -2, 3], [-4, 5, -6]]) |
| 72 | + |
| 73 | + # Non-contiguous source |
| 74 | + src = c_src[::2, ::2] |
| 75 | + dest = ndarray([0]*4, shape=[2, 2], format='B', flags=ND_WRITABLE) |
| 76 | + self.assertEqual(copydata(dest, src), 0) |
| 77 | + self.assertEqual(dest.tolist(), [[0, 2], [8, 10]]) |
| 78 | + |
| 79 | + def test_buffer_fillcontiguousstrides(self): |
| 80 | + # Test PyBuffer_FillContiguousStrides() |
| 81 | + fill = _testlimitedcapi.buffer_fillcontiguousstrides |
| 82 | + |
| 83 | + self.assertEqual(fill((2, 3, 4), 8, 'C'), (96, 32, 8)) |
| 84 | + self.assertEqual(fill((2, 3, 4), 8, 'F'), (8, 16, 48)) |
| 85 | + self.assertEqual(fill((5,), 2, 'C'), (2,)) |
| 86 | + self.assertEqual(fill((5,), 2, 'F'), (2,)) |
| 87 | + self.assertEqual(fill((), 4, 'C'), ()) |
| 88 | + self.assertEqual(fill((), 4, 'F'), ()) |
| 89 | + self.assertEqual(fill((2, 0, 3), 4, 'C'), (0, 12, 4)) |
| 90 | + self.assertEqual(fill((2, 0, 3), 4, 'F'), (4, 8, 0)) |
| 91 | + |
| 92 | + |
| 93 | +if __name__ == "__main__": |
| 94 | + unittest.main() |
0 commit comments