mirror of https://github.com/python/cpython
gh-103462: Ensure SelectorSocketTransport.writelines registers a writer when data is still pending (#103463)
This commit is contained in:
parent
9e677406ee
commit
19d2639d1e
|
@ -1176,6 +1176,9 @@ class _SelectorSocketTransport(_SelectorTransport):
|
|||
return
|
||||
self._buffer.extend([memoryview(data) for data in list_of_data])
|
||||
self._write_ready()
|
||||
# If the entire buffer couldn't be written, register a write handler
|
||||
if self._buffer:
|
||||
self._loop._add_writer(self._sock_fd, self._write_ready)
|
||||
|
||||
def can_write_eof(self):
|
||||
return True
|
||||
|
|
|
@ -747,6 +747,48 @@ class SelectorSocketTransportTests(test_utils.TestCase):
|
|||
self.assertFalse(self.sock.sendmsg.called)
|
||||
self.assertEqual(list_to_buffer([b'data']), transport._buffer)
|
||||
|
||||
@unittest.skipUnless(selector_events._HAS_SENDMSG, 'no sendmsg')
|
||||
def test_writelines_sendmsg_full(self):
|
||||
data = memoryview(b'data')
|
||||
self.sock.sendmsg = mock.Mock()
|
||||
self.sock.sendmsg.return_value = len(data)
|
||||
|
||||
transport = self.socket_transport(sendmsg=True)
|
||||
transport.writelines([data])
|
||||
self.assertTrue(self.sock.sendmsg.called)
|
||||
self.assertFalse(self.loop.writers)
|
||||
|
||||
@unittest.skipUnless(selector_events._HAS_SENDMSG, 'no sendmsg')
|
||||
def test_writelines_sendmsg_partial(self):
|
||||
data = memoryview(b'data')
|
||||
self.sock.sendmsg = mock.Mock()
|
||||
self.sock.sendmsg.return_value = 2
|
||||
|
||||
transport = self.socket_transport(sendmsg=True)
|
||||
transport.writelines([data])
|
||||
self.assertTrue(self.sock.sendmsg.called)
|
||||
self.assertTrue(self.loop.writers)
|
||||
|
||||
def test_writelines_send_full(self):
|
||||
data = memoryview(b'data')
|
||||
self.sock.send.return_value = len(data)
|
||||
self.sock.send.fileno.return_value = 7
|
||||
|
||||
transport = self.socket_transport()
|
||||
transport.writelines([data])
|
||||
self.assertTrue(self.sock.send.called)
|
||||
self.assertFalse(self.loop.writers)
|
||||
|
||||
def test_writelines_send_partial(self):
|
||||
data = memoryview(b'data')
|
||||
self.sock.send.return_value = 2
|
||||
self.sock.send.fileno.return_value = 7
|
||||
|
||||
transport = self.socket_transport()
|
||||
transport.writelines([data])
|
||||
self.assertTrue(self.sock.send.called)
|
||||
self.assertTrue(self.loop.writers)
|
||||
|
||||
@unittest.skipUnless(selector_events._HAS_SENDMSG, 'no sendmsg')
|
||||
def test_write_sendmsg_full(self):
|
||||
data = memoryview(b'data')
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Fixed an issue with using :meth:`~asyncio.WriteTransport.writelines` in :mod:`asyncio` to send very
|
||||
large payloads that exceed the amount of data that can be written in one
|
||||
call to :meth:`socket.socket.send` or :meth:`socket.socket.sendmsg`,
|
||||
resulting in the remaining buffer being left unwritten.
|
Loading…
Reference in New Issue