Author: Ronan Lamy <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit