Commits

Brian Kearns  committed 922c7ee

more buffer cleanups

  • Participants
  • Parent commits 3c1786c

Comments (0)

Files changed (17)

File lib-python/2.7/test/test_memoryview.py

                 # very inconsisten on CPython. In PyPy, memoryview supports
                 # the buffer interface, and thus the following comparison
                 # succeeds. See also the comment in
-                # pypy.modules.__builtin__.interp_memoryview.W_MemoryView.descr_buffer
+                # pypy.objspace.std.memoryview.W_MemoryView.descr_buffer
                 #
                 # Comparison with objects which don't support the buffer API
                 self.assertFalse(m == u"abcdef", "%s %s" % (self, tp))

File pypy/interpreter/test/test_buffer.py

 import py
-from pypy.module.__builtin__.interp_memoryview import W_Buffer
 from rpython.tool.udir import udir
 
 testdir = udir.ensure('test_buffer', dir=1)
 
 
 class TestBuffer:
-
     def test_buffer_w(self):
         space = self.space
         w_hello = space.wrap('hello world')
         assert buf.getlength() == 11
         assert buf.as_str() == 'hello world'
         assert buf.getslice(1, 6, 1, 5) == 'ello '
-        assert space.buffer_w(W_Buffer(buf)) is buf
+        assert space.buffer_w(space.newbuffer(buf)) is buf
         assert space.bufferstr_w(w_hello) == 'hello world'
-        assert space.bufferstr_w(W_Buffer(space.buffer_w(w_hello))) == 'hello world'
+        assert space.bufferstr_w(space.newbuffer(space.buffer_w(w_hello))) == 'hello world'
         space.raises_w(space.w_TypeError, space.buffer_w, space.wrap(5))
 
     def test_file_write(self):
         space = self.space
