This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2017年04月16日 18:18 by socketpair, last changed 2022年04月11日 14:58 by admin.
| Messages (2) | |||
|---|---|---|---|
| msg291763 - (view) | Author: Марк Коренберг (socketpair) * | Date: 2017年04月16日 18:18 | |
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()
=====
|
|||
| msg377104 - (view) | Author: Guilherme Salgado (salgado) * | Date: 2020年09月18日 10:56 | |
I've also been affected by this and found that if you use asyncio.run() the coroutine is interrupted with a CancelledError as you'd expect. The following script shows that
=======================
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()
async def main():
listener = await asyncio.start_server(handle_connection, '127.0.0.1', 8888)
try:
async with listener:
await listener.serve_forever()
except KeyboardInterrupt:
print('KeyboardInterrupt')
asyncio.run(main())
=============================================
|
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:58:45 | admin | set | github: 74269 |
| 2020年09月18日 10:56:44 | salgado | set | nosy:
+ salgado messages: + msg377104 |
| 2017年04月16日 18:19:43 | socketpair | set | nosy:
+ yselivanov components: + asyncio versions: + Python 3.5 |
| 2017年04月16日 18:18:42 | socketpair | create | |