[Python-checkins] cpython (merge 3.6 -> default): Merge 3.6 (issue #28370)

yury.selivanov python-checkins at python.org
Wed Oct 5 18:17:38 EDT 2016


https://hg.python.org/cpython/rev/5913c2b1d80a
changeset:   104307:5913c2b1d80a
parent:      104304:745e0ff513c2
parent:      104306:b76553de3a29
user:        Yury Selivanov <yury at magic.io>
date:        Wed Oct 05 18:04:48 2016 -0400
summary:
  Merge 3.6 (issue #28370)

files:
  Lib/asyncio/streams.py |  32 ++++++++++++++---------------
  Misc/NEWS              |   3 ++
  2 files changed, 18 insertions(+), 17 deletions(-)


diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py
--- a/Lib/asyncio/streams.py
+++ b/Lib/asyncio/streams.py
@@ -448,6 +448,7 @@
         assert not self._eof, '_wait_for_data after EOF'
 
         # Waiting for data while paused will make deadlock, so prevent it.
+        # This is essential for readexactly(n) for case when n > self._limit.
         if self._paused:
             self._paused = False
             self._transport.resume_reading()
@@ -658,25 +659,22 @@
         if n == 0:
             return b''
 
-        # There used to be "optimized" code here.  It created its own
-        # Future and waited until self._buffer had at least the n
-        # bytes, then called read(n).  Unfortunately, this could pause
-        # the transport if the argument was larger than the pause
-        # limit (which is twice self._limit).  So now we just read()
-        # into a local buffer.
+        while len(self._buffer) < n:
+            if self._eof:
+                incomplete = bytes(self._buffer)
+                self._buffer.clear()
+                raise IncompleteReadError(incomplete, n)
 
-        blocks = []
-        while n > 0:
-            block = yield from self.read(n)
-            if not block:
-                partial = b''.join(blocks)
-                raise IncompleteReadError(partial, len(partial) + n)
-            blocks.append(block)
-            n -= len(block)
+            yield from self._wait_for_data('readexactly')
 
-        assert n == 0
-
-        return b''.join(blocks)
+        if len(self._buffer) == n:
+            data = bytes(self._buffer)
+            self._buffer.clear()
+        else:
+            data = bytes(self._buffer[:n])
+            del self._buffer[:n]
+        self._maybe_resume_transport()
+        return data
 
     if compat.PY35:
         @coroutine
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -181,6 +181,9 @@
 - Issue #28369: Raise RuntimeError when transport's FD is used with
   add_reader, add_writer, etc.
 
+- Issue #28370: Speedup asyncio.StreamReader.readexactly.
+  Patch by Коренберг Марк.
+
 Windows
 -------
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list