# HG changeset patch # User Augie Fackler # Date 2018-04-11 18:39:49 # Node ID 192b7ad06932682fa7f87e44f10a85bfabb4f7a7 # Parent b94fecf4cd8c64dc00a2fba35a6d771cbf568e16 keepalive: rewrite readinto() to not use read() It turns out http.client on Python 3 sometimes uses readinto() in the implementation of read(). Unfortunately, Python 2 doesn't have a readinto() in httplib's client, so we have to support both codepaths. Subclassing is bad, folks. Differential Revision: https://phab.mercurial-scm.org/D3246 diff --git a/mercurial/keepalive.py b/mercurial/keepalive.py --- a/mercurial/keepalive.py +++ b/mercurial/keepalive.py @@ -384,6 +384,7 @@ class HTTPResponse(httplib.HTTPResponse) self._connection = None # (same) _raw_read = httplib.HTTPResponse.read + _raw_readinto = getattr(httplib.HTTPResponse, 'readinto', None) def close(self): if self.fp: @@ -523,12 +524,24 @@ class HTTPResponse(httplib.HTTPResponse) return list def readinto(self, dest): - res = self.read(len(dest)) - if not res: - return 0 - - dest[0:len(res)] = res - return len(res) + if self._raw_readinto is None: + res = self.read(len(dest)) + if not res: + return 0 + dest[0:len(res)] = res + return len(res) + total = len(dest) + have = len(self._rbuf) + if have >= total: + dest[0:total] = self._rbuf[:total] + self._rbuf = self._rbuf[total:] + return total + mv = memoryview(dest) + got = self._raw_readinto(mv[have:total]) + dest[0:have] = self._rbuf + got += len(self._rbuf) + self._rbuf = '' + return got def safesend(self, str): """Send `str' to the server.