New submission from Марк Коренберг: How to reproduce: Run the following program: ========================= import asyncio async def handle_connection(reader, writer): try: await reader.readexactly(42) except BaseException as err: print('Interesting: %r.' % err) raise finally: writer.close()
loop = asyncio.get_event_loop() coro = asyncio.start_server(handle_connection, '127.0.0.1', 8888) server = loop.run_until_complete(coro) try: loop.run_forever() except KeyboardInterrupt: print('KeyboardInterrupt catched.') server.close() loop.run_until_complete(server.wait_closed()) loop.close() ========================= 0. Python 3.5.2 1. Connect using telnet to localhost and port 888, type one short line and press Enter. 2. Type Ctrl+C in terminal where programw is running. 3. You will see the following output: ========================= ^CKeyboardInterrupt catched. Interesting: GeneratorExit(). Exception ignored in: <coroutine object handle_connection at 0x7fa6a1d91b48> Traceback (most recent call last): File "bug.py", line 12, in handle_connection writer.close() File "/usr/lib/python3.5/asyncio/streams.py", line 306, in close return self._transport.close() File "/usr/lib/python3.5/asyncio/selector_events.py", line 591, in close self._loop.call_soon(self._call_connection_lost, None) File "/usr/lib/python3.5/asyncio/base_events.py", line 567, in call_soon handle = self._call_soon(callback, args) File "/usr/lib/python3.5/asyncio/base_events.py", line 576, in _call_soon self._check_closed() File "/usr/lib/python3.5/asyncio/base_events.py", line 356, in _check_closed raise RuntimeError('Event loop is closed') RuntimeError: Event loop is closed Task was destroyed but it is pending! task: <Task pending coro=<handle_connection() done, defined at bug.py:4> wait_for=<Future pending cb=[Task._wakeup()]>> ========================= This is almost canonical example of asyncio usage. So I have two questions: 1. Why coroutine is interrupted with GeneratorExit instead of CancelledError ? 2. Why something happend AFTER io loop is closed ? 3. How to code all that right ? I want to close connection on any error. Example provided is simplified code. In real code it looks like: ===== try: await asyncio.wait_for(self._handle_connection(reader, writer), 60) except asyncio.TimeoutError: writer.transport.abort() except asyncio.CancelledError: writer.transport.abort() except Exception: writer.transport.abort() finally: writer.close() ===== ---------- messages: 291763 nosy: socketpair priority: normal severity: normal status: open title: Asyncio: GeneratorExit + strange exception _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue30083> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com