Author: Manuel Jacob <[email protected]>
Branch: py3.5
Changeset: r90519:5adc6b27b53a
Date: 2017-03-04 00:43 +0100
http://bitbucket.org/pypy/pypy/changeset/5adc6b27b53a/
Log: hg merge default
diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -672,15 +672,17 @@
w_filename2=w_filename2,
eintr_retry=eintr_retry)
-def exception_from_saved_errno(space, w_type):
- from rpython.rlib.rposix import get_saved_errno
-
- errno = get_saved_errno()
+def exception_from_errno(space, w_type, errno):
msg = strerror(errno)
w_error = space.call_function(w_type, space.newint(errno),
space.newunicode(msg))
return OperationError(w_type, w_error)
+def exception_from_saved_errno(space, w_type):
+ from rpython.rlib.rposix import get_saved_errno
+ errno = get_saved_errno()
+ return exception_from_errno(space, w_type, errno)
+
def new_exception_class(space, name, w_bases=None, w_dict=None):
"""Create a new exception type.
@param name: the name of the type.
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
@@ -5,6 +5,8 @@
TypeDef, GetSetProperty, generic_new_descr, interp_attrproperty_w)
from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
from rpython.rlib.buffer import Buffer, SubBuffer
+from rpython.rlib.rgc import (
+ nonmoving_raw_ptr_for_resizable_list, resizable_list_supporting_raw_ptr)
from rpython.rlib.rstring import StringBuilder
from rpython.rlib.rarithmetic import r_longlong, intmask
from rpython.rlib import rposix
@@ -159,7 +161,7 @@
def __init__(self, n):
self.length = n
- self.buf = ['\0'] * n
+ self.buf = resizable_list_supporting_raw_ptr(['\0'] * n)
self.readonly = False
def getlength(self):
diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py
--- a/pypy/module/_io/interp_fileio.py
+++ b/pypy/module/_io/interp_fileio.py
@@ -1,11 +1,13 @@
from pypy.interpreter.typedef import TypeDef, interp_attrproperty,
GetSetProperty
from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.interpreter.error import (
- OperationError, oefmt, wrap_oserror, wrap_oserror2)
+ OperationError, oefmt, wrap_oserror, wrap_oserror2, exception_from_errno)
from rpython.rlib.rarithmetic import r_longlong
+from rpython.rlib.rposix import get_saved_errno
from rpython.rlib.rstring import StringBuilder
from rpython.rlib import rposix
from rpython.rlib.rposix_stat import STAT_FIELD_TYPES
+from rpython.rtyper.lltypesystem import lltype, rffi
from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_TRUNC, O_EXCL
import sys, os, stat, errno
from pypy.module._io.interp_iobase import (
@@ -126,6 +128,15 @@
return currentsize + BIGCHUNK
return currentsize + SMALLCHUNK
+
+_WIN32 = sys.platform.startswith('win')
+UNDERSCORE_ON_WIN32 = '_' if _WIN32 else ''
+
+os_read = rffi.llexternal(UNDERSCORE_ON_WIN32 + 'read',
+ [rffi.INT, rffi.CCHARP, rffi.SIZE_T],
+ rffi.SSIZE_T, save_err=rffi.RFFI_SAVE_ERRNO)
+
+
class W_FileIO(W_RawIOBase):
def __init__(self, space):
W_RawIOBase.__init__(self, space)
@@ -447,18 +458,42 @@
self._check_readable(space)
rwbuffer = space.getarg_w('w*', w_buffer)
length = rwbuffer.getlength()
- while True:
+
+ target_address = lltype.nullptr(rffi.CCHARP.TO)
+ if length > 64:
try:
- buf = os.read(self.fd, length)
- break
- except OSError as e:
- if e.errno == errno.EAGAIN:
+ target_address = rwbuffer.get_raw_address()
+ except ValueError:
+ pass
+
+ if not target_address:
+ # unoptimized case
+ while True:
+ try:
+ buf = os.read(self.fd, length)
+ break
+ except OSError as e:
+ if e.errno == errno.EAGAIN:
+ return space.w_None
+ wrap_oserror(space, e,
+ exception_name='w_IOError',
+ eintr_retry=True)
+ rwbuffer.setslice(0, buf)
+ return space.newint(len(buf))
+ else:
+ # optimized case: reading more than 64 bytes into a rwbuffer
+ # with a valid raw address
+ # XXX TODO(mjacob): implement PEP 475 here!
+ got = os_read(self.fd, target_address, length)
+ got = rffi.cast(lltype.Signed, got)
+ if got >= 0:
+ return space.newint(got)
+ else:
+ err = get_saved_errno()
+ if err == errno.EAGAIN:
return space.w_None
- wrap_oserror(space, e,
- exception_name='w_IOError',
- eintr_retry=True)
- rwbuffer.setslice(0, buf)
- return space.newint(len(buf))
+ raise exception_from_errno(space, space.w_IOError, err)
+ keepalive_until_here(rwbuffer)
def readall_w(self, space):
self._check_closed(space)
diff --git a/pypy/module/_io/test/test_fileio.py
b/pypy/module/_io/test/test_fileio.py
--- a/pypy/module/_io/test/test_fileio.py
+++ b/pypy/module/_io/test/test_fileio.py
@@ -1,4 +1,5 @@
# encoding: utf-8
+from pypy.interpreter.gateway import interp2app
from rpython.tool.udir import udir
import os
@@ -14,6 +15,11 @@
self.w_posix = self.space.appexec([], """():
import %s as m;
return m""" % os.name)
+ def create_bigfile_w():
+ bigfile = udir.join('bigfile')
+ bigfile.write('a' * 1000, mode='wb')
+ return self.space.wrap(str(bigfile))
+ self.w_create_bigfile = self.space.wrap(interp2app(create_bigfile_w))
def test_constructor(self):
import _io
@@ -151,13 +157,10 @@
import _io
a = bytearray(b'x' * 10)
f = _io.FileIO(self.tmpfile, 'r+')
- f.seek(5)
- f.write(b'\x00' * 5)
- f.seek(0)
assert f.readinto(a) == 5
f.seek(0)
m = memoryview(bytearray(b"helloworld"))
- assert f.readinto(m) == 10
+ assert f.readinto(m) == 5
#
exc = raises(TypeError, f.readinto, u"hello")
msg = str(exc.value)
@@ -179,6 +182,13 @@
f.close()
assert a == b'a\nbxxxxxxx'
+ def test_readinto_optimized(self):
+ import _io
+ a = bytearray(b'x' * 1024)
+ f = _io.FileIO(self.create_bigfile(), 'r+')
+ assert f.readinto(a) == 1000
+ assert a == b'a' * 1000 + b'x' * 24
+
def test_nonblocking_read(self):
try:
import os, fcntl
@@ -194,6 +204,8 @@
assert f.read(10) is None
a = bytearray(b'x' * 10)
assert f.readinto(a) is None
+ a2 = bytearray(b'x' * 1024)
+ assert f.readinto(a2) is None
def test_repr(self):
import _io
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit