diff --git a/aiohttp/streams.py b/aiohttp/streams.py index db22f162396..bf090cd8925 100644 --- a/aiohttp/streams.py +++ b/aiohttp/streams.py @@ -1,5 +1,6 @@ import asyncio import collections +import io import warnings from typing import ( Awaitable, @@ -398,13 +399,13 @@ async def read(self, n: int = -1) -> bytes: # collect everything in self._buffer, but that would # deadlock if the subprocess sends more than self.limit # bytes. So just call self.readany() until EOF. - blocks = [] + buffer = io.BytesIO() while True: block = await self.readany() if not block: break - blocks.append(block) - return b"".join(blocks) + buffer.write(block) + return buffer.getvalue() # TODO: should be `if` instead of `while` # because waiter maybe triggered on chunk end, @@ -464,16 +465,16 @@ async def readexactly(self, n: int) -> bytes: if self._exception is not None: raise self._exception - blocks: List[bytes] = [] + buffer = io.BytesIO() while n > 0: block = await self.read(n) if not block: - partial = b"".join(blocks) + partial = buffer.getvalue() raise asyncio.IncompleteReadError(partial, len(partial) + n) - blocks.append(block) + buffer.write(block) n -= len(block) - return b"".join(blocks) + return buffer.getvalue() def read_nowait(self, n: int = -1) -> bytes: # default was changed to be consistent with .read(-1) @@ -522,16 +523,16 @@ def _read_nowait(self, n: int) -> bytes: """Read not more than n bytes, or whole buffer if n == -1""" self._timer.assert_timeout() - chunks = [] + buffer = io.BytesIO() while self._buffer: chunk = self._read_nowait_chunk(n) - chunks.append(chunk) + buffer.write(chunk) if n != -1: n -= len(chunk) if n == 0: break - return b"".join(chunks) if chunks else b"" + return buffer.getvalue() class EmptyStreamReader(StreamReader): # lgtm [py/missing-call-to-init]