Author: Manuel Jacob <m...@manueljacob.de> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit