From f12ba7cd0a7370631214ac0b337ab5455ce717b2 Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Tue, 14 May 2019 19:09:44 +0300 Subject: bpo-36916: asyncio: Swallow unhandled write() exception (GH-13313) --- Lib/asyncio/streams.py | 11 ++++++++++- Lib/test/test_asyncio/test_streams.py | 3 +++ .../next/Library/2019-05-14-15-39-34.bpo-36916._GPsTt.rst | 2 ++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2019-05-14-15-39-34.bpo-36916._GPsTt.rst diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py index d9a9f5e..146a338 100644 --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -329,6 +329,13 @@ class StreamReaderProtocol(FlowControlMixin, protocols.Protocol): closed.exception() +def _swallow_unhandled_exception(task): + # Do a trick to suppress unhandled exception + # if stream.write() was used without await and + # stream.drain() was paused and resumed with an exception + task.exception() + + class StreamWriter: """Wraps a Transport. @@ -393,7 +400,9 @@ class StreamWriter: # fast path, the stream is not paused # no need to wait for resume signal return self._complete_fut - return self._loop.create_task(self.drain()) + ret = self._loop.create_task(self.drain()) + ret.add_done_callback(_swallow_unhandled_exception) + return ret def write_eof(self): return self._transport.write_eof() diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index bf93f30..8d6a1d2 100644 --- a/Lib/test/test_asyncio/test_streams.py +++ b/Lib/test/test_asyncio/test_streams.py @@ -851,6 +851,8 @@ os.close(fd) # where it never gives up the event loop but the socket is # closed on the server side. + messages = [] + self.loop.set_exception_handler(lambda loop, ctx: messages.append(ctx)) q = queue.Queue() def server(): @@ -883,6 +885,7 @@ os.close(fd) # Clean up the thread. (Only on success; on failure, it may # be stuck in accept().) thread.join() + self.assertEqual([], messages) def test___repr__(self): stream = asyncio.StreamReader(loop=self.loop, diff --git a/Misc/NEWS.d/next/Library/2019-05-14-15-39-34.bpo-36916._GPsTt.rst b/Misc/NEWS.d/next/Library/2019-05-14-15-39-34.bpo-36916._GPsTt.rst new file mode 100644 index 0000000..8726bb2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-05-14-15-39-34.bpo-36916._GPsTt.rst @@ -0,0 +1,2 @@ +Remove a message about an unhandled exception in a task when writer.write() +is used without await and writer.drain() fails with an exception. -- cgit v0.12