diff --git a/cheroot/_compat.py b/cheroot/_compat.py index 8be7d75198..670aa719fd 100644 --- a/cheroot/_compat.py +++ b/cheroot/_compat.py @@ -65,3 +65,14 @@ def assert_native(n): """ if not isinstance(n, str): raise TypeError('n must be a native str (got %s)' % type(n).__name__) + + +if six.PY3: + """Python 3 has memoryview builtin.""" + # Python 2.7 has it backported, but socket.write() does + # str(memoryview(b'0' * 100)) -> + # instead of accessing it correctly. + memoryview = memoryview +else: + """Link memoryview to buffer under Python 2.""" + memoryview = buffer # noqa: F821 diff --git a/cheroot/makefile.py b/cheroot/makefile.py index bec864890c..52e66c0154 100644 --- a/cheroot/makefile.py +++ b/cheroot/makefile.py @@ -15,6 +15,7 @@ import six from . import errors +from ._compat import memoryview class BufferedWriter(io.BufferedWriter): @@ -64,10 +65,12 @@ def _drop(self): def write(self, data): """Sendall for non-blocking sockets.""" - while data: + bytes_sent = 0 + data_mv = memoryview(data) + payload_size = len(data_mv) + while bytes_sent < payload_size: try: - bytes_sent = self.send(data) - data = data[bytes_sent:] + bytes_sent += self.send(data_mv[bytes_sent:]) except socket.error as e: if e.args[0] not in errors.socket_errors_nonblocking: raise