Author: Armin Rigo <ar...@tunes.org> Branch: py3.5 Changeset: r86592:12c05bf05cd7 Date: 2016-08-27 10:05 +0200 http://bitbucket.org/pypy/pypy/changeset/12c05bf05cd7/
Log: hg merge py3k diff --git a/pypy/objspace/std/memoryobject.py b/pypy/objspace/std/memoryobject.py --- a/pypy/objspace/std/memoryobject.py +++ b/pypy/objspace/std/memoryobject.py @@ -10,6 +10,7 @@ from pypy.interpreter.error import OperationError, oefmt from pypy.interpreter.gateway import interp2app from pypy.interpreter.typedef import TypeDef, GetSetProperty, make_weakref_descr +from pypy.objspace.std.bytesobject import getbytevalue from pypy.module.struct.formatiterator import UnpackFormatIterator, PackFormatIterator @@ -17,6 +18,7 @@ """Implement the built-in 'memoryview' type as a wrapper around an interp-level buffer. """ + _immutable_fields_ = ['format', 'itemsize'] def __init__(self, buf, format='B', itemsize=1): assert isinstance(buf, Buffer) @@ -62,8 +64,7 @@ def as_str(self): buf = self.buf - n_bytes = buf.getlength() - return buf.getslice(0, n_bytes, 1, n_bytes) + return buf.as_str() def getlength(self): return self.buf.getlength() // self.itemsize @@ -82,82 +83,68 @@ def descr_getitem(self, space, w_index): self._check_released(space) start, stop, step, size = space.decode_index4(w_index, self.getlength()) - itemsize = self.buf.getitemsize() - if itemsize > 1: - start *= itemsize - size *= itemsize - stop = start + size - if step == 0: - step = 1 - if stop > self.getlength(): - raise oefmt(space.w_IndexError, 'index out of range') - if step not in (0, 1): - raise oefmt(space.w_NotImplementedError, "") + # ^^^ for a non-slice index, this returns (index, 0, 0, 1) + itemsize = self.itemsize if step == 0: # index only - # TODO: this probably isn't very fast - buf = SubBuffer(self.buf, start, self.itemsize) - fmtiter = UnpackFormatIterator(space, buf) - fmtiter.interpret(self.format) - return fmtiter.result_w[0] + if itemsize == 1: + ch = self.buf.getitem(start) + return space.newint(ord(ch)) + else: + # TODO: this probably isn't very fast + buf = SubBuffer(self.buf, start * itemsize, itemsize) + fmtiter = UnpackFormatIterator(space, buf) + fmtiter.interpret(self.format) + return fmtiter.result_w[0] elif step == 1: - buf = SubBuffer(self.buf, start, size) - return W_MemoryView(buf, self.format, self.itemsize) + buf = SubBuffer(self.buf, start * itemsize, size * itemsize) + return W_MemoryView(buf, self.format, itemsize) else: - buf = SubBuffer(self.buf, start, size) - return W_MemoryView(buf) + raise oefmt(space.w_NotImplementedError, + "XXX extended slicing") def descr_setitem(self, space, w_index, w_obj): self._check_released(space) if self.buf.readonly: raise oefmt(space.w_TypeError, "cannot modify read-only memory") if space.isinstance_w(w_index, space.w_tuple): - raise oefmt(space.w_NotImplementedError, "") + raise oefmt(space.w_NotImplementedError, "XXX tuple setitem") start, stop, step, size = space.decode_index4(w_index, self.getlength()) - itemsize = self.buf.getitemsize() - if itemsize > 1: - start *= itemsize - size *= itemsize - stop = start + size - if step == 0: - step = 1 - if stop > self.getlength(): - raise oefmt(space.w_IndexError, 'index out of range') - if step not in (0, 1): - raise oefmt(space.w_NotImplementedError, "") - value = space.buffer_w(w_obj, space.BUF_CONTIG_RO) - if value.getlength() != size: - raise oefmt(space.w_ValueError, - "cannot modify size of memoryview object") + itemsize = self.itemsize if step == 0: # index only - # TODO: this probably isn't very fast - fmtiter = PackFormatIterator(space, [w_obj], self.itemsize) - try: - fmtiter.interpret(self.format) - except StructError as e: - raise oefmt(space.w_TypeError, - "memoryview: invalid type for format '%s'", - self.format) - self.buf.setslice(start, fmtiter.result.build()) + if itemsize == 1: + ch = getbytevalue(space, w_obj) + self.buf.setitem(start, ch) + else: + # TODO: this probably isn't very fast + fmtiter = PackFormatIterator(space, [w_obj], itemsize) + try: + fmtiter.interpret(self.format) + except StructError as e: + raise oefmt(space.w_TypeError, + "memoryview: invalid type for format '%s'", + self.format) + self.buf.setslice(start * itemsize, fmtiter.result.build()) elif step == 1: value = space.buffer_w(w_obj, space.BUF_CONTIG_RO) if value.getlength() != size * self.itemsize: raise oefmt(space.w_ValueError, "cannot modify size of memoryview object") - self.buf.setslice(start, value.as_str()) + self.buf.setslice(start * itemsize, value.as_str()) else: - raise oefmt(space.w_NotImplementedError, "") + raise oefmt(space.w_NotImplementedError, + "XXX extended slicing") def descr_len(self, space): self._check_released(space) - return space.wrap(self.buf.getlength()) + return space.wrap(self.getlength()) def w_get_format(self, space): self._check_released(space) - return space.wrap(self.buf.getformat()) + return space.wrap(self.format) def w_get_itemsize(self, space): self._check_released(space) - return space.wrap(self.buf.getitemsize()) + return space.newint(self.itemsize) def w_get_ndim(self, space): self._check_released(space) @@ -169,11 +156,11 @@ def w_get_shape(self, space): self._check_released(space) - return space.newtuple([space.wrap(x) for x in self.buf.getshape()]) + return space.newtuple([space.newint(self.getlength())]) def w_get_strides(self, space): self._check_released(space) - return space.newtuple([space.wrap(x) for x in self.buf.getstrides()]) + return space.newtuple([space.newint(self.itemsize)]) def w_get_suboffsets(self, space): self._check_released(space) @@ -221,7 +208,7 @@ "is internally %r" % (self.buf,)) raise OperationError(space.w_ValueError, space.wrap(msg)) return space.wrap(rffi.cast(lltype.Signed, ptr)) - + def get_native_fmtchar(self, fmt): from rpython.rtyper.lltypesystem import rffi size = -1 @@ -252,8 +239,10 @@ return size def descr_cast(self, space, w_format, w_shape=None): - # XXX fixme. does not do anything near cpython (see memoryobjet.c memory_cast) self._check_released(space) + if not space.is_none(w_shape): + raise oefmt(space.w_NotImplementedError, + "XXX cast() with a shape") fmt = space.str_w(w_format) newitemsize = self.get_native_fmtchar(fmt) return W_MemoryView(self.buf, fmt, newitemsize) diff --git a/pypy/objspace/std/test/test_memoryobject.py b/pypy/objspace/std/test/test_memoryobject.py --- a/pypy/objspace/std/test/test_memoryobject.py +++ b/pypy/objspace/std/test/test_memoryobject.py @@ -16,8 +16,6 @@ w = v[1:234] assert isinstance(w, memoryview) assert len(w) == 2 - exc = raises(NotImplementedError, "v[0:2:2]") - assert str(exc.value) == "" exc = raises(TypeError, "memoryview('foobar')") def test_rw(self): @@ -32,8 +30,15 @@ assert data == bytearray(eval("b'23f3fg'")) exc = raises(ValueError, "v[2:3] = b'spam'") assert str(exc.value) == "cannot modify size of memoryview object" - exc = raises(NotImplementedError, "v[0:2:2] = b'spam'") - assert str(exc.value) == "" + + def test_extended_slice(self): + data = bytearray(b'abcefg') + v = memoryview(data) + w = v[0:2:2] # failing for now: NotImplementedError + assert len(w) == 1 + assert list(w) == [97] + v[::2] = b'ABC' + assert data == bytearray(b'AbBeCg') def test_memoryview_attrs(self): v = memoryview(b"a"*100) @@ -165,3 +170,51 @@ def test_hex(self): assert memoryview(b"abc").hex() == u'616263' + + def test_memoryview_cast(self): + m1 = memoryview(b'abcdefgh') + m2 = m1.cast('I') + m3 = m1.cast('h') + assert list(m1) == [97, 98, 99, 100, 101, 102, 103, 104] + assert list(m2) == [1684234849, 1751606885] + assert list(m3) == [25185, 25699, 26213, 26727] + assert m1[1] == 98 + assert m2[1] == 1751606885 + assert m3[1] == 25699 + assert list(m3[1:3]) == [25699, 26213] + assert m3[1:3].tobytes() == b'cdef' + assert len(m2) == 2 + assert len(m3) == 4 + assert (m2[-2], m2[-1]) == (1684234849, 1751606885) + raises(IndexError, "m2[2]") + raises(IndexError, "m2[-3]") + assert list(m3[-99:3]) == [25185, 25699, 26213] + assert list(m3[1:99]) == [25699, 26213, 26727] + raises(IndexError, "m1[8]") + raises(IndexError, "m1[-9]") + assert m1[-8] == 97 + + def test_memoryview_cast_extended_slicing(self): + m1 = memoryview(b'abcdefgh') + m3 = m1.cast('h') + assert m3[1::2].tobytes() == b'cdgh' + assert m3[::2].tobytes() == b'abef' + assert m3[:2:2].tobytes() == b'ab' + + def test_memoryview_cast_setitem(self): + data = bytearray(b'abcdefgh') + m1 = memoryview(data) + m2 = m1.cast('I') + m3 = m1.cast('h') + m1[2] = ord(b'C') + assert m2[0] == 1682137697 + m3[1] = -9999 + assert data == bytearray(bytes([97, 98, 241, 216, 101, 102, 103, 104])) + m3[1:3] = memoryview(b"pqrs").cast('h') + assert data == bytearray(b'abpqrsgh') + + def test_memoryview_cast_setitem_extended_slicing(self): + data = bytearray(b'abcdefghij') + m3 = memoryview(data).cast('h') + m3[1:5:2] = memoryview(b"xyXY").cast('h') + assert data == bytearray(b'abxyefXYij') diff --git a/rpython/rlib/buffer.py b/rpython/rlib/buffer.py --- a/rpython/rlib/buffer.py +++ b/rpython/rlib/buffer.py @@ -10,6 +10,7 @@ _immutable_ = True def getlength(self): + """Returns the size in bytes (even if getitemsize() > 1).""" raise NotImplementedError def __len__(self): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit