def test_slice_stride(self):
        a = b'World_ _i_s_ _hell!'
        a_refcount = sys.getrefcount(a)

        b = containers.ArrayView(a)
        b_refcount = sys.getrefcount(b)
        self.assertEqual(sys.getrefcount(a), a_refcount + 1)

        # When slicing to a strided array view, b's refcount should not change
        # but a's refcount should increase. Check consistency with slices on
        # bytes, slicing bytes will make a copy so it doesn't affect the
        # refcount.
        c1 = a[4:-4:2]
        c2 = b[4:-4:2]
        self.assertIsInstance(c2, containers.StridedArrayView1D)
        self.assertEqual(len(c1), 6)
        self.assertEqual(len(c2), 6)
        self.assertEqual(bytes(c1), b'd is h')
        self.assertEqual(bytes(c2), b'd is h')
        self.assertEqual(c2.size, (6, ))
        self.assertEqual(c2.stride, (2, ))
        self.assertEqual(sys.getrefcount(b), b_refcount)
        self.assertEqual(sys.getrefcount(a), a_refcount + 2)

        # Deleting a slice should reduce a's refcount again, keep b's unchanged
        del c2
        self.assertEqual(sys.getrefcount(b), b_refcount)
        self.assertEqual(sys.getrefcount(a), a_refcount + 1)
 def test_init_buffer_memoryview_obj(self):
     a = b'hello'
     v = memoryview(a)
     b = containers.ArrayView(v)
     # memoryview's buffer protocol returns itself, not the underlying
     # bytes, as it manages the Py_buffer instance. So this is expected.
     self.assertIs(b.owner, v)
    def test_init_buffer(self):
        a = b'hello'
        a_refcount = sys.getrefcount(a)

        b = containers.ArrayView(a)
        self.assertIs(b.owner, a)
        self.assertEqual(len(b), 5)
        self.assertEqual(bytes(b), b'hello')
        self.assertEqual(b[2], 'l')
        self.assertEqual(sys.getrefcount(a), a_refcount + 1)

        # Not mutable
        with self.assertRaisesRegex(TypeError,
                                    "object does not support item assignment"):
            b[4] = '!'

        # b should keep a reference to a, so deleting the local reference
        # shouldn't affect it
        del a
        self.assertTrue(sys.getrefcount(b.owner), a_refcount)
        self.assertEqual(b[2], 'l')

        # Now, if we delete b, a should not be referenced by anything anymore
        a = b.owner
        del b
        self.assertTrue(sys.getrefcount(a), a_refcount)
    def test_init_buffer_empty(self):
        a = b''
        a_refcount = sys.getrefcount(a)

        b = containers.ArrayView(a)
        self.assertIs(b.owner, None)
        self.assertEqual(len(b), 0)
        self.assertEqual(sys.getrefcount(a), a_refcount)
 def test_init_buffer_unexpected_stride(self):
     a = memoryview(b'hello')[::2]
     self.assertEqual(bytes(a), b'hlo')
     # Error emitted by memoryview, not us
     with self.assertRaisesRegex(
             BufferError,
             "memoryview: underlying buffer is not C-contiguous"):
         b = containers.ArrayView(a)
 def test_init(self):
     a = containers.ArrayView()
     b = containers.MutableArrayView()
     self.assertIs(a.owner, None)
     self.assertIs(b.owner, None)
     self.assertEqual(len(a), 0)
     self.assertEqual(len(b), 0)
     self.assertEqual(bytes(a), b'')
     self.assertEqual(bytes(b), b'')
    def test_slice_stride_empty(self):
        data = b'hello'
        data_refcount = sys.getrefcount(data)

        # slice.start = slice.stop
        a = containers.ArrayView(data)[7:8:2]
        self.assertEqual(len(a), 0)

        # Empty view, original data not referenced at all
        self.assertIs(a.owner, None)
        self.assertEqual(sys.getrefcount(data), data_refcount)
    def test_slice_stride_negative(self):
        a = b'World_ _i_s_ _hell!'
        b = containers.ArrayView(a)

        # Check consistency with slices on bytes
        c1 = a[-5:3:-2]  # like [4:-4:2] above, but reverted
        c2 = b[-5:3:-2]
        self.assertEqual(len(c1), 6)
        self.assertEqual(len(c2), 6)
        self.assertEqual(bytes(c1), b'h si d')  # like b'd is h' but reverted
        self.assertEqual(bytes(c2), b'h si d')
        self.assertEqual(c2.size, (6, ))
        self.assertEqual(c2.stride, (-2, ))
    def test_slice(self):
        a = b'World is hell!'
        a_refcount = sys.getrefcount(a)

        b = containers.ArrayView(a)
        b_refcount = sys.getrefcount(b)
        self.assertEqual(sys.getrefcount(a), a_refcount + 1)

        # When slicing, b's refcount should not change but a's refcount should
        # increase
        c = b[4:-4]
        self.assertIsInstance(c, containers.ArrayView)
        self.assertEqual(bytes(c), b'd is h')
        self.assertEqual(sys.getrefcount(b), b_refcount)
        self.assertEqual(sys.getrefcount(a), a_refcount + 2)

        # Deleting a slice should reduce a's refcount again, keep b's unchanged
        del c
        self.assertEqual(sys.getrefcount(b), b_refcount)
        self.assertEqual(sys.getrefcount(a), a_refcount + 1)
    def test_convert_memoryview(self):
        a = b'World is hell!'
        a_refcount = sys.getrefcount(a)

        b = containers.ArrayView(a)
        b_refcount = sys.getrefcount(b)
        self.assertEqual(sys.getrefcount(a), a_refcount + 1)

        c = memoryview(b)
        # Unlike slicing, ArrayView's buffer protocol returns a reference to
        # itself -- it needs to be kept around because the Py_buffer refers to
        # its internals for size. Also returning a reference to the underlying
        # buffer would mean the underlying buffer's releasebuffer function gets
        # called instead of ours which is *not* wanted.
        self.assertIs(c.obj, b)
        self.assertEqual(sys.getrefcount(b), b_refcount + 1)
        self.assertEqual(sys.getrefcount(a), a_refcount + 1)

        with self.assertRaisesRegex(TypeError, "cannot modify read-only memory"):
            c[-1] = ord('?')
示例#11
0
 def test_init_array(self):
     a = array.array('f', [1.0, 4.5, 7.9])
     b = containers.ArrayView(a)
     self.assertIs(b.owner, a)
     self.assertEqual(len(b), 3 * 4)
示例#12
0
 def test_slice_stride_reverse(self):
     # slice.stop = -1
     a = containers.ArrayView(b'hello')[::-1]
     self.assertEqual(len(a), 5)
     self.assertEqual(bytes(a), b'olleh')
示例#13
0
 def test_slice_invalid(self):
     with self.assertRaisesRegex(ValueError, "slice step cannot be zero"):
         containers.ArrayView()[::0]
 def test_slice_empty(self):
     # slice.start = slice.stop
     a = containers.ArrayView(b'hello')[7:8]
     self.assertEqual(len(a), 0)