Wrong exception re-raises if task raises CancelledError inside except block
import asyncio
from contextlib import suppress
async def main():
task = asyncio.ensure_future(asyncio.sleep(1))
task.cancel()
try:
raise Exception()
except Exception:
with suppress(asyncio.CancelledError):
await task
raise
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Expected output:
Exception
Actual output:
concurrent.futures._base.CancelledError
Windows 10, Python 3.5.0
I can repro this too -- it's not unique to Windows or to PEP 492 (it fails the same way with coroutine/yield-from in Python 3.4). It's also not due to something in contextlib.suppress() or due to having a try/except in the outer except clause.
@1st1 -- do you have any suggestions? I suspect there's some special-casing of CancelledError that goes wrong here.
I might be mistaken here, but it looks like this a bug in CPython...
class MainError(Exception):
pass
class SubError(Exception):
pass
def sub():
yield
def main():
try:
raise MainError()
except MainError:
try:
yield from sub()
except SubError:
pass
raise
coro = main()
coro.send(None)
coro.throw(SubError())
Outputs:
Traceback (most recent call last):
File "t.py", line 47, in <module>
coro.throw(SubError())
File "t.py", line 43, in main
raise
RuntimeError: No active exception to reraise
And if you replace except MainError: with except MainError as e:, and raise with raise e then everything works correctly.
It's not even a yield from bug:
class MainError(Exception):
pass
class SubError(Exception):
pass
def main():
try:
raise MainError()
except MainError:
try:
yield
except SubError:
print('got SubError')
raise
coro = main()
coro.send(None)
coro.throw(SubError())
Outputs:
got SubError
Traceback (most recent call last):
File "t.py", line 19, in <module>
coro.throw(SubError())
File "t.py", line 15, in main
raise
RuntimeError: No active exception to reraise
http://bugs.python.org/issue25612
Thanks for the thorough investigation!