diff options
author | Chris Withers <chris@simplistix.co.uk> | 2009-09-04 17:04:16 (GMT) |
---|---|---|
committer | Chris Withers <chris@simplistix.co.uk> | 2009-09-04 17:04:16 (GMT) |
commit | 9c33cbfbef5858e83a0079e89d81ae6fb15fc360 (patch) | |
tree | 6f9ad05cceced3e80d2b77b3a9f31452df01110c | |
parent | 9338585791e56cb09fff1d48f21258191b085c8d (diff) | |
download | cpython-9c33cbfbef5858e83a0079e89d81ae6fb15fc360.zip cpython-9c33cbfbef5858e83a0079e89d81ae6fb15fc360.tar.gz cpython-9c33cbfbef5858e83a0079e89d81ae6fb15fc360.tar.bz2 |
Fixes issue #6838: use a list to accumulate the value instead of repeatedly concatenating strings.
-rw-r--r-- | Lib/http/client.py | 21 | ||||
-rw-r--r-- | Misc/NEWS | 5 |
2 files changed, 14 insertions, 12 deletions
diff --git a/Lib/http/client.py b/Lib/http/client.py index 496c89a..b7092de 100644 --- a/Lib/http/client.py +++ b/Lib/http/client.py @@ -518,10 +518,7 @@ class HTTPResponse(io.RawIOBase): def _read_chunked(self, amt): assert self.chunked != _UNKNOWN chunk_left = self.chunk_left - value = b"" - - # XXX This accumulates chunks by repeated string concatenation, - # which is not efficient as the number or size of chunks gets big. + value = [] while True: if chunk_left is None: line = self.fp.readline() @@ -534,22 +531,22 @@ class HTTPResponse(io.RawIOBase): # close the connection as protocol synchronisation is # probably lost self.close() - raise IncompleteRead(value) + raise IncompleteRead(b''.join(value)) if chunk_left == 0: break if amt is None: - value += self._safe_read(chunk_left) + value.append(self._safe_read(chunk_left)) elif amt < chunk_left: - value += self._safe_read(amt) + value.append(self._safe_read(amt)) self.chunk_left = chunk_left - amt - return value + return b''.join(value) elif amt == chunk_left: - value += self._safe_read(amt) + value.append(self._safe_read(amt)) self._safe_read(2) # toss the CRLF at the end of the chunk self.chunk_left = None - return value + return b''.join(value) else: - value += self._safe_read(chunk_left) + value.append(self._safe_read(chunk_left)) amt -= chunk_left # we read the whole chunk, get another @@ -570,7 +567,7 @@ class HTTPResponse(io.RawIOBase): # we read everything; close the "file" self.close() - return value + return b''.join(value) def _safe_read(self, amt): """Read the number of bytes requested, compensating for partial reads. @@ -68,6 +68,11 @@ C-API Library ------- +- Issue #6838: Use a list to accumulate the value instead of + repeatedly concatenating strings in http.client's + HTTPResponse._read_chunked providing a significant speed increase + when downloading large files servend with a Transfer-Encoding of 'chunked'. + - Trying to import a submodule from a module that is not a package, ImportError should be raised, not AttributeError. |