Author: Ronan Lamy <ronan.l...@gmail.com> Branch: PyBuffer-backport Changeset: r91203:4eabf29be4e9 Date: 2017-05-08 18:33 +0100 http://bitbucket.org/pypy/pypy/changeset/4eabf29be4e9/
Log: _io and writebuf_w changes diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -9,7 +9,9 @@ from rpython.rlib.signature import signature from rpython.rlib.rarithmetic import r_uint, SHRT_MIN, SHRT_MAX, \ INT_MIN, INT_MAX, UINT_MAX, USHRT_MAX +from rpython.rlib.buffer import StringBuffer +from pypy.interpreter.buffer import BufferInterfaceNotFound from pypy.interpreter.executioncontext import (ExecutionContext, ActionFlag, make_finalizer_queue) from pypy.interpreter.error import OperationError, new_exception_class, oefmt @@ -396,9 +398,6 @@ class DescrMismatch(Exception): pass -class BufferInterfaceNotFound(Exception): - pass - @specialize.memo() def wrappable_class_name(Class): try: @@ -1513,10 +1512,15 @@ def writebuf_w(self, w_obj): # Old buffer interface, returns a writeable buffer (PyObject_AsWriteBuffer) try: + return w_obj.buffer_w(self, self.BUF_WRITABLE).as_writebuf() + except OperationError: + self._getarg_error("read-write buffer", w_obj) + except BufferInterfaceNotFound: + pass + try: return w_obj.writebuf_w(self) except BufferInterfaceNotFound: - raise oefmt(self.w_TypeError, - "expected a writeable buffer object") + self._getarg_error("read-write buffer", w_obj) def charbuf_w(self, w_obj): # Old buffer interface, returns a character buffer (PyObject_AsCharBuffer) @@ -1562,16 +1566,7 @@ except BufferInterfaceNotFound: self._getarg_error("string or read-only buffer", w_obj) elif code == 'w*': - try: - return w_obj.buffer_w(self, self.BUF_WRITABLE) - except OperationError: - self._getarg_error("read-write buffer", w_obj) - except BufferInterfaceNotFound: - pass - try: - return w_obj.writebuf_w(self) - except BufferInterfaceNotFound: - self._getarg_error("read-write buffer", w_obj) + return self.writebuf_w(w_obj) elif code == 't#': try: return w_obj.charbuf_w(self) diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py --- a/pypy/module/_io/interp_bufferedio.py +++ b/pypy/module/_io/interp_bufferedio.py @@ -1,12 +1,15 @@ from __future__ import with_statement +from rpython.rlib.signature import signature +from rpython.rlib import types + from pypy.interpreter.error import OperationError, oefmt from pypy.interpreter.typedef import ( TypeDef, GetSetProperty, generic_new_descr, interp_attrproperty_w) from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault -from rpython.rlib.rgc import ( - nonmoving_raw_ptr_for_resizable_list, resizable_list_supporting_raw_ptr) -from rpython.rlib.buffer import Buffer +from pypy.interpreter.buffer import SimpleView + +from rpython.rlib.buffer import ByteBuffer, SubBuffer from rpython.rlib.rstring import StringBuilder from rpython.rlib.rarithmetic import r_longlong, intmask from rpython.rlib import rposix @@ -16,7 +19,6 @@ check_readable_w, check_writable_w, check_seekable_w) from pypy.module._io.interp_io import W_BlockingIOError from rpython.rlib import rthread -from rpython.rtyper.lltypesystem import rffi STATE_ZERO, STATE_OK, STATE_DETACHED = range(3) @@ -88,12 +90,16 @@ self._unsupportedoperation(space, "detach") def readinto_w(self, space, w_buffer): - rwbuffer = space.getarg_w('w*', w_buffer) + return self._readinto(space, w_buffer, "read") + + def _readinto(self, space, w_buffer, methodname): + rwbuffer = space.writebuf_w(w_buffer) length = rwbuffer.getlength() - w_data = space.call_method(self, "read", space.newint(length)) + w_data = space.call_method(self, methodname, space.newint(length)) if not space.isinstance_w(w_data, space.w_bytes): - raise oefmt(space.w_TypeError, "read() should return bytes") + raise oefmt(space.w_TypeError, "%s() should return bytes", + methodname) data = space.bytes_w(w_data) rwbuffer.setslice(0, data) return space.newint(len(data)) @@ -108,25 +114,6 @@ readinto = interp2app(W_BufferedIOBase.readinto_w), ) -class RawBuffer(Buffer): - _immutable_ = True - - def __init__(self, buf, start, length): - self.buf = buf - self.start = start - self.length = length - self.readonly = False - - def getlength(self): - return self.length - - def setitem(self, index, char): - self.buf[self.start + index] = char - - def get_raw_address(self): - ptr = nonmoving_raw_ptr_for_resizable_list(self.buf) - return rffi.ptradd(ptr, self.start) - class BufferedMixin: _mixin_ = True @@ -165,8 +152,7 @@ raise oefmt(space.w_ValueError, "buffer size must be strictly positive") - self.buffer = resizable_list_supporting_raw_ptr(['\0'] * - self.buffer_size) + self.buffer = ByteBuffer(self.buffer_size) self.lock = TryLock(space) @@ -238,6 +224,7 @@ # ______________________________________________ + @signature(types.any(), returns=types.int()) def _readahead(self): if self.readable and self.read_end != -1: available = self.read_end - self.pos @@ -278,7 +265,7 @@ else: offset = pos if -self.pos <= offset <= available: - newpos = self.pos + offset + newpos = self.pos + int(offset) assert newpos >= 0 self.pos = newpos return space.newint(current - available + offset) @@ -374,11 +361,7 @@ return written def _raw_write(self, space, start, end): - # XXX inefficient - l = [] - for i in range(start, end): - l.append(self.buffer[i]) - return self._write(space, ''.join(l)) + return self._write(space, self.buffer[start:end]) def detach_w(self, space): self._check_init(space) @@ -428,6 +411,7 @@ @unwrap_spec(size=int) def peek_w(self, space, size=0): self._check_init(space) + self._check_closed(space, "peek of closed file") with self.lock: if self.writable: self._flush_and_rewind_unlocked(space) @@ -439,7 +423,7 @@ # buffer. have = self._readahead() if have > 0: - data = ''.join(self.buffer[self.pos:self.pos+have]) + data = self.buffer[self.pos:self.pos+have] return space.newbytes(data) # Fill the buffer from the raw stream, and copy it to the result @@ -449,7 +433,7 @@ except BlockingIOError: size = 0 self.pos = 0 - data = ''.join(self.buffer[:size]) + data = self.buffer[0:size] return space.newbytes(data) @unwrap_spec(size=int) @@ -486,7 +470,7 @@ if size > have: size = have endpos = self.pos + size - data = ''.join(self.buffer[self.pos:endpos]) + data = self.buffer[self.pos:endpos] self.pos = endpos return space.newbytes(data) @@ -498,7 +482,7 @@ current_size = self._readahead() data = None if current_size: - data = ''.join(self.buffer[self.pos:self.pos + current_size]) + data = self.buffer[self.pos:self.pos + current_size] builder.append(data) self.pos += current_size # We're going past the buffer's bounds, flush it @@ -524,11 +508,13 @@ return space.newbytes(builder.build()) def _raw_read(self, space, buffer, start, length): + assert buffer is not None length = intmask(length) - w_buf = space.newbuffer(RawBuffer(buffer, start, length)) + start = intmask(start) + w_view = SimpleView(SubBuffer(buffer, start, length)).wrap(space) while True: try: - w_size = space.call_method(self.w_raw, "readinto", w_buf) + w_size = space.call_method(self.w_raw, "readinto", w_view) except OperationError as e: if trap_eintr(space, e): continue # try again @@ -565,12 +551,12 @@ if n <= current_size: return self._read_fast(n) - result_buffer = resizable_list_supporting_raw_ptr(['\0'] * n) + result_buffer = ByteBuffer(n) remaining = n written = 0 if current_size: - for i in range(current_size): - result_buffer[written + i] = self.buffer[self.pos + i] + result_buffer.setslice( + written, self.buffer[self.pos:self.pos + current_size]) remaining -= current_size written += current_size self.pos += current_size @@ -592,7 +578,7 @@ return None size = 0 if size == 0: - return ''.join(result_buffer[:written]) + return result_buffer[0:written] remaining -= size written += size @@ -614,14 +600,13 @@ if remaining > 0: if size > remaining: size = remaining - for i in range(size): - result_buffer[written + i] = self.buffer[self.pos + i] + result_buffer.setslice( + written, self.buffer[self.pos:self.pos + size]) self.pos += size - written += size remaining -= size - return ''.join(result_buffer[:written]) + return result_buffer[0:written] def _read_fast(self, n): """Read n bytes from the buffer if it can, otherwise return None. @@ -629,7 +614,7 @@ current_size = self._readahead() if n <= current_size: endpos = self.pos + n - res = ''.join(self.buffer[self.pos:endpos]) + res = self.buffer[self.pos:endpos] self.pos = endpos return res return None @@ -652,11 +637,11 @@ else: pos = -1 if pos >= 0: - w_res = space.newbytes(''.join(self.buffer[self.pos:pos+1])) + w_res = space.newbytes(self.buffer[self.pos:pos+1]) self.pos = pos + 1 return w_res if have == limit: - w_res = space.newbytes(''.join(self.buffer[self.pos:self.pos+have])) + w_res = space.newbytes(self.buffer[self.pos:self.pos+have]) self.pos += have return w_res @@ -665,7 +650,7 @@ # Now we try to get some more from the raw stream chunks = [] if have > 0: - chunks.extend(self.buffer[self.pos:self.pos+have]) + chunks.append(self.buffer[self.pos:self.pos+have]) written += have self.pos += have if limit >= 0: @@ -683,13 +668,14 @@ pos = 0 found = False while pos < have: - c = self.buffer[pos] + # 'buffer.data[]' instead of 'buffer[]' because RPython... + c = self.buffer.data[pos] pos += 1 if c == '\n': self.pos = pos found = True break - chunks.extend(self.buffer[0:pos]) + chunks.append(self.buffer[0:pos]) if found: break if have == limit: @@ -716,7 +702,6 @@ size = len(data) with self.lock: - if (not (self.readable and self.read_end != -1) and not (self.writable and self.write_end != -1)): self.pos = 0 @@ -746,7 +731,8 @@ self._reader_reset_buf() # Make some place by shifting the buffer for i in range(self.write_pos, self.write_end): - self.buffer[i - self.write_pos] = self.buffer[i] + # XXX: messing with buffer internals + self.buffer.data[i - self.write_pos] = self.buffer.data[i] self.write_end -= self.write_pos self.raw_pos -= self.write_pos newpos = self.pos - self.write_pos diff --git a/pypy/module/_io/interp_bytesio.py b/pypy/module/_io/interp_bytesio.py --- a/pypy/module/_io/interp_bytesio.py +++ b/pypy/module/_io/interp_bytesio.py @@ -34,17 +34,17 @@ size = convert_size(space, w_size) return space.newbytes(self.read(size)) + def read1_w(self, space, w_size): + return self.read_w(space, w_size) + def readline_w(self, space, w_limit=None): self._check_closed(space) limit = convert_size(space, w_limit) return space.newbytes(self.readline(limit)) - def read1_w(self, space, w_size): - return self.read_w(space, w_size) - def readinto_w(self, space, w_buffer): self._check_closed(space) - rwbuffer = space.getarg_w('w*', w_buffer) + rwbuffer = space.writebuf_w(w_buffer) size = rwbuffer.getlength() output = self.read(size) diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py --- a/pypy/objspace/fake/objspace.py +++ b/pypy/objspace/fake/objspace.py @@ -1,9 +1,4 @@ from rpython.annotator.model import SomeInstance, s_None -from pypy.interpreter import argument, gateway -from pypy.interpreter.baseobjspace import W_Root, ObjSpace, SpaceCache -from pypy.interpreter.typedef import TypeDef, GetSetProperty -from pypy.objspace.std.sliceobject import W_SliceObject -from rpython.rlib.buffer import StringBuffer from rpython.rlib.objectmodel import (instantiate, we_are_translated, specialize, not_rpython) from rpython.rlib.nonconst import NonConstant @@ -14,6 +9,13 @@ from rpython.tool.sourcetools import compile2, func_with_new_name from rpython.translator.translator import TranslationContext +from pypy.tool.option import make_config +from pypy.interpreter import argument, gateway +from pypy.interpreter.baseobjspace import W_Root, ObjSpace, SpaceCache +from pypy.interpreter.buffer import StringBuffer, SimpleView +from pypy.interpreter.typedef import TypeDef, GetSetProperty +from pypy.objspace.std.sliceobject import W_SliceObject + class W_MyObject(W_Root): typedef = None @@ -41,7 +43,7 @@ is_root(w_subtype) def buffer_w(self, space, flags): - return StringBuffer("foobar") + return SimpleView(StringBuffer("foobar")) def str_w(self, space): return NonConstant("foobar") @@ -123,7 +125,7 @@ BUILTIN_TYPES = ['int', 'str', 'float', 'long', 'tuple', 'list', 'dict', 'unicode', 'complex', 'slice', 'bool', 'basestring', 'object', - 'bytearray', 'buffer', 'set', 'frozenset'] + 'set', 'frozenset', 'bytearray', 'buffer', 'memoryview'] INTERP_TYPES = ['function', 'builtin_function', 'module', 'getset_descriptor', 'instance', 'classobj'] @@ -197,7 +199,7 @@ def newseqiter(self, x): return w_some_obj() - def newbuffer(self, x): + def newmemoryview(self, x): return w_some_obj() @not_rpython _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit