1
"""Unit tests for the memoryview
3
XXX We need more tests! Some tests are in test_bytes
14
class AbstractMemoryTests:
15
source_bytes = b"abcdef"
19
return self.source_bytes
23
return filter(None, [self.ro_type, self.rw_type])
25
def check_getitem_with_type(self, tp):
26
item = self.getitem_type
28
oldrefcount = sys.getrefcount(b)
30
self.assertEquals(m[0], item(b"a"))
31
self.assert_(isinstance(m[0], bytes), type(m[0]))
32
self.assertEquals(m[5], item(b"f"))
33
self.assertEquals(m[-1], item(b"f"))
34
self.assertEquals(m[-6], item(b"a"))
36
self.assertRaises(IndexError, lambda: m[6])
37
self.assertRaises(IndexError, lambda: m[-7])
38
self.assertRaises(IndexError, lambda: m[sys.maxsize])
39
self.assertRaises(IndexError, lambda: m[-sys.maxsize])
41
self.assertRaises(TypeError, lambda: m[None])
42
self.assertRaises(TypeError, lambda: m[0.0])
43
self.assertRaises(TypeError, lambda: m["a"])
45
self.assertEquals(sys.getrefcount(b), oldrefcount)
47
def test_getitem(self):
48
for tp in self._types:
49
self.check_getitem_with_type(tp)
51
def test_setitem_readonly(self):
54
b = self.ro_type(self._source)
55
oldrefcount = sys.getrefcount(b)
59
self.assertRaises(TypeError, setitem, b"a")
60
self.assertRaises(TypeError, setitem, 65)
61
self.assertRaises(TypeError, setitem, memoryview(b"a"))
63
self.assertEquals(sys.getrefcount(b), oldrefcount)
65
def test_setitem_writable(self):
69
b = self.rw_type(self._source)
70
oldrefcount = sys.getrefcount(b)
73
self._check_contents(tp, b, b"0bcdef")
75
self._check_contents(tp, b, b"012def")
77
self._check_contents(tp, b, b"012def")
79
self._check_contents(tp, b, b"abcdef")
81
# Overlapping copies of a view into itself
83
self._check_contents(tp, b, b"cdedef")
86
self._check_contents(tp, b, b"ababcf")
88
def setitem(key, value):
91
self.assertRaises(IndexError, setitem, 6, b"a")
92
self.assertRaises(IndexError, setitem, -7, b"a")
93
self.assertRaises(IndexError, setitem, sys.maxsize, b"a")
94
self.assertRaises(IndexError, setitem, -sys.maxsize, b"a")
95
# Wrong index/slice types
96
self.assertRaises(TypeError, setitem, 0.0, b"a")
97
self.assertRaises(TypeError, setitem, (0,), b"a")
98
self.assertRaises(TypeError, setitem, "a", b"a")
99
# Trying to resize the memory object
100
self.assertRaises(ValueError, setitem, 0, b"")
101
self.assertRaises(ValueError, setitem, 0, b"ab")
102
self.assertRaises(ValueError, setitem, slice(1,1), b"a")
103
self.assertRaises(ValueError, setitem, slice(0,2), b"a")
106
self.assertEquals(sys.getrefcount(b), oldrefcount)
108
def test_tobytes(self):
109
for tp in self._types:
110
m = self._view(tp(self._source))
112
# This calls self.getitem_type() on each separate byte of b"abcdef"
114
self.getitem_type(bytes([c])) for c in b"abcdef")
115
self.assertEquals(b, expected)
116
self.assert_(isinstance(b, bytes), type(b))
118
def test_tolist(self):
119
for tp in self._types:
120
m = self._view(tp(self._source))
122
self.assertEquals(l, list(b"abcdef"))
124
def test_compare(self):
125
# memoryviews can compare for equality with other objects
126
# having the buffer interface.
127
for tp in self._types:
128
m = self._view(tp(self._source))
129
for tp_comp in self._types:
130
self.assertTrue(m == tp_comp(b"abcdef"))
131
self.assertFalse(m != tp_comp(b"abcdef"))
132
self.assertFalse(m == tp_comp(b"abcde"))
133
self.assertTrue(m != tp_comp(b"abcde"))
134
self.assertFalse(m == tp_comp(b"abcde1"))
135
self.assertTrue(m != tp_comp(b"abcde1"))
136
self.assertTrue(m == m)
137
self.assertTrue(m == m[:])
138
self.assertTrue(m[0:6] == m[:])
139
self.assertFalse(m[0:5] == m)
141
# Comparison with objects which don't support the buffer API
142
self.assertFalse(m == "abcdef")
143
self.assertTrue(m != "abcdef")
144
self.assertFalse("abcdef" == m)
145
self.assertTrue("abcdef" != m)
147
# Unordered comparisons
148
for c in (m, b"abcdef"):
149
self.assertRaises(TypeError, lambda: m < c)
150
self.assertRaises(TypeError, lambda: c <= m)
151
self.assertRaises(TypeError, lambda: m >= c)
152
self.assertRaises(TypeError, lambda: c > m)
154
def check_attributes_with_type(self, tp):
155
m = self._view(tp(self._source))
156
self.assertEquals(m.format, self.format)
157
self.assertEquals(m.itemsize, self.itemsize)
158
self.assertEquals(m.ndim, 1)
159
self.assertEquals(m.shape, (6,))
160
self.assertEquals(len(m), 6)
161
self.assertEquals(m.strides, (self.itemsize,))
162
self.assertEquals(m.suboffsets, None)
165
def test_attributes_readonly(self):
168
m = self.check_attributes_with_type(self.ro_type)
169
self.assertEquals(m.readonly, True)
171
def test_attributes_writable(self):
174
m = self.check_attributes_with_type(self.rw_type)
175
self.assertEquals(m.readonly, False)
177
def test_getbuffer(self):
178
# Test PyObject_GetBuffer() on a memoryview object.
179
for tp in self._types:
181
oldrefcount = sys.getrefcount(b)
183
oldviewrefcount = sys.getrefcount(m)
185
self._check_contents(tp, b, s.encode("utf-8"))
186
self.assertEquals(sys.getrefcount(m), oldviewrefcount)
188
self.assertEquals(sys.getrefcount(b), oldrefcount)
191
for tp in self._types:
192
if not isinstance(tp, type):
193
# If tp is a factory rather than a plain type, skip
201
# Create a reference cycle through a memoryview object
202
b = MySource(tp(b'abc'))
209
# The cycle must be broken
211
self.assert_(wr() is None, wr())
214
# Variations on source objects for the buffer: bytes-like objects, then arrays
216
# NOTE: support for multi-dimensional objects is unimplemented.
218
class BaseBytesMemoryTests(AbstractMemoryTests):
225
class BaseArrayMemoryTests(AbstractMemoryTests):
227
rw_type = lambda self, b: array.array('i', list(b))
228
getitem_type = lambda self, b: array.array('i', list(b)).tostring()
229
itemsize = array.array('i').itemsize
232
def test_getbuffer(self):
233
# XXX Test should be adapted for non-byte buffers
236
def test_tolist(self):
237
# XXX NotImplementedError: tolist() only supports byte views
241
# Variations on indirection levels: memoryview, slice of memoryview,
242
# slice of slice of memoryview.
243
# This is important to test allocation subtleties.
245
class BaseMemoryviewTests:
246
def _view(self, obj):
247
return memoryview(obj)
249
def _check_contents(self, tp, obj, contents):
250
self.assertEquals(obj, tp(contents))
252
class BaseMemorySliceTests:
253
source_bytes = b"XabcdefY"
255
def _view(self, obj):
259
def _check_contents(self, tp, obj, contents):
260
self.assertEquals(obj[1:7], tp(contents))
263
for tp in self._types:
264
m = memoryview(tp(self._source))
265
oldrefcount = sys.getrefcount(m)
267
self.assertEquals(sys.getrefcount(m), oldrefcount)
269
class BaseMemorySliceSliceTests:
270
source_bytes = b"XabcdefY"
272
def _view(self, obj):
276
def _check_contents(self, tp, obj, contents):
277
self.assertEquals(obj[1:7], tp(contents))
280
# Concrete test classes
282
class BytesMemoryviewTest(unittest.TestCase,
283
BaseMemoryviewTests, BaseBytesMemoryTests):
285
def test_constructor(self):
286
for tp in self._types:
287
ob = tp(self._source)
288
self.assert_(memoryview(ob))
289
self.assert_(memoryview(object=ob))
290
self.assertRaises(TypeError, memoryview)
291
self.assertRaises(TypeError, memoryview, ob, ob)
292
self.assertRaises(TypeError, memoryview, argument=ob)
293
self.assertRaises(TypeError, memoryview, ob, argument=True)
295
class ArrayMemoryviewTest(unittest.TestCase,
296
BaseMemoryviewTests, BaseArrayMemoryTests):
298
def test_array_assign(self):
299
# Issue #4569: segfault when mutating a memoryview with itemsize != 1
300
a = array.array('i', range(10))
302
new_a = array.array('i', range(9, -1, -1))
304
self.assertEquals(a, new_a)
307
class BytesMemorySliceTest(unittest.TestCase,
308
BaseMemorySliceTests, BaseBytesMemoryTests):
311
class ArrayMemorySliceTest(unittest.TestCase,
312
BaseMemorySliceTests, BaseArrayMemoryTests):
315
class BytesMemorySliceSliceTest(unittest.TestCase,
316
BaseMemorySliceSliceTests, BaseBytesMemoryTests):
319
class ArrayMemorySliceSliceTest(unittest.TestCase,
320
BaseMemorySliceSliceTests, BaseArrayMemoryTests):
325
test.support.run_unittest(__name__)
327
if __name__ == "__main__":