@@ -448,6 +448,7 @@ def _wait_for_data(self, func_name):
448
448
assert not self ._eof , '_wait_for_data after EOF'
449
449
450
450
# Waiting for data while paused will make deadlock, so prevent it.
451
+ # This is essential for readexactly(n) for case when n > self._limit.
451
452
if self ._paused :
452
453
self ._paused = False
453
454
self ._transport .resume_reading ()
@@ -658,25 +659,22 @@ def readexactly(self, n):
658
659
if n == 0 :
659
660
return b''
660
661
661
- # There used to be "optimized" code here. It created its own
662
- # Future and waited until self._buffer had at least the n
663
- # bytes, then called read(n). Unfortunately, this could pause
664
- # the transport if the argument was larger than the pause
665
- # limit (which is twice self._limit). So now we just read()
666
- # into a local buffer.
667
-
668
- blocks = []
669
- while n > 0 :
670
- block = yield from self .read (n )
671
- if not block :
672
- partial = b'' .join (blocks )
673
- raise IncompleteReadError (partial , len (partial ) + n )
674
- blocks .append (block )
675
- n -= len (block )
676
-
677
- assert n == 0
678
-
679
- return b'' .join (blocks )
662
+ while len (self ._buffer ) < n :
663
+ if self ._eof :
664
+ incomplete = bytes (self ._buffer )
665
+ self ._buffer .clear ()
666
+ raise IncompleteReadError (incomplete , n )
667
+
668
+ yield from self ._wait_for_data ('readexactly' )
669
+
670
+ if len (self ._buffer
711B
span>) == n :
671
+ data = bytes (self ._buffer )
672
+ self ._buffer .clear ()
673
+ else :
674
+ data = bytes (self ._buffer [:n ])
675
+ del self ._buffer [:n ]
676
+ self ._maybe_resume_transport ()
677
+ return data
680
678
681
679
if compat .PY35 :
682
680
@coroutine
0 commit comments