| 
									
										
										
										
											2007-11-08 02:28:11 +00:00
										 |  |  | """Unit tests for the memoryview
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-19 12:50:24 +02:00
										 |  |  |    Some tests are in test_bytes. Many tests that require _testbuffer.ndarray | 
					
						
							|  |  |  |    are in test_buffer. | 
					
						
							| 
									
										
										
										
											2007-11-08 02:28:11 +00:00
										 |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import unittest | 
					
						
							| 
									
										
										
										
											2008-05-20 21:35:26 +00:00
										 |  |  | import test.support | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | import sys | 
					
						
							| 
									
										
										
										
											2008-09-01 15:10:14 +00:00
										 |  |  | import gc | 
					
						
							|  |  |  | import weakref | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  | import array | 
					
						
							| 
									
										
										
										
											2011-01-18 18:57:52 +00:00
										 |  |  | import io | 
					
						
							| 
									
										
										
										
											2007-11-08 02:28:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  | class AbstractMemoryTests: | 
					
						
							|  |  |  |     source_bytes = b"abcdef" | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |     @property | 
					
						
							|  |  |  |     def _source(self): | 
					
						
							|  |  |  |         return self.source_bytes | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @property | 
					
						
							|  |  |  |     def _types(self): | 
					
						
							|  |  |  |         return filter(None, [self.ro_type, self.rw_type]) | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def check_getitem_with_type(self, tp): | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |         b = tp(self._source) | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  |         oldrefcount = sys.getrefcount(b) | 
					
						
							|  |  |  |         m = self._view(b) | 
					
						
							| 
									
										
										
										
											2012-02-25 12:24:21 +01:00
										 |  |  |         self.assertEqual(m[0], ord(b"a")) | 
					
						
							|  |  |  |         self.assertIsInstance(m[0], int) | 
					
						
							|  |  |  |         self.assertEqual(m[5], ord(b"f")) | 
					
						
							|  |  |  |         self.assertEqual(m[-1], ord(b"f")) | 
					
						
							|  |  |  |         self.assertEqual(m[-6], ord(b"a")) | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  |         # Bounds checking | 
					
						
							|  |  |  |         self.assertRaises(IndexError, lambda: m[6]) | 
					
						
							|  |  |  |         self.assertRaises(IndexError, lambda: m[-7]) | 
					
						
							|  |  |  |         self.assertRaises(IndexError, lambda: m[sys.maxsize]) | 
					
						
							|  |  |  |         self.assertRaises(IndexError, lambda: m[-sys.maxsize]) | 
					
						
							|  |  |  |         # Type checking | 
					
						
							|  |  |  |         self.assertRaises(TypeError, lambda: m[None]) | 
					
						
							|  |  |  |         self.assertRaises(TypeError, lambda: m[0.0]) | 
					
						
							|  |  |  |         self.assertRaises(TypeError, lambda: m["a"]) | 
					
						
							|  |  |  |         m = None | 
					
						
							| 
									
										
										
										
											2010-11-20 19:04:17 +00:00
										 |  |  |         self.assertEqual(sys.getrefcount(b), oldrefcount) | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |     def test_getitem(self): | 
					
						
							|  |  |  |         for tp in self._types: | 
					
						
							|  |  |  |             self.check_getitem_with_type(tp) | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-23 20:38:54 +00:00
										 |  |  |     def test_iter(self): | 
					
						
							|  |  |  |         for tp in self._types: | 
					
						
							|  |  |  |             b = tp(self._source) | 
					
						
							|  |  |  |             m = self._view(b) | 
					
						
							|  |  |  |             self.assertEqual(list(m), [m[i] for i in range(len(m))]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  |     def test_setitem_readonly(self): | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |         if not self.ro_type: | 
					
						
							| 
									
										
										
										
											2013-12-08 00:20:35 -06:00
										 |  |  |             self.skipTest("no read-only type to test") | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |         b = self.ro_type(self._source) | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  |         oldrefcount = sys.getrefcount(b) | 
					
						
							|  |  |  |         m = self._view(b) | 
					
						
							|  |  |  |         def setitem(value): | 
					
						
							|  |  |  |             m[0] = value | 
					
						
							|  |  |  |         self.assertRaises(TypeError, setitem, b"a") | 
					
						
							|  |  |  |         self.assertRaises(TypeError, setitem, 65) | 
					
						
							|  |  |  |         self.assertRaises(TypeError, setitem, memoryview(b"a")) | 
					
						
							|  |  |  |         m = None | 
					
						
							| 
									
										
										
										
											2010-11-20 19:04:17 +00:00
										 |  |  |         self.assertEqual(sys.getrefcount(b), oldrefcount) | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_setitem_writable(self): | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |         if not self.rw_type: | 
					
						
							| 
									
										
										
										
											2013-12-08 00:20:35 -06:00
										 |  |  |             self.skipTest("no writable type to test") | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |         tp = self.rw_type | 
					
						
							|  |  |  |         b = self.rw_type(self._source) | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  |         oldrefcount = sys.getrefcount(b) | 
					
						
							|  |  |  |         m = self._view(b) | 
					
						
							| 
									
										
										
										
											2012-02-25 12:24:21 +01:00
										 |  |  |         m[0] = ord(b'1') | 
					
						
							|  |  |  |         self._check_contents(tp, b, b"1bcdef") | 
					
						
							|  |  |  |         m[0:1] = tp(b"0") | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |         self._check_contents(tp, b, b"0bcdef") | 
					
						
							|  |  |  |         m[1:3] = tp(b"12") | 
					
						
							|  |  |  |         self._check_contents(tp, b, b"012def") | 
					
						
							|  |  |  |         m[1:1] = tp(b"") | 
					
						
							|  |  |  |         self._check_contents(tp, b, b"012def") | 
					
						
							|  |  |  |         m[:] = tp(b"abcdef") | 
					
						
							|  |  |  |         self._check_contents(tp, b, b"abcdef") | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         # Overlapping copies of a view into itself | 
					
						
							|  |  |  |         m[0:3] = m[2:5] | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |         self._check_contents(tp, b, b"cdedef") | 
					
						
							|  |  |  |         m[:] = tp(b"abcdef") | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  |         m[2:5] = m[0:3] | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |         self._check_contents(tp, b, b"ababcf") | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         def setitem(key, value): | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |             m[key] = tp(value) | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  |         # Bounds checking | 
					
						
							|  |  |  |         self.assertRaises(IndexError, setitem, 6, b"a") | 
					
						
							|  |  |  |         self.assertRaises(IndexError, setitem, -7, b"a") | 
					
						
							|  |  |  |         self.assertRaises(IndexError, setitem, sys.maxsize, b"a") | 
					
						
							|  |  |  |         self.assertRaises(IndexError, setitem, -sys.maxsize, b"a") | 
					
						
							|  |  |  |         # Wrong index/slice types | 
					
						
							|  |  |  |         self.assertRaises(TypeError, setitem, 0.0, b"a") | 
					
						
							|  |  |  |         self.assertRaises(TypeError, setitem, (0,), b"a") | 
					
						
							| 
									
										
										
										
											2012-02-25 12:24:21 +01:00
										 |  |  |         self.assertRaises(TypeError, setitem, (slice(0,1,1), 0), b"a") | 
					
						
							|  |  |  |         self.assertRaises(TypeError, setitem, (0, slice(0,1,1)), b"a") | 
					
						
							|  |  |  |         self.assertRaises(TypeError, setitem, (0,), b"a") | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  |         self.assertRaises(TypeError, setitem, "a", b"a") | 
					
						
							| 
									
										
										
										
											2012-02-25 12:24:21 +01:00
										 |  |  |         # Not implemented: multidimensional slices | 
					
						
							|  |  |  |         slices = (slice(0,1,1), slice(0,1,2)) | 
					
						
							|  |  |  |         self.assertRaises(NotImplementedError, setitem, slices, b"a") | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  |         # Trying to resize the memory object | 
					
						
							| 
									
										
										
										
											2012-02-25 12:24:21 +01:00
										 |  |  |         exc = ValueError if m.format == 'c' else TypeError | 
					
						
							|  |  |  |         self.assertRaises(exc, setitem, 0, b"") | 
					
						
							|  |  |  |         self.assertRaises(exc, setitem, 0, b"ab") | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  |         self.assertRaises(ValueError, setitem, slice(1,1), b"a") | 
					
						
							|  |  |  |         self.assertRaises(ValueError, setitem, slice(0,2), b"a") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m = None | 
					
						
							| 
									
										
										
										
											2010-11-20 19:04:17 +00:00
										 |  |  |         self.assertEqual(sys.getrefcount(b), oldrefcount) | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-01 21:14:16 +00:00
										 |  |  |     def test_delitem(self): | 
					
						
							|  |  |  |         for tp in self._types: | 
					
						
							|  |  |  |             b = tp(self._source) | 
					
						
							|  |  |  |             m = self._view(b) | 
					
						
							|  |  |  |             with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                 del m[1] | 
					
						
							|  |  |  |             with self.assertRaises(TypeError): | 
					
						
							|  |  |  |                 del m[1:4] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  |     def test_tobytes(self): | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |         for tp in self._types: | 
					
						
							|  |  |  |             m = self._view(tp(self._source)) | 
					
						
							|  |  |  |             b = m.tobytes() | 
					
						
							|  |  |  |             # This calls self.getitem_type() on each separate byte of b"abcdef" | 
					
						
							|  |  |  |             expected = b"".join( | 
					
						
							|  |  |  |                 self.getitem_type(bytes([c])) for c in b"abcdef") | 
					
						
							| 
									
										
										
										
											2010-11-20 19:04:17 +00:00
										 |  |  |             self.assertEqual(b, expected) | 
					
						
							| 
									
										
										
										
											2010-01-24 19:26:24 +00:00
										 |  |  |             self.assertIsInstance(b, bytes) | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_tolist(self): | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |         for tp in self._types: | 
					
						
							|  |  |  |             m = self._view(tp(self._source)) | 
					
						
							|  |  |  |             l = m.tolist() | 
					
						
							| 
									
										
										
										
											2010-11-20 19:04:17 +00:00
										 |  |  |             self.assertEqual(l, list(b"abcdef")) | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_compare(self): | 
					
						
							|  |  |  |         # memoryviews can compare for equality with other objects | 
					
						
							|  |  |  |         # having the buffer interface. | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |         for tp in self._types: | 
					
						
							|  |  |  |             m = self._view(tp(self._source)) | 
					
						
							|  |  |  |             for tp_comp in self._types: | 
					
						
							|  |  |  |                 self.assertTrue(m == tp_comp(b"abcdef")) | 
					
						
							|  |  |  |                 self.assertFalse(m != tp_comp(b"abcdef")) | 
					
						
							|  |  |  |                 self.assertFalse(m == tp_comp(b"abcde")) | 
					
						
							|  |  |  |                 self.assertTrue(m != tp_comp(b"abcde")) | 
					
						
							|  |  |  |                 self.assertFalse(m == tp_comp(b"abcde1")) | 
					
						
							|  |  |  |                 self.assertTrue(m != tp_comp(b"abcde1")) | 
					
						
							|  |  |  |             self.assertTrue(m == m) | 
					
						
							|  |  |  |             self.assertTrue(m == m[:]) | 
					
						
							|  |  |  |             self.assertTrue(m[0:6] == m[:]) | 
					
						
							|  |  |  |             self.assertFalse(m[0:5] == m) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # Comparison with objects which don't support the buffer API | 
					
						
							|  |  |  |             self.assertFalse(m == "abcdef") | 
					
						
							|  |  |  |             self.assertTrue(m != "abcdef") | 
					
						
							|  |  |  |             self.assertFalse("abcdef" == m) | 
					
						
							|  |  |  |             self.assertTrue("abcdef" != m) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # Unordered comparisons | 
					
						
							|  |  |  |             for c in (m, b"abcdef"): | 
					
						
							|  |  |  |                 self.assertRaises(TypeError, lambda: m < c) | 
					
						
							|  |  |  |                 self.assertRaises(TypeError, lambda: c <= m) | 
					
						
							|  |  |  |                 self.assertRaises(TypeError, lambda: m >= c) | 
					
						
							|  |  |  |                 self.assertRaises(TypeError, lambda: c > m) | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def check_attributes_with_type(self, tp): | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |         m = self._view(tp(self._source)) | 
					
						
							| 
									
										
										
										
											2010-11-20 19:04:17 +00:00
										 |  |  |         self.assertEqual(m.format, self.format) | 
					
						
							|  |  |  |         self.assertEqual(m.itemsize, self.itemsize) | 
					
						
							|  |  |  |         self.assertEqual(m.ndim, 1) | 
					
						
							|  |  |  |         self.assertEqual(m.shape, (6,)) | 
					
						
							|  |  |  |         self.assertEqual(len(m), 6) | 
					
						
							|  |  |  |         self.assertEqual(m.strides, (self.itemsize,)) | 
					
						
							| 
									
										
										
										
											2012-02-25 12:24:21 +01:00
										 |  |  |         self.assertEqual(m.suboffsets, ()) | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  |         return m | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_attributes_readonly(self): | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |         if not self.ro_type: | 
					
						
							| 
									
										
										
										
											2013-12-08 00:20:35 -06:00
										 |  |  |             self.skipTest("no read-only type to test") | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |         m = self.check_attributes_with_type(self.ro_type) | 
					
						
							| 
									
										
										
										
											2010-11-20 19:04:17 +00:00
										 |  |  |         self.assertEqual(m.readonly, True) | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_attributes_writable(self): | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |         if not self.rw_type: | 
					
						
							| 
									
										
										
										
											2013-12-08 00:20:35 -06:00
										 |  |  |             self.skipTest("no writable type to test") | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |         m = self.check_attributes_with_type(self.rw_type) | 
					
						
							| 
									
										
										
										
											2010-11-20 19:04:17 +00:00
										 |  |  |         self.assertEqual(m.readonly, False) | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-01 15:10:14 +00:00
										 |  |  |     def test_getbuffer(self): | 
					
						
							|  |  |  |         # Test PyObject_GetBuffer() on a memoryview object. | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |         for tp in self._types: | 
					
						
							|  |  |  |             b = tp(self._source) | 
					
						
							|  |  |  |             oldrefcount = sys.getrefcount(b) | 
					
						
							|  |  |  |             m = self._view(b) | 
					
						
							|  |  |  |             oldviewrefcount = sys.getrefcount(m) | 
					
						
							|  |  |  |             s = str(m, "utf-8") | 
					
						
							|  |  |  |             self._check_contents(tp, b, s.encode("utf-8")) | 
					
						
							| 
									
										
										
										
											2010-11-20 19:04:17 +00:00
										 |  |  |             self.assertEqual(sys.getrefcount(m), oldviewrefcount) | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |             m = None | 
					
						
							| 
									
										
										
										
											2010-11-20 19:04:17 +00:00
										 |  |  |             self.assertEqual(sys.getrefcount(b), oldrefcount) | 
					
						
							| 
									
										
										
										
											2008-09-01 15:10:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_gc(self): | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |         for tp in self._types: | 
					
						
							|  |  |  |             if not isinstance(tp, type): | 
					
						
							|  |  |  |                 # If tp is a factory rather than a plain type, skip | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-25 12:24:21 +01:00
										 |  |  |             class MyView(): | 
					
						
							|  |  |  |                 def __init__(self, base): | 
					
						
							|  |  |  |                     self.m = memoryview(base) | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |             class MySource(tp): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |             class MyObject: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-25 12:24:21 +01:00
										 |  |  |             # Create a reference cycle through a memoryview object. | 
					
						
							|  |  |  |             # This exercises mbuf_clear(). | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |             b = MySource(tp(b'abc')) | 
					
						
							|  |  |  |             m = self._view(b) | 
					
						
							|  |  |  |             o = MyObject() | 
					
						
							|  |  |  |             b.m = m | 
					
						
							|  |  |  |             b.o = o | 
					
						
							|  |  |  |             wr = weakref.ref(o) | 
					
						
							|  |  |  |             b = m = o = None | 
					
						
							|  |  |  |             # The cycle must be broken | 
					
						
							|  |  |  |             gc.collect() | 
					
						
							| 
									
										
										
										
											2009-06-30 23:06:06 +00:00
										 |  |  |             self.assertTrue(wr() is None, wr()) | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-25 12:24:21 +01:00
										 |  |  |             # This exercises memory_clear(). | 
					
						
							|  |  |  |             m = MyView(tp(b'abc')) | 
					
						
							|  |  |  |             o = MyObject() | 
					
						
							|  |  |  |             m.x = m | 
					
						
							|  |  |  |             m.o = o | 
					
						
							|  |  |  |             wr = weakref.ref(o) | 
					
						
							|  |  |  |             m = o = None | 
					
						
							|  |  |  |             # The cycle must be broken | 
					
						
							|  |  |  |             gc.collect() | 
					
						
							|  |  |  |             self.assertTrue(wr() is None, wr()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-09 12:59:39 +00:00
										 |  |  |     def _check_released(self, m, tp): | 
					
						
							| 
									
										
										
										
											2010-12-01 02:32:32 +00:00
										 |  |  |         check = self.assertRaisesRegex(ValueError, "released") | 
					
						
							| 
									
										
										
										
											2010-09-09 12:59:39 +00:00
										 |  |  |         with check: bytes(m) | 
					
						
							|  |  |  |         with check: m.tobytes() | 
					
						
							|  |  |  |         with check: m.tolist() | 
					
						
							|  |  |  |         with check: m[0] | 
					
						
							|  |  |  |         with check: m[0] = b'x' | 
					
						
							|  |  |  |         with check: len(m) | 
					
						
							|  |  |  |         with check: m.format | 
					
						
							|  |  |  |         with check: m.itemsize | 
					
						
							|  |  |  |         with check: m.ndim | 
					
						
							|  |  |  |         with check: m.readonly | 
					
						
							|  |  |  |         with check: m.shape | 
					
						
							|  |  |  |         with check: m.strides | 
					
						
							|  |  |  |         with check: | 
					
						
							|  |  |  |             with m: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |         # str() and repr() still function | 
					
						
							|  |  |  |         self.assertIn("released memory", str(m)) | 
					
						
							|  |  |  |         self.assertIn("released memory", repr(m)) | 
					
						
							|  |  |  |         self.assertEqual(m, m) | 
					
						
							|  |  |  |         self.assertNotEqual(m, memoryview(tp(self._source))) | 
					
						
							|  |  |  |         self.assertNotEqual(m, tp(self._source)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_contextmanager(self): | 
					
						
							|  |  |  |         for tp in self._types: | 
					
						
							|  |  |  |             b = tp(self._source) | 
					
						
							|  |  |  |             m = self._view(b) | 
					
						
							|  |  |  |             with m as cm: | 
					
						
							|  |  |  |                 self.assertIs(cm, m) | 
					
						
							|  |  |  |             self._check_released(m, tp) | 
					
						
							|  |  |  |             m = self._view(b) | 
					
						
							|  |  |  |             # Can release explicitly inside the context manager | 
					
						
							|  |  |  |             with m: | 
					
						
							|  |  |  |                 m.release() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_release(self): | 
					
						
							|  |  |  |         for tp in self._types: | 
					
						
							|  |  |  |             b = tp(self._source) | 
					
						
							|  |  |  |             m = self._view(b) | 
					
						
							|  |  |  |             m.release() | 
					
						
							|  |  |  |             self._check_released(m, tp) | 
					
						
							|  |  |  |             # Can be called a second time (it's a no-op) | 
					
						
							|  |  |  |             m.release() | 
					
						
							|  |  |  |             self._check_released(m, tp) | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-18 18:57:52 +00:00
										 |  |  |     def test_writable_readonly(self): | 
					
						
							|  |  |  |         # Issue #10451: memoryview incorrectly exposes a readonly | 
					
						
							|  |  |  |         # buffer as writable causing a segfault if using mmap | 
					
						
							|  |  |  |         tp = self.ro_type | 
					
						
							|  |  |  |         if tp is None: | 
					
						
							| 
									
										
										
										
											2013-12-08 00:20:35 -06:00
										 |  |  |             self.skipTest("no read-only type to test") | 
					
						
							| 
									
										
										
										
											2011-01-18 18:57:52 +00:00
										 |  |  |         b = tp(self._source) | 
					
						
							|  |  |  |         m = self._view(b) | 
					
						
							|  |  |  |         i = io.BytesIO(b'ZZZZ') | 
					
						
							|  |  |  |         self.assertRaises(TypeError, i.readinto, m) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-25 12:24:21 +01:00
										 |  |  |     def test_getbuf_fail(self): | 
					
						
							|  |  |  |         self.assertRaises(TypeError, self._view, {}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-21 20:46:33 +01:00
										 |  |  |     def test_hash(self): | 
					
						
							|  |  |  |         # Memoryviews of readonly (hashable) types are hashable, and they | 
					
						
							| 
									
										
										
										
											2012-02-25 12:24:21 +01:00
										 |  |  |         # hash as hash(obj.tobytes()). | 
					
						
							| 
									
										
										
										
											2011-11-21 20:46:33 +01:00
										 |  |  |         tp = self.ro_type | 
					
						
							|  |  |  |         if tp is None: | 
					
						
							|  |  |  |             self.skipTest("no read-only type to test") | 
					
						
							|  |  |  |         b = tp(self._source) | 
					
						
							|  |  |  |         m = self._view(b) | 
					
						
							|  |  |  |         self.assertEqual(hash(m), hash(b"abcdef")) | 
					
						
							|  |  |  |         # Releasing the memoryview keeps the stored hash value (as with weakrefs) | 
					
						
							|  |  |  |         m.release() | 
					
						
							|  |  |  |         self.assertEqual(hash(m), hash(b"abcdef")) | 
					
						
							|  |  |  |         # Hashing a memoryview for the first time after it is released | 
					
						
							|  |  |  |         # results in an error (as with weakrefs). | 
					
						
							|  |  |  |         m = self._view(b) | 
					
						
							|  |  |  |         m.release() | 
					
						
							|  |  |  |         self.assertRaises(ValueError, hash, m) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_hash_writable(self): | 
					
						
							|  |  |  |         # Memoryviews of writable types are unhashable | 
					
						
							|  |  |  |         tp = self.rw_type | 
					
						
							|  |  |  |         if tp is None: | 
					
						
							|  |  |  |             self.skipTest("no writable type to test") | 
					
						
							|  |  |  |         b = tp(self._source) | 
					
						
							|  |  |  |         m = self._view(b) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, hash, m) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-28 21:35:09 +01:00
										 |  |  |     def test_weakref(self): | 
					
						
							|  |  |  |         # Check memoryviews are weakrefable | 
					
						
							|  |  |  |         for tp in self._types: | 
					
						
							|  |  |  |             b = tp(self._source) | 
					
						
							|  |  |  |             m = self._view(b) | 
					
						
							|  |  |  |             L = [] | 
					
						
							|  |  |  |             def callback(wr, b=b): | 
					
						
							|  |  |  |                 L.append(b) | 
					
						
							|  |  |  |             wr = weakref.ref(m, callback) | 
					
						
							|  |  |  |             self.assertIs(wr(), m) | 
					
						
							|  |  |  |             del m | 
					
						
							|  |  |  |             test.support.gc_collect() | 
					
						
							|  |  |  |             self.assertIs(wr(), None) | 
					
						
							|  |  |  |             self.assertIs(L[0], b) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-02 22:06:54 +10:00
										 |  |  |     def test_reversed(self): | 
					
						
							|  |  |  |         for tp in self._types: | 
					
						
							|  |  |  |             b = tp(self._source) | 
					
						
							|  |  |  |             m = self._view(b) | 
					
						
							|  |  |  |             aslist = list(reversed(m.tolist())) | 
					
						
							|  |  |  |             self.assertEqual(list(reversed(m)), aslist) | 
					
						
							|  |  |  |             self.assertEqual(list(reversed(m)), list(m[::-1])) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-29 14:27:23 +01:00
										 |  |  |     def test_issue22668(self): | 
					
						
							| 
									
										
										
										
											2015-01-29 17:33:31 +01:00
										 |  |  |         a = array.array('H', [256, 256, 256, 256]) | 
					
						
							|  |  |  |         x = memoryview(a) | 
					
						
							|  |  |  |         m = x.cast('B') | 
					
						
							| 
									
										
										
										
											2015-01-29 14:27:23 +01:00
										 |  |  |         b = m.cast('H') | 
					
						
							|  |  |  |         c = b[0:2] | 
					
						
							|  |  |  |         d = memoryview(b) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         del b | 
					
						
							| 
									
										
										
										
											2015-01-29 14:33:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-29 14:27:23 +01:00
										 |  |  |         self.assertEqual(c[0], 256) | 
					
						
							|  |  |  |         self.assertEqual(d[0], 256) | 
					
						
							|  |  |  |         self.assertEqual(c.format, "H") | 
					
						
							|  |  |  |         self.assertEqual(d.format, "H") | 
					
						
							| 
									
										
										
										
											2015-01-29 14:33:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-29 14:27:23 +01:00
										 |  |  |         _ = m.cast('I') | 
					
						
							|  |  |  |         self.assertEqual(c[0], 256) | 
					
						
							|  |  |  |         self.assertEqual(d[0], 256) | 
					
						
							|  |  |  |         self.assertEqual(c.format, "H") | 
					
						
							|  |  |  |         self.assertEqual(d.format, "H") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-02 22:06:54 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  | # Variations on source objects for the buffer: bytes-like objects, then arrays | 
					
						
							|  |  |  | # with itemsize > 1. | 
					
						
							|  |  |  | # NOTE: support for multi-dimensional objects is unimplemented. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BaseBytesMemoryTests(AbstractMemoryTests): | 
					
						
							|  |  |  |     ro_type = bytes | 
					
						
							|  |  |  |     rw_type = bytearray | 
					
						
							|  |  |  |     getitem_type = bytes | 
					
						
							|  |  |  |     itemsize = 1 | 
					
						
							|  |  |  |     format = 'B' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BaseArrayMemoryTests(AbstractMemoryTests): | 
					
						
							|  |  |  |     ro_type = None | 
					
						
							|  |  |  |     rw_type = lambda self, b: array.array('i', list(b)) | 
					
						
							| 
									
										
										
										
											2010-09-01 20:29:34 +00:00
										 |  |  |     getitem_type = lambda self, b: array.array('i', list(b)).tobytes() | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |     itemsize = array.array('i').itemsize | 
					
						
							|  |  |  |     format = 'i' | 
					
						
							| 
									
										
										
										
											2008-09-01 15:10:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-08 00:20:35 -06:00
										 |  |  |     @unittest.skip('XXX test should be adapted for non-byte buffers') | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |     def test_getbuffer(self): | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-08 00:20:35 -06:00
										 |  |  |     @unittest.skip('XXX NotImplementedError: tolist() only supports byte views') | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |     def test_tolist(self): | 
					
						
							|  |  |  |         pass | 
					
						
							| 
									
										
										
										
											2008-09-01 15:10:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  | # Variations on indirection levels: memoryview, slice of memoryview, | 
					
						
							|  |  |  | # slice of slice of memoryview. | 
					
						
							|  |  |  | # This is important to test allocation subtleties. | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  | class BaseMemoryviewTests: | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  |     def _view(self, obj): | 
					
						
							|  |  |  |         return memoryview(obj) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |     def _check_contents(self, tp, obj, contents): | 
					
						
							| 
									
										
										
										
											2010-11-20 19:04:17 +00:00
										 |  |  |         self.assertEqual(obj, tp(contents)) | 
					
						
							| 
									
										
										
										
											2008-12-07 20:14:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  | class BaseMemorySliceTests: | 
					
						
							|  |  |  |     source_bytes = b"XabcdefY" | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def _view(self, obj): | 
					
						
							|  |  |  |         m = memoryview(obj) | 
					
						
							|  |  |  |         return m[1:7] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |     def _check_contents(self, tp, obj, contents): | 
					
						
							| 
									
										
										
										
											2010-11-20 19:04:17 +00:00
										 |  |  |         self.assertEqual(obj[1:7], tp(contents)) | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_refs(self): | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |         for tp in self._types: | 
					
						
							|  |  |  |             m = memoryview(tp(self._source)) | 
					
						
							|  |  |  |             oldrefcount = sys.getrefcount(m) | 
					
						
							|  |  |  |             m[1:2] | 
					
						
							| 
									
										
										
										
											2010-11-20 19:04:17 +00:00
										 |  |  |             self.assertEqual(sys.getrefcount(m), oldrefcount) | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  | class BaseMemorySliceSliceTests: | 
					
						
							|  |  |  |     source_bytes = b"XabcdefY" | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def _view(self, obj): | 
					
						
							|  |  |  |         m = memoryview(obj) | 
					
						
							|  |  |  |         return m[:7][1:] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |     def _check_contents(self, tp, obj, contents): | 
					
						
							| 
									
										
										
										
											2010-11-20 19:04:17 +00:00
										 |  |  |         self.assertEqual(obj[1:7], tp(contents)) | 
					
						
							| 
									
										
										
										
											2008-08-19 22:09:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  | # Concrete test classes | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BytesMemoryviewTest(unittest.TestCase, | 
					
						
							|  |  |  |     BaseMemoryviewTests, BaseBytesMemoryTests): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_constructor(self): | 
					
						
							|  |  |  |         for tp in self._types: | 
					
						
							|  |  |  |             ob = tp(self._source) | 
					
						
							| 
									
										
										
										
											2009-06-30 23:06:06 +00:00
										 |  |  |             self.assertTrue(memoryview(ob)) | 
					
						
							|  |  |  |             self.assertTrue(memoryview(object=ob)) | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |             self.assertRaises(TypeError, memoryview) | 
					
						
							|  |  |  |             self.assertRaises(TypeError, memoryview, ob, ob) | 
					
						
							|  |  |  |             self.assertRaises(TypeError, memoryview, argument=ob) | 
					
						
							|  |  |  |             self.assertRaises(TypeError, memoryview, ob, argument=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ArrayMemoryviewTest(unittest.TestCase, | 
					
						
							|  |  |  |     BaseMemoryviewTests, BaseArrayMemoryTests): | 
					
						
							| 
									
										
										
										
											2007-11-08 02:28:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  |     def test_array_assign(self): | 
					
						
							|  |  |  |         # Issue #4569: segfault when mutating a memoryview with itemsize != 1 | 
					
						
							|  |  |  |         a = array.array('i', range(10)) | 
					
						
							|  |  |  |         m = memoryview(a) | 
					
						
							|  |  |  |         new_a = array.array('i', range(9, -1, -1)) | 
					
						
							|  |  |  |         m[:] = new_a | 
					
						
							| 
									
										
										
										
											2010-11-20 19:04:17 +00:00
										 |  |  |         self.assertEqual(a, new_a) | 
					
						
							| 
									
										
										
										
											2009-01-03 16:59:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BytesMemorySliceTest(unittest.TestCase, | 
					
						
							|  |  |  |     BaseMemorySliceTests, BaseBytesMemoryTests): | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ArrayMemorySliceTest(unittest.TestCase, | 
					
						
							|  |  |  |     BaseMemorySliceTests, BaseArrayMemoryTests): | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BytesMemorySliceSliceTest(unittest.TestCase, | 
					
						
							|  |  |  |     BaseMemorySliceSliceTests, BaseBytesMemoryTests): | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ArrayMemorySliceSliceTest(unittest.TestCase, | 
					
						
							|  |  |  |     BaseMemorySliceSliceTests, BaseArrayMemoryTests): | 
					
						
							|  |  |  |     pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-08 02:28:11 +00:00
										 |  |  | if __name__ == "__main__": | 
					
						
							| 
									
										
										
										
											2015-04-13 15:00:43 -05:00
										 |  |  |     unittest.main() |