From c66204a0f79ea0658d148da3eaf08fe6071c1f07 Mon Sep 17 00:00:00 2001 From: "Mads R. B. Kristensen" Date: Tue, 2 Mar 2021 10:52:29 +0100 Subject: [PATCH] BaseIOStream.write(): support typed memoryview Making sure that ``len(data) == data.nbytes`` by casting memoryviews to bytes. --- tornado/iostream.py | 3 +++ tornado/test/iostream_test.py | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/tornado/iostream.py b/tornado/iostream.py index 7610bce4f..86235f4dc 100644 --- a/tornado/iostream.py +++ b/tornado/iostream.py @@ -529,6 +529,9 @@ class BaseIOStream(object): """ self._check_closed() if data: + if isinstance(data, memoryview): + # Make sure that ``len(data) == data.nbytes`` + data = memoryview(data).cast("B") if ( self.max_write_buffer_size is not None and len(self._write_buffer) + len(data) > self.max_write_buffer_size diff --git a/tornado/test/iostream_test.py b/tornado/test/iostream_test.py index a43aa64ca..797a2dfc1 100644 --- a/tornado/test/iostream_test.py +++ b/tornado/test/iostream_test.py @@ -1047,6 +1047,17 @@ class TestIOStreamStartTLS(AsyncTestCase): # The server fails to connect, but the exact error is unspecified. yield server_future + @gen_test + def test_typed_memoryview(self): + # Test support of memoryviews with an item size greater than 1 byte. + buf = memoryview(bytes(80)).cast("L") + assert self.server_stream is not None + yield self.server_stream.write(buf) + assert self.client_stream is not None + # This will timeout if the calculation of the buffer size is incorrect + recv = yield self.client_stream.read_bytes(buf.nbytes) + self.assertEqual(bytes(recv), bytes(buf)) + class WaitForHandshakeTest(AsyncTestCase): @gen.coroutine -- 2.47.2