-        w_buffer = W_Buffer(space.buffer_w(space.wrap('hello world')))
+        w_buffer = space.newbuffer(space.buffer_w(space.wrap('hello world')))
         filename = str(testdir.join('test_file_write'))
         space.appexec([w_buffer, space.wrap(filename)], """(buffer, filename):
             f = open(filename, 'wb')
                        space.bufferstr_w, space.wrap(u'\xe9'))
 
 
-# Note: some app-level tests for buffer are in module/__builtin__/test/.
+# Note: some app-level tests for buffer are in objspace/std/test/test_memoryview.py.

File pypy/module/__builtin__/__init__.py

 
     interpleveldefs = {
         # constants
+        '__debug__'     : '(space.w_True)',      # XXX
         'None'          : '(space.w_None)',
         'False'         : '(space.w_False)',
         'True'          : '(space.w_True)',
-        '__debug__'     : '(space.w_True)',      # XXX
-        'type'          : '(space.w_type)',
-        'object'        : '(space.w_object)',
         'bytes'         : '(space.w_str)',
-        'unicode'       : '(space.w_unicode)',
-        'buffer'        : 'interp_memoryview.W_Buffer',
-        'memoryview'    : 'interp_memoryview.W_MemoryView',
 
         'file'          : 'state.get(space).w_file',
         'open'          : 'state.get(space).w_file',

File pypy/module/__builtin__/interp_memoryview.py

-"""
-Implementation of the 'buffer' and 'memoryview' types.
-"""
-import operator
-
-from pypy.interpreter import buffer
-from pypy.interpreter.baseobjspace import W_Root
-from pypy.interpreter.error import OperationError
-from pypy.interpreter.gateway import interp2app, unwrap_spec
-from pypy.interpreter.typedef import TypeDef, GetSetProperty
-from rpython.rlib.objectmodel import compute_hash
-from rpython.rlib.rstring import StringBuilder
-
-
-def _buffer_setitem(space, buf, w_index, newstring):
-    start, stop, step, size = space.decode_index4(w_index, buf.getlength())
-    if step == 0:  # index only
-        if len(newstring) != 1:
-            msg = 'buffer[index]=x: x must be a single character'
-            raise OperationError(space.w_TypeError, space.wrap(msg))
-        char = newstring[0]   # annotator hint
-        buf.setitem(start, char)
-    elif step == 1:
-        if len(newstring) != size:
-            msg = "right operand length must match slice length"
-            raise OperationError(space.w_ValueError, space.wrap(msg))
-        buf.setslice(start, newstring)
-    else:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("buffer object does not support"
-                                        " slicing with a step"))
-
-
-class W_Buffer(W_Root):
-    """Implement the built-in 'buffer' type as a wrapper around
-    an interp-level buffer.
-    """
-
-    def __init__(self, buf):
-        self.buf = buf
-
-    def buffer_w(self, space):
-        return self.buf
-
-    @staticmethod
-    @unwrap_spec(offset=int, size=int)
-    def descr_new_buffer(space, w_subtype, w_object, offset=0, size=-1):
-        if space.isinstance_w(w_object, space.w_unicode):
-            # unicode objects support the old buffer interface
-            # but not the new buffer interface (change in python 2.7)
-            from rpython.rlib.rstruct.unichar import pack_unichar, UNICODE_SIZE
-            unistr = space.unicode_w(w_object)
-            builder = StringBuilder(len(unistr) * UNICODE_SIZE)
-            for unich in unistr:
-                pack_unichar(unich, builder)
-            from pypy.interpreter.buffer import StringBuffer
-            buf = StringBuffer(builder.build())
-        else:
-            buf = space.buffer_w(w_object)
-
-        if offset == 0 and size == -1:
-            return W_Buffer(buf)
-        # handle buffer slices
-        if offset < 0:
-            raise OperationError(space.w_ValueError,
-                                 space.wrap("offset must be zero or positive"))
-        if size < -1:
-            raise OperationError(space.w_ValueError,
-                                 space.wrap("size must be zero or positive"))
-        if isinstance(buf, buffer.RWBuffer):
-            buf = buffer.RWSubBuffer(buf, offset, size)
-        else:
-            buf = buffer.SubBuffer(buf, offset, size)
-        return W_Buffer(buf)
-
-    def descr_len(self, space):
-        return space.wrap(self.buf.getlength())
-
-    def descr_getitem(self, space, w_index):
-        start, stop, step, size = space.decode_index4(w_index, self.buf.getlength())
-        if step == 0:  # index only
-            return space.wrap(self.buf.getitem(start))
-        res = self.buf.getslice(start, stop, step, size)
-        return space.wrap(res)
-
-    @unwrap_spec(newstring='bufferstr')
-    def descr_setitem(self, space, w_index, newstring):
-        if not isinstance(self.buf, buffer.RWBuffer):
-            raise OperationError(space.w_TypeError,
-                                 space.wrap("buffer is read-only"))
-        _buffer_setitem(space, self.buf, w_index, newstring)
-
-    def descr_str(self, space):
-        return space.wrap(self.buf.as_str())
-
-    @unwrap_spec(other='bufferstr')
-    def descr_add(self, space, other):
-        return space.wrap(self.buf.as_str() + other)
-
-    def _make_descr__cmp(name):
-        def descr__cmp(self, space, w_other):
-            if not isinstance(w_other, W_Buffer):
-                return space.w_NotImplemented
-            # xxx not the most efficient implementation
-            str1 = self.buf.as_str()
-            str2 = w_other.buf.as_str()
-            return space.wrap(getattr(operator, name)(str1, str2))
-        descr__cmp.func_name = name
-        return descr__cmp
-
-    descr_eq = _make_descr__cmp('eq')
-    descr_ne = _make_descr__cmp('ne')
-    descr_lt = _make_descr__cmp('lt')
-    descr_le = _make_descr__cmp('le')
-    descr_gt = _make_descr__cmp('gt')
-    descr_ge = _make_descr__cmp('ge')
-
-    def descr_hash(self, space):
-        return space.wrap(compute_hash(self.buf.as_str()))
-
-    def descr_mul(self, space, w_times):
-        # xxx not the most efficient implementation
-        w_string = space.wrap(self.buf.as_str())
-        # use the __mul__ method instead of space.mul() so that we
-        # return NotImplemented instead of raising a TypeError
-        return space.call_method(w_string, '__mul__', w_times)
-
-    def descr_repr(self, space):
-        if isinstance(self.buf, buffer.RWBuffer):
-            info = 'read-write buffer'
-        else:
-            info = 'read-only buffer'
-        addrstring = self.getaddrstring(space)
-
-        return space.wrap("<%s for 0x%s, size %d>" %
-                          (info, addrstring, self.buf.getlength()))
-
-W_Buffer.typedef = TypeDef(
-    "buffer",
-    __doc__ = """\
-buffer(object [, offset[, size]])
-
-Create a new buffer object which references the given object.
-The buffer will reference a slice of the target object from the
-start of the object (or at the specified offset). The slice will
-extend to the end of the target object (or with the specified size).
-""",
-    __new__ = interp2app(W_Buffer.descr_new_buffer),
-    __len__ = interp2app(W_Buffer.descr_len),
-    __getitem__ = interp2app(W_Buffer.descr_getitem),
-    __setitem__ = interp2app(W_Buffer.descr_setitem),
-    __str__ = interp2app(W_Buffer.descr_str),
-    __add__ = interp2app(W_Buffer.descr_add),
-    __eq__ = interp2app(W_Buffer.descr_eq),
-    __ne__ = interp2app(W_Buffer.descr_ne),
-    __lt__ = interp2app(W_Buffer.descr_lt),
-    __le__ = interp2app(W_Buffer.descr_le),
-    __gt__ = interp2app(W_Buffer.descr_gt),
-    __ge__ = interp2app(W_Buffer.descr_ge),
-    __hash__ = interp2app(W_Buffer.descr_hash),
-    __mul__ = interp2app(W_Buffer.descr_mul),
-    __rmul__ = interp2app(W_Buffer.descr_mul),
-    __repr__ = interp2app(W_Buffer.descr_repr),
-)
-W_Buffer.typedef.acceptable_as_base_class = False
-
-
-class W_MemoryView(W_Root):
-    """Implement the built-in 'memoryview' type as a wrapper around
-    an interp-level buffer.
-    """
-
-    def __init__(self, buf):
-        self.buf = buf
-
-    def buffer_w(self, space):
-        return self.buf
-
-    @staticmethod
-    def descr_new_memoryview(space, w_subtype, w_object):
-        return W_MemoryView(space.buffer_w(w_object))
-
-    def _make_descr__cmp(name):
-        def descr__cmp(self, space, w_other):
-            if isinstance(w_other, W_MemoryView):
-                # xxx not the most efficient implementation
-                str1 = self.as_str()
-                str2 = w_other.as_str()
-                return space.wrap(getattr(operator, name)(str1, str2))
-
-            try:
-                buf = space.buffer_w(w_other)
-            except OperationError, e:
-                if not e.match(space, space.w_TypeError):
-                    raise
-                return space.w_NotImplemented
-            else:
-                str1 = self.as_str()
-                str2 = buf.as_str()
-                return space.wrap(getattr(operator, name)(str1, str2))
-        descr__cmp.func_name = name
-        return descr__cmp
-
-    descr_eq = _make_descr__cmp('eq')
-    descr_ne = _make_descr__cmp('ne')
-    descr_lt = _make_descr__cmp('lt')
-    descr_le = _make_descr__cmp('le')
-    descr_gt = _make_descr__cmp('gt')
-    descr_ge = _make_descr__cmp('ge')
-
-    def as_str(self):
-        return self.buf.as_str()
-
-    def getlength(self):
-        return self.buf.getlength()
-
-    def getslice(self, start, stop):
-        if start < 0:
-            start = 0
-        size = stop - start
-        if size < 0:
-            size = 0
-        buf = self.buf
-        if isinstance(buf, buffer.RWBuffer):
-            buf = buffer.RWSubBuffer(buf, start, size)
-        else:
-            buf = buffer.SubBuffer(buf, start, size)
-        return W_MemoryView(buf)
-
-    def descr_buffer(self, space):
-        """
-        Note that memoryview() is very inconsistent in CPython: it does not
-        support the buffer interface but does support the new buffer
-        interface: as a result, it is possible to pass memoryview to
-        e.g. socket.send() but not to file.write().  For simplicity and
-        consistency, in PyPy memoryview DOES support buffer(), which means
-        that it is accepted in more places than CPython.
-        """
-        return space.wrap(self.buf)
-
-    def descr_tobytes(self, space):
-        return space.wrap(self.as_str())
-
-    def descr_tolist(self, space):
-        buf = self.buf
-        result = []
-        for i in range(buf.getlength()):
-            result.append(space.wrap(ord(buf.getitem(i))))
-        return space.newlist(result)
-
-    def descr_getitem(self, space, w_index):
-        start, stop, step = space.decode_index(w_index, self.getlength())
-        if step == 0:  # index only
-            return space.wrap(self.buf.getitem(start))
-        elif step == 1:
-            res = self.getslice(start, stop)
-            return space.wrap(res)
-        else:
-            raise OperationError(space.w_ValueError,
-                space.wrap("memoryview object does not support"
-                           " slicing with a step"))
-
-    @unwrap_spec(newstring='bufferstr')
-    def descr_setitem(self, space, w_index, newstring):
-        if not isinstance(self.buf, buffer.RWBuffer):
-            raise OperationError(space.w_TypeError,
-                                 space.wrap("cannot modify read-only memory"))
-        _buffer_setitem(space, self.buf, w_index, newstring)
-
-    def descr_len(self, space):
-        return space.wrap(self.buf.getlength())
-
-    def w_get_format(self, space):
-        return space.wrap("B")
-
-    def w_get_itemsize(self, space):
-        return space.wrap(1)
-
-    def w_get_ndim(self, space):
-        return space.wrap(1)
-
-    def w_is_readonly(self, space):
-        return space.wrap(not isinstance(self.buf, buffer.RWBuffer))
-
-    def w_get_shape(self, space):
-        return space.newtuple([space.wrap(self.getlength())])
-
-    def w_get_strides(self, space):
-        return space.newtuple([space.wrap(1)])
-
-    def w_get_suboffsets(self, space):
-        # I've never seen anyone filling this field
-        return space.w_None
-
-W_MemoryView.typedef = TypeDef(
-    "memoryview",
-    __doc__ = """\
-Create a new memoryview object which references the given object.
-""",
-    __new__     = interp2app(W_MemoryView.descr_new_memoryview),
-    __eq__      = interp2app(W_MemoryView.descr_eq),
-    __ge__      = interp2app(W_MemoryView.descr_ge),
-    __getitem__ = interp2app(W_MemoryView.descr_getitem),
-    __gt__      = interp2app(W_MemoryView.descr_gt),
-    __le__      = interp2app(W_MemoryView.descr_le),
-    __len__     = interp2app(W_MemoryView.descr_len),
-    __lt__      = interp2app(W_MemoryView.descr_lt),
-    __ne__      = interp2app(W_MemoryView.descr_ne),
-    __setitem__ = interp2app(W_MemoryView.descr_setitem),
-    tobytes     = interp2app(W_MemoryView.descr_tobytes),
-    tolist      = interp2app(W_MemoryView.descr_tolist),
-    format      = GetSetProperty(W_MemoryView.w_get_format),
-    itemsize    = GetSetProperty(W_MemoryView.w_get_itemsize),
-    ndim        = GetSetProperty(W_MemoryView.w_get_ndim),
-    readonly    = GetSetProperty(W_MemoryView.w_is_readonly),
-    shape       = GetSetProperty(W_MemoryView.w_get_shape),
-    strides     = GetSetProperty(W_MemoryView.w_get_strides),
-    suboffsets  = GetSetProperty(W_MemoryView.w_get_suboffsets),
-    )
-W_MemoryView.typedef.acceptable_as_base_class = False

File pypy/module/__builtin__/test/test_buffer.py

-"""Tests some behaviour of the buffer type that is not tested in
-lib-python/2.5.2/test/test_types.py where the stdlib buffer tests live."""
-
-class AppTestBuffer:
-    spaceconfig = dict(usemodules=['array'])
-
-    def test_init(self):
-        class A(object):
-            def __buffer__(self):
-                return buffer('123')
-        raises(TypeError, buffer, A())
-
-    def test_unicode_buffer(self):
-        import sys
-        b = buffer(u"ab")
-        if sys.maxunicode == 65535: # UCS2 build
-            assert len(b) == 4
-            if sys.byteorder == "big":
-                assert b[0:4] == "\x00a\x00b"
-            else:
-                assert b[0:4] == "a\x00b\x00"
-        else: # UCS4 build
-            assert len(b) == 8
-            if sys.byteorder == "big":
-                assert b[0:8] == "\x00\x00\x00a\x00\x00\x00b"
-            else:
-                assert b[0:8] == "a\x00\x00\x00b\x00\x00\x00"
-
-    def test_array_buffer(self):
-        import array
-        b = buffer(array.array("B", [1, 2, 3]))
-        assert len(b) == 3
-        assert b[0:3] == "\x01\x02\x03"
-
-    def test_nonzero(self):
-        assert buffer('\x00')
-        assert not buffer('')
-        import array
-        assert buffer(array.array("B", [0]))
-        assert not buffer(array.array("B", []))
-
-    def test_str(self):
-        assert str(buffer('hello')) == 'hello'
-
-    def test_repr(self):
-        # from 2.5.2 lib tests
-        assert repr(buffer('hello')).startswith('<read-only buffer for 0x')
-
-    def test_add(self):
-        assert buffer('abc') + 'def' == 'abcdef'
-        import array
-        assert buffer('abc') + array.array('c', 'def') == 'abcdef'
-
-    def test_cmp(self):
-        assert buffer('ab') != 'ab'
-        assert not ('ab' == buffer('ab'))
-        assert buffer('ab') == buffer('ab')
-        assert not (buffer('ab') != buffer('ab'))
-        assert not (buffer('ab') <  buffer('ab'))
-        assert buffer('ab') <= buffer('ab')
-        assert not (buffer('ab') >  buffer('ab'))
-        assert buffer('ab') >= buffer('ab')
-        assert buffer('ab') != buffer('abc')
-        assert buffer('ab') <  buffer('abc')
-        assert buffer('ab') <= buffer('ab')
-        assert buffer('ab') >  buffer('aa')
-        assert buffer('ab') >= buffer('ab')
-
-    def test_hash(self):
-        assert hash(buffer('hello')) == hash('hello')
-
-    def test_mul(self):
-        assert buffer('ab') * 5 == 'ababababab'
-        assert buffer('ab') * (-2) == ''
-        assert 5 * buffer('ab') == 'ababababab'
-        assert (-2) * buffer('ab') == ''
-
-    def test_offset_size(self):
-        b = buffer('hello world', 6)
-        assert len(b) == 5
-        assert b[0] == 'w'
-        assert b[:] == 'world'
-        raises(IndexError, 'b[5]')
-        b = buffer(b, 2)
-        assert len(b) == 3
-        assert b[0] == 'r'
-        assert b[:] == 'rld'
-        raises(IndexError, 'b[3]')
-        b = buffer('hello world', 1, 8)
-        assert len(b) == 8
-        assert b[0] == 'e'
-        assert b[:] == 'ello wor'
-        raises(IndexError, 'b[8]')
-        b = buffer(b, 2, 3)
-        assert len(b) == 3
-        assert b[2] == ' '
-        assert b[:] == 'lo '
-        raises(IndexError, 'b[3]')
-        b = buffer('hello world', 55)
-        assert len(b) == 0
-        assert b[:] == ''
-        b = buffer('hello world', 6, 999)
-        assert len(b) == 5
-        assert b[:] == 'world'
-
-        raises(ValueError, buffer, "abc", -1)
-        raises(ValueError, buffer, "abc", 0, -2)
-
-    def test_rw_offset_size(self):
-        import array
-
-        a = array.array("c", 'hello world')
-        b = buffer(a, 6)
-        assert len(b) == 5
-        assert b[0] == 'w'
-        assert b[:] == 'world'
-        raises(IndexError, 'b[5]')
-        b[0] = 'W'
-        assert str(b) == 'World'
-        assert a.tostring() == 'hello World'
-        b[:] = '12345'
-        assert a.tostring() == 'hello 12345'
-        raises(IndexError, 'b[5] = "."')
-        b[4:2] = ''
-        assert a.tostring() == 'hello 12345'
-
-        b = buffer(b, 2)
-        assert len(b) == 3
-        assert b[0] == '3'
-        assert b[:] == '345'
-        raises(IndexError, 'b[3]')
-        b[1] = 'X'
-        assert a.tostring() == 'hello 123X5'
-        raises(IndexError, 'b[3] = "."')
-
-        a = array.array("c", 'hello world')
-        b = buffer(a, 1, 8)
-        assert len(b) == 8
-        assert b[0] == 'e'
-        assert b[:] == 'ello wor'
-        raises(IndexError, 'b[8]')
-        b[0] = 'E'
-        assert str(b) == 'Ello wor'
-        assert a.tostring() == 'hEllo world'
-        b[:] = '12345678'
-        assert a.tostring() == 'h12345678ld'
-        raises(IndexError, 'b[8] = "."')
-
-        b = buffer(b, 2, 3)
-        assert len(b) == 3
-        assert b[2] == '5'
-        assert b[:] == '345'
-        raises(IndexError, 'b[3]')
-        b[1] = 'X'
-        assert a.tostring() == 'h123X5678ld'
-        raises(IndexError, 'b[3] = "."')
-
-        b = buffer(a, 55)
-        assert len(b) == 0
-        assert b[:] == ''
-        b = buffer(a, 6, 999)
-        assert len(b) == 5
-        assert b[:] == '678ld'
-
-        raises(ValueError, buffer, a, -1)
-        raises(ValueError, buffer, a, 0, -2)
-
-    def test_slice(self):
-        # Test extended slicing by comparing with list slicing.
-        s = "".join(chr(c) for c in list(range(255, -1, -1)))
-        b = buffer(s)
-        indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300)
-        for start in indices:
-            for stop in indices:
-                # Skip step 0 (invalid)
-                for step in indices[1:]:
-                    assert b[start:stop:step] == s[start:stop:step]
-
-    def test_getitem_only_ints(self):
-        class MyInt(object):
-          def __init__(self, x):
-            self.x = x
-
-          def __int__(self):
-            return self.x
-
-        buf = buffer('hello world')
-        raises(TypeError, "buf[MyInt(0)]")
-        raises(TypeError, "buf[MyInt(0):MyInt(5)]")
-
-
-class AppTestMemoryView:
-    def test_basic(self):
-        v = memoryview("abc")
-        assert v.tobytes() == "abc"
-        assert len(v) == 3
-        assert list(v) == ['a', 'b', 'c']
-        assert v.tolist() == [97, 98, 99]
-        assert v[1] == "b"
-        assert v[-1] == "c"
-        raises(TypeError, "v[1] = 'x'")
-        assert v.readonly is True
-        w = v[1:234]
-        assert isinstance(w, memoryview)
-        assert len(w) == 2
-
-    def test_rw(self):
-        data = bytearray('abcefg')
-        v = memoryview(data)
-        assert v.readonly is False
-        v[0] = 'z'
-        assert data == bytearray(eval("b'zbcefg'"))
-        v[1:4] = '123'
-        assert data == bytearray(eval("b'z123fg'"))
-        raises((ValueError, TypeError), "v[2] = 'spam'")
-
-    def test_memoryview_attrs(self):
-        v = memoryview("a"*100)
-        assert v.format == "B"
-        assert v.itemsize == 1
-        assert v.shape == (100,)
-        assert v.ndim == 1
-        assert v.strides == (1,)
-
-    def test_suboffsets(self):
-        v = memoryview("a"*100)
-        assert v.suboffsets == None
-        v = memoryview(buffer("a"*100, 2))
-        assert v.shape == (98,)
-        assert v.suboffsets == None
-
-    def test_compare(self):
-        assert memoryview("abc") == "abc"
-        assert memoryview("abc") == bytearray("abc")
-        assert memoryview("abc") != 3

File pypy/module/__builtin__/test/test_builtin.py

         else:
             cls.w_safe_runtimerror = cls.space.wrap(sys.version_info < (2, 6))
 
+    def test_builtin_names(self):
+        import __builtin__
+        assert __builtin__.None is None
+        assert __builtin__.False is False
+        assert __builtin__.True is True
+
+        assert __builtin__.buffer is buffer
+        assert __builtin__.bytes is str
+        assert __builtin__.dict is dict
+        assert __builtin__.memoryview is memoryview
+
     def test_bytes_alias(self):
         assert bytes is str
         assert isinstance(eval("b'hi'"), str)

File pypy/module/__pypy__/bytebuffer.py

 
 from pypy.interpreter.buffer import RWBuffer
 from pypy.interpreter.gateway import unwrap_spec
-from pypy.module.__builtin__.interp_memoryview import W_Buffer
 
 
 class ByteBuffer(RWBuffer):
-
     def __init__(self, len):
         self.data = ['\x00'] * len
 
 
 @unwrap_spec(length=int)
 def bytebuffer(space, length):
-    return W_Buffer(ByteBuffer(length))
+    return space.newbuffer(ByteBuffer(length))

File pypy/module/_cffi_backend/cbuffer.py

 from pypy.interpreter.gateway import unwrap_spec, interp2app
 from pypy.interpreter.typedef import TypeDef, make_weakref_descr
 from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypearray
-from pypy.module.__builtin__.interp_memoryview import W_Buffer
+from pypy.objspace.std.memoryview import W_Buffer
 
 from rpython.rtyper.annlowlevel import llstr
 from rpython.rtyper.lltypesystem import rffi

File pypy/module/_io/interp_bufferedio.py

     TypeDef, GetSetProperty, generic_new_descr, interp_attrproperty_w)
 from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
 from pypy.interpreter.buffer import RWBuffer
-from pypy.module.__builtin__.interp_memoryview import W_Buffer
 from rpython.rlib.rstring import StringBuilder
 from rpython.rlib.rarithmetic import r_longlong, intmask
 from rpython.rlib import rposix
 
     def _raw_read(self, space, buffer, start, length):
         length = intmask(length)
-        w_buf = W_Buffer(RawBuffer(buffer, start, length))
+        w_buf = space.newbuffer(RawBuffer(buffer, start, length))
         while True:
             try:
                 w_size = space.call_method(self.w_raw, "readinto", w_buf)

File pypy/module/cpyext/api.py

 from pypy.interpreter.nestedscope import Cell
 from pypy.interpreter.module import Module
 from pypy.interpreter.function import StaticMethod
+from pypy.objspace.std.memoryview import W_MemoryView
 from pypy.objspace.std.sliceobject import W_SliceObject
 from pypy.module.__builtin__.descriptor import W_Property
 from pypy.module.__builtin__.interp_classobj import W_ClassObject
-from pypy.module.__builtin__.interp_memoryview import W_MemoryView
 from pypy.module.micronumpy.base import W_NDimArray
 from rpython.rlib.entrypoint import entrypoint_lowlevel
 from rpython.rlib.rposix import is_valid_fd, validate_fd

File pypy/module/cpyext/bufferobject.py

 from rpython.rtyper.lltypesystem import rffi, lltype
+from pypy.interpreter.buffer import StringBuffer, SubBuffer
+from pypy.interpreter.error import OperationError
 from pypy.module.cpyext.api import (
     cpython_api, Py_ssize_t, cpython_struct, bootstrap_function,
     PyObjectFields, PyObject)
 from pypy.module.cpyext.pyobject import make_typedescr, Py_DecRef, make_ref
-from pypy.interpreter.buffer import StringBuffer, SubBuffer
-from pypy.interpreter.error import OperationError
-from pypy.module.__builtin__.interp_memoryview import W_Buffer
 from pypy.module.array.interp_array import ArrayBuffer
+from pypy.objspace.std.memoryview import W_Buffer
 
 
 PyBufferObjectStruct = lltype.ForwardReference()

File pypy/module/cpyext/slotdefs.py

 from pypy.module.cpyext.pyobject import from_ref
 from pypy.module.cpyext.pyerrors import PyErr_Occurred
 from pypy.module.cpyext.state import State
-from pypy.module.__builtin__.interp_memoryview import W_Buffer
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.buffer import Buffer
 from pypy.interpreter.argument import Arguments
         size = generic_cpy_call(space, func_target, w_self, index, ptr)
         if size < 0:
             space.fromcache(State).check_and_raise_exception(always=True)
-        return W_Buffer(CPyBuffer(ptr[0], size, w_self))
+        return space.newbuffer(CPyBuffer(ptr[0], size, w_self))
 
 def get_richcmp_func(OP_CONST):
     def inner(space, w_self, w_args, func):

File pypy/module/micronumpy/ndarray.py

 from rpython.rlib.rawstorage import RAW_STORAGE_PTR
 from rpython.rtyper.lltypesystem import rffi
 from rpython.tool.sourcetools import func_with_new_name
-from pypy.module.__builtin__.interp_memoryview import W_Buffer
 from pypy.module.micronumpy import descriptor, ufuncs, boxes, arrayops, loop, \
     support, constants as NPY
 from pypy.module.micronumpy.appbridge import get_appbridge_cache
         return self.implementation.get_buffer(space)
 
     def descr_get_data(self, space):
-        return W_Buffer(self.buffer_w(space))
+        return space.newbuffer(self.buffer_w(space))
 
     @unwrap_spec(offset=int, axis1=int, axis2=int)
     def descr_diagonal(self, space, offset=0, axis1=0, axis2=1):

File pypy/objspace/std/memoryview.py

+"""
+Implementation of the 'buffer' and 'memoryview' types.
+"""
+import operator
+
+from pypy.interpreter import buffer
+from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter.error import OperationError
+from pypy.interpreter.gateway import interp2app, unwrap_spec
+from pypy.interpreter.typedef import TypeDef, GetSetProperty
+from rpython.rlib.objectmodel import compute_hash
+from rpython.rlib.rstring import StringBuilder
+
+
+def _buffer_setitem(space, buf, w_index, newstring):
+    start, stop, step, size = space.decode_index4(w_index, buf.getlength())
+    if step == 0:  # index only
+        if len(newstring) != 1:
+            msg = 'buffer[index]=x: x must be a single character'
+            raise OperationError(space.w_TypeError, space.wrap(msg))
+        char = newstring[0]   # annotator hint
+        buf.setitem(start, char)
+    elif step == 1:
+        if len(newstring) != size:
+            msg = "right operand length must match slice length"
+            raise OperationError(space.w_ValueError, space.wrap(msg))
+        buf.setslice(start, newstring)
+    else:
+        raise OperationError(space.w_ValueError,
+                             space.wrap("buffer object does not support"
+                                        " slicing with a step"))
+
+
+class W_Buffer(W_Root):
+    """Implement the built-in 'buffer' type as a wrapper around
+    an interp-level buffer.
+    """
+
+    def __init__(self, buf):
+        assert isinstance(buf, buffer.Buffer)
+        self.buf = buf
+
+    def buffer_w(self, space):
+        return self.buf
+
+    @staticmethod
+    @unwrap_spec(offset=int, size=int)
+    def descr_new_buffer(space, w_subtype, w_object, offset=0, size=-1):
+        if space.isinstance_w(w_object, space.w_unicode):
+            # unicode objects support the old buffer interface
+            # but not the new buffer interface (change in python 2.7)
+            from rpython.rlib.rstruct.unichar import pack_unichar, UNICODE_SIZE
+            unistr = space.unicode_w(w_object)
+            builder = StringBuilder(len(unistr) * UNICODE_SIZE)
+            for unich in unistr:
+                pack_unichar(unich, builder)
+            from pypy.interpreter.buffer import StringBuffer
+            buf = StringBuffer(builder.build())
+        else:
+            buf = space.buffer_w(w_object)
+
+        if offset == 0 and size == -1:
+            return W_Buffer(buf)
+        # handle buffer slices
+        if offset < 0:
+            raise OperationError(space.w_ValueError,
+                                 space.wrap("offset must be zero or positive"))
+        if size < -1:
+            raise OperationError(space.w_ValueError,
+                                 space.wrap("size must be zero or positive"))
+        if isinstance(buf, buffer.RWBuffer):
+            buf = buffer.RWSubBuffer(buf, offset, size)
+        else:
+            buf = buffer.SubBuffer(buf, offset, size)
+        return W_Buffer(buf)
+
+    def descr_len(self, space):
+        return space.wrap(self.buf.getlength())
+
+    def descr_getitem(self, space, w_index):
+        start, stop, step, size = space.decode_index4(w_index, self.buf.getlength())
+        if step == 0:  # index only
+            return space.wrap(self.buf.getitem(start))
+        res = self.buf.getslice(start, stop, step, size)
+        return space.wrap(res)
+
+    @unwrap_spec(newstring='bufferstr')
+    def descr_setitem(self, space, w_index, newstring):
+        if not isinstance(self.buf, buffer.RWBuffer):
+            raise OperationError(space.w_TypeError,
+                                 space.wrap("buffer is read-only"))
+        _buffer_setitem(space, self.buf, w_index, newstring)
+
+    def descr_str(self, space):
+        return space.wrap(self.buf.as_str())
+
+    @unwrap_spec(other='bufferstr')
+    def descr_add(self, space, other):
+        return space.wrap(self.buf.as_str() + other)
+
+    def _make_descr__cmp(name):
+        def descr__cmp(self, space, w_other):
+            if not isinstance(w_other, W_Buffer):
+                return space.w_NotImplemented
+            # xxx not the most efficient implementation
+            str1 = self.buf.as_str()
+            str2 = w_other.buf.as_str()
+            return space.wrap(getattr(operator, name)(str1, str2))
+        descr__cmp.func_name = name
+        return descr__cmp
+
+    descr_eq = _make_descr__cmp('eq')
+    descr_ne = _make_descr__cmp('ne')
+    descr_lt = _make_descr__cmp('lt')
+    descr_le = _make_descr__cmp('le')
+    descr_gt = _make_descr__cmp('gt')
+    descr_ge = _make_descr__cmp('ge')
+
+    def descr_hash(self, space):
+        return space.wrap(compute_hash(self.buf.as_str()))
+
+    def descr_mul(self, space, w_times):
+        # xxx not the most efficient implementation
+        w_string = space.wrap(self.buf.as_str())
+        # use the __mul__ method instead of space.mul() so that we
+        # return NotImplemented instead of raising a TypeError
+        return space.call_method(w_string, '__mul__', w_times)
+
+    def descr_repr(self, space):
+        if isinstance(self.buf, buffer.RWBuffer):
+            info = 'read-write buffer'
+        else:
+            info = 'read-only buffer'
+        addrstring = self.getaddrstring(space)
+
+        return space.wrap("<%s for 0x%s, size %d>" %
+                          (info, addrstring, self.buf.getlength()))
+
+W_Buffer.typedef = TypeDef(
+    "buffer",
+    __doc__ = """\
+buffer(object [, offset[, size]])
+
+Create a new buffer object which references the given object.
+The buffer will reference a slice of the target object from the
+start of the object (or at the specified offset). The slice will
+extend to the end of the target object (or with the specified size).
+""",
+    __new__ = interp2app(W_Buffer.descr_new_buffer),
+    __len__ = interp2app(W_Buffer.descr_len),
+    __getitem__ = interp2app(W_Buffer.descr_getitem),
+    __setitem__ = interp2app(W_Buffer.descr_setitem),
+    __str__ = interp2app(W_Buffer.descr_str),
+    __add__ = interp2app(W_Buffer.descr_add),
+    __eq__ = interp2app(W_Buffer.descr_eq),
+    __ne__ = interp2app(W_Buffer.descr_ne),
+    __lt__ = interp2app(W_Buffer.descr_lt),
+    __le__ = interp2app(W_Buffer.descr_le),
+    __gt__ = interp2app(W_Buffer.descr_gt),
+    __ge__ = interp2app(W_Buffer.descr_ge),
+    __hash__ = interp2app(W_Buffer.descr_hash),
+    __mul__ = interp2app(W_Buffer.descr_mul),
+    __rmul__ = interp2app(W_Buffer.descr_mul),
+    __repr__ = interp2app(W_Buffer.descr_repr),
+)
+W_Buffer.typedef.acceptable_as_base_class = False
+
+
+class W_MemoryView(W_Root):
+    """Implement the built-in 'memoryview' type as a wrapper around
+    an interp-level buffer.
+    """
+
+    def __init__(self, buf):
+        assert isinstance(buf, buffer.Buffer)
+        self.buf = buf
+
+    def buffer_w(self, space):
+        return self.buf
+
+    @staticmethod
+    def descr_new_memoryview(space, w_subtype, w_object):
+        return W_MemoryView(space.buffer_w(w_object))
+
+    def _make_descr__cmp(name):
+        def descr__cmp(self, space, w_other):
+            if isinstance(w_other, W_MemoryView):
+                # xxx not the most efficient implementation
+                str1 = self.as_str()
+                str2 = w_other.as_str()
+                return space.wrap(getattr(operator, name)(str1, str2))
+
+            try:
+                buf = space.buffer_w(w_other)
+            except OperationError, e:
+                if not e.match(space, space.w_TypeError):
+                    raise
+                return space.w_NotImplemented
+            else:
+                str1 = self.as_str()
+                str2 = buf.as_str()
+                return space.wrap(getattr(operator, name)(str1, str2))
+        descr__cmp.func_name = name
+        return descr__cmp
+
+    descr_eq = _make_descr__cmp('eq')
+    descr_ne = _make_descr__cmp('ne')
+    descr_lt = _make_descr__cmp('lt')
+    descr_le = _make_descr__cmp('le')
+    descr_gt = _make_descr__cmp('gt')
+    descr_ge = _make_descr__cmp('ge')
+
+    def as_str(self):
+        return self.buf.as_str()
+
+    def getlength(self):
+        return self.buf.getlength()
+
+    def getslice(self, start, stop):
+        if start < 0:
+            start = 0
+        size = stop - start
+        if size < 0:
+            size = 0
+        buf = self.buf
+        if isinstance(buf, buffer.RWBuffer):
+            buf = buffer.RWSubBuffer(buf, start, size)
+        else:
+            buf = buffer.SubBuffer(buf, start, size)
+        return W_MemoryView(buf)
+
+    def descr_buffer(self, space):
+        """
+        Note that memoryview() is very inconsistent in CPython: it does not
+        support the buffer interface but does support the new buffer
+        interface: as a result, it is possible to pass memoryview to
+        e.g. socket.send() but not to file.write().  For simplicity and
+        consistency, in PyPy memoryview DOES support buffer(), which means
+        that it is accepted in more places than CPython.
+        """
+        return space.wrap(self.buf)
+
+    def descr_tobytes(self, space):
+        return space.wrap(self.as_str())
+
+    def descr_tolist(self, space):
+        buf = self.buf
+        result = []
+        for i in range(buf.getlength()):
+            result.append(space.wrap(ord(buf.getitem(i))))
+        return space.newlist(result)
+
+    def descr_getitem(self, space, w_index):
+        start, stop, step = space.decode_index(w_index, self.getlength())
+        if step == 0:  # index only
+            return space.wrap(self.buf.getitem(start))
+        elif step == 1:
+            res = self.getslice(start, stop)
+            return space.wrap(res)
+        else:
+            raise OperationError(space.w_ValueError,
+                space.wrap("memoryview object does not support"
+                           " slicing with a step"))
+
+    @unwrap_spec(newstring='bufferstr')
+    def descr_setitem(self, space, w_index, newstring):
+        if not isinstance(self.buf, buffer.RWBuffer):
+            raise OperationError(space.w_TypeError,
+                                 space.wrap("cannot modify read-only memory"))
+        _buffer_setitem(space, self.buf, w_index, newstring)
+
+    def descr_len(self, space):
+        return space.wrap(self.buf.getlength())
+
+    def w_get_format(self, space):
+        return space.wrap("B")
+
+    def w_get_itemsize(self, space):
+        return space.wrap(1)
+
+    def w_get_ndim(self, space):
+        return space.wrap(1)
+
+    def w_is_readonly(self, space):
+        return space.wrap(not isinstance(self.buf, buffer.RWBuffer))
+
+    def w_get_shape(self, space):
+        return space.newtuple([space.wrap(self.getlength())])
+
+    def w_get_strides(self, space):
+        return space.newtuple([space.wrap(1)])
+
+    def w_get_suboffsets(self, space):
+        # I've never seen anyone filling this field
+        return space.w_None
+
+W_MemoryView.typedef = TypeDef(
+    "memoryview",
+    __doc__ = """\
+Create a new memoryview object which references the given object.
+""",
+    __new__     = interp2app(W_MemoryView.descr_new_memoryview),
+    __eq__      = interp2app(W_MemoryView.descr_eq),
+    __ge__      = interp2app(W_MemoryView.descr_ge),
+    __getitem__ = interp2app(W_MemoryView.descr_getitem),
+    __gt__      = interp2app(W_MemoryView.descr_gt),
+    __le__      = interp2app(W_MemoryView.descr_le),
+    __len__     = interp2app(W_MemoryView.descr_len),
+    __lt__      = interp2app(W_MemoryView.descr_lt),
+    __ne__      = interp2app(W_MemoryView.descr_ne),
+    __setitem__ = interp2app(W_MemoryView.descr_setitem),
+    tobytes     = interp2app(W_MemoryView.descr_tobytes),
+    tolist      = interp2app(W_MemoryView.descr_tolist),
+    format      = GetSetProperty(W_MemoryView.w_get_format),
+    itemsize    = GetSetProperty(W_MemoryView.w_get_itemsize),
+    ndim        = GetSetProperty(W_MemoryView.w_get_ndim),
+    readonly    = GetSetProperty(W_MemoryView.w_is_readonly),
+    shape       = GetSetProperty(W_MemoryView.w_get_shape),
+    strides     = GetSetProperty(W_MemoryView.w_get_strides),
+    suboffsets  = GetSetProperty(W_MemoryView.w_get_suboffsets),
+    )
+W_MemoryView.typedef.acceptable_as_base_class = False

File pypy/objspace/std/model.py

         from pypy.objspace.std import unicodeobject
         from pypy.objspace.std import dictproxyobject
         from pypy.objspace.std import proxyobject
-        from pypy.module.__builtin__.interp_memoryview import W_Buffer
+        from pypy.objspace.std.memoryview import W_Buffer, W_MemoryView
         import pypy.objspace.std.default # register a few catch-all multimethods
 
         import pypy.objspace.std.marshal_impl # install marshal multimethods
         self.pythontypes.append(boolobject.W_BoolObject.typedef)
         self.pythontypes.append(longobject.W_LongObject.typedef)
         self.pythontypes.append(W_Buffer.typedef)
+        self.pythontypes.append(W_MemoryView.typedef)
 
         # the set of implementation types
         self.typeorder = {

File pypy/objspace/std/objspace.py

 from pypy.objspace.std.iterobject import W_AbstractSeqIterObject
 from pypy.objspace.std.listobject import W_ListObject
 from pypy.objspace.std.longobject import W_LongObject, newlong
+from pypy.objspace.std.memoryview import W_Buffer
 from pypy.objspace.std.noneobject import W_NoneObject
 from pypy.objspace.std.objectobject import W_ObjectObject
 from pypy.objspace.std.iterobject import W_SeqIterObject
     def newseqiter(self, w_obj):
         return W_SeqIterObject(w_obj)
 
+    def newbuffer(self, w_obj):
+        return W_Buffer(w_obj)
+
     def type(self, w_obj):
         jit.promote(w_obj.__class__)
         return w_obj.getclass(self)

File pypy/objspace/std/test/test_memoryview.py

+class AppTestBuffer:
+    spaceconfig = dict(usemodules=['array'])
+
+    def test_init(self):
+        class A(object):
+            def __buffer__(self):
+                return buffer('123')
+        raises(TypeError, buffer, A())
+
+    def test_unicode_buffer(self):
+        import sys
+        b = buffer(u"ab")
+        if sys.maxunicode == 65535: # UCS2 build
+            assert len(b) == 4
+            if sys.byteorder == "big":
+                assert b[0:4] == "\x00a\x00b"
+            else:
+                assert b[0:4] == "a\x00b\x00"
+        else: # UCS4 build
+            assert len(b) == 8
+            if sys.byteorder == "big":
+                assert b[0:8] == "\x00\x00\x00a\x00\x00\x00b"
+            else:
+                assert b[0:8] == "a\x00\x00\x00b\x00\x00\x00"
+
+    def test_array_buffer(self):
+        import array
+        b = buffer(array.array("B", [1, 2, 3]))
+        assert len(b) == 3
+        assert b[0:3] == "\x01\x02\x03"
+
+    def test_nonzero(self):
+        assert buffer('\x00')
+        assert not buffer('')
+        import array
+        assert buffer(array.array("B", [0]))
+        assert not buffer(array.array("B", []))
+
+    def test_str(self):
+        assert str(buffer('hello')) == 'hello'
+
+    def test_repr(self):
+        # from 2.5.2 lib tests
+        assert repr(buffer('hello')).startswith('<read-only buffer for 0x')
+
+    def test_add(self):
+        assert buffer('abc') + 'def' == 'abcdef'
+        import array
+        assert buffer('abc') + array.array('c', 'def') == 'abcdef'
+
+    def test_cmp(self):
+        assert buffer('ab') != 'ab'
+        assert not ('ab' == buffer('ab'))
+        assert buffer('ab') == buffer('ab')
+        assert not (buffer('ab') != buffer('ab'))
+        assert not (buffer('ab') <  buffer('ab'))
+        assert buffer('ab') <= buffer('ab')
+        assert not (buffer('ab') >  buffer('ab'))
+        assert buffer('ab') >= buffer('ab')
+        assert buffer('ab') != buffer('abc')
+        assert buffer('ab') <  buffer('abc')
+        assert buffer('ab') <= buffer('ab')
+        assert buffer('ab') >  buffer('aa')
+        assert buffer('ab') >= buffer('ab')
+
+    def test_hash(self):
+        assert hash(buffer('hello')) == hash('hello')
+
+    def test_mul(self):
+        assert buffer('ab') * 5 == 'ababababab'
+        assert buffer('ab') * (-2) == ''
+        assert 5 * buffer('ab') == 'ababababab'
+        assert (-2) * buffer('ab') == ''
+
+    def test_offset_size(self):
+        b = buffer('hello world', 6)
+        assert len(b) == 5
+        assert b[0] == 'w'
+        assert b[:] == 'world'
+        raises(IndexError, 'b[5]')
+        b = buffer(b, 2)
+        assert len(b) == 3
+        assert b[0] == 'r'
+        assert b[:] == 'rld'
+        raises(IndexError, 'b[3]')
+        b = buffer('hello world', 1, 8)
+        assert len(b) == 8
+        assert b[0] == 'e'
+        assert b[:] == 'ello wor'
+        raises(IndexError, 'b[8]')
+        b = buffer(b, 2, 3)
+        assert len(b) == 3
+        assert b[2] == ' '
+        assert b[:] == 'lo '
+        raises(IndexError, 'b[3]')
+        b = buffer('hello world', 55)
+        assert len(b) == 0
+        assert b[:] == ''
+        b = buffer('hello world', 6, 999)
+        assert len(b) == 5
+        assert b[:] == 'world'
+
+        raises(ValueError, buffer, "abc", -1)
+        raises(ValueError, buffer, "abc", 0, -2)
+
+    def test_rw_offset_size(self):
+        import array
+
+        a = array.array("c", 'hello world')
+        b = buffer(a, 6)
+        assert len(b) == 5
+        assert b[0] == 'w'
+        assert b[:] == 'world'
+        raises(IndexError, 'b[5]')
+        b[0] = 'W'
+        assert str(b) == 'World'
+        assert a.tostring() == 'hello World'
+        b[:] = '12345'
+        assert a.tostring() == 'hello 12345'
+        raises(IndexError, 'b[5] = "."')
+        b[4:2] = ''
+        assert a.tostring() == 'hello 12345'
+
+        b = buffer(b, 2)
+        assert len(b) == 3
+        assert b[0] == '3'
+        assert b[:] == '345'
+        raises(IndexError, 'b[3]')
+        b[1] = 'X'
+        assert a.tostring() == 'hello 123X5'
+        raises(IndexError, 'b[3] = "."')
+
+        a = array.array("c", 'hello world')
+        b = buffer(a, 1, 8)
+        assert len(b) == 8
+        assert b[0] == 'e'
+        assert b[:] == 'ello wor'
+        raises(IndexError, 'b[8]')
+        b[0] = 'E'
+        assert str(b) == 'Ello wor'
+        assert a.tostring() == 'hEllo world'
+        b[:] = '12345678'
+        assert a.tostring() == 'h12345678ld'
+        raises(IndexError, 'b[8] = "."')
+
+        b = buffer(b, 2, 3)
+        assert len(b) == 3
+        assert b[2] == '5'
+        assert b[:] == '345'
+        raises(IndexError, 'b[3]')
+        b[1] = 'X'
+        assert a.tostring() == 'h123X5678ld'
+        raises(IndexError, 'b[3] = "."')
+
+        b = buffer(a, 55)
+        assert len(b) == 0
+        assert b[:] == ''
+        b = buffer(a, 6, 999)
+        assert len(b) == 5
+        assert b[:] == '678ld'
+
+        raises(ValueError, buffer, a, -1)
+        raises(ValueError, buffer, a, 0, -2)
+
+    def test_slice(self):
+        # Test extended slicing by comparing with list slicing.
+        s = "".join(chr(c) for c in list(range(255, -1, -1)))
+        b = buffer(s)
+        indices = (0, None, 1, 3, 19, 300, -1, -2, -31, -300)
+        for start in indices:
+            for stop in indices:
+                # Skip step 0 (invalid)
+                for step in indices[1:]:
+                    assert b[start:stop:step] == s[start:stop:step]
+
+    def test_getitem_only_ints(self):
+        class MyInt(object):
+          def __init__(self, x):
+            self.x = x
+
+          def __int__(self):
+            return self.x
+
+        buf = buffer('hello world')
+        raises(TypeError, "buf[MyInt(0)]")
+        raises(TypeError, "buf[MyInt(0):MyInt(5)]")
+
+
+class AppTestMemoryView:
+    def test_basic(self):
+        v = memoryview("abc")
+        assert v.tobytes() == "abc"
+        assert len(v) == 3
+        assert list(v) == ['a', 'b', 'c']
+        assert v.tolist() == [97, 98, 99]
+        assert v[1] == "b"
+        assert v[-1] == "c"
+        raises(TypeError, "v[1] = 'x'")
+        assert v.readonly is True
+        w = v[1:234]
+        assert isinstance(w, memoryview)
+        assert len(w) == 2
+
+    def test_rw(self):
+        data = bytearray('abcefg')
+        v = memoryview(data)
+        assert v.readonly is False
+        v[0] = 'z'
+        assert data == bytearray(eval("b'zbcefg'"))
+        v[1:4] = '123'
+        assert data == bytearray(eval("b'z123fg'"))
+        raises((ValueError, TypeError), "v[2] = 'spam'")
+
+    def test_memoryview_attrs(self):
+        v = memoryview("a"*100)
+        assert v.format == "B"
+        assert v.itemsize == 1
+        assert v.shape == (100,)
+        assert v.ndim == 1
+        assert v.strides == (1,)
+
+    def test_suboffsets(self):
+        v = memoryview("a"*100)
+        assert v.suboffsets == None
+        v = memoryview(buffer("a"*100, 2))
+        assert v.shape == (98,)
+        assert v.suboffsets == None
+
+    def test_compare(self):
+        assert memoryview("abc") == "abc"
+        assert memoryview("abc") == bytearray("abc")
+        assert memoryview("abc") != 3