Bug report
Bug description:
An empty chunk passed to writelines() can never be drained, so the transport never finishes closing.
The current code will never return without raising TimeoutError:
import asyncio import socket async def main(): s1, s2 = socket.socketpair() reader, writer = await asyncio.open_connection(sock=s1) writer.writelines([b'hello', b'']) writer.close() try: await asyncio.wait_for(writer.wait_closed(), 3) print("closed") except TimeoutError: print("hang:", list(writer.transport._buffer)) asyncio.run(main())
But should finish with:
closed
Proposed fix - skip empty data chunks in writelines():
for data in list_of_data: if not data: continue self._buffer.append(memoryview(data)) self._buffer_size += len(data) if not self._buffer: return self._write_ready()
I have a fix ready
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS