Skip to content

Commit

Permalink
pythongh-117459: Keep the traceback in _convert_future_exc (python#11…
Browse files Browse the repository at this point in the history
  • Loading branch information
rsp4jack authored and diegorusso committed Apr 17, 2024
1 parent aef97cb commit 7bc2f07
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 4 deletions.
6 changes: 2 additions & 4 deletions Lib/asyncio/futures.py
Expand Up @@ -319,11 +319,9 @@ def _set_result_unless_cancelled(fut, result):
def _convert_future_exc(exc):
exc_class = type(exc)
if exc_class is concurrent.futures.CancelledError:
return exceptions.CancelledError(*exc.args)
elif exc_class is concurrent.futures.TimeoutError:
return exceptions.TimeoutError(*exc.args)
return exceptions.CancelledError(*exc.args).with_traceback(exc.__traceback__)
elif exc_class is concurrent.futures.InvalidStateError:
return exceptions.InvalidStateError(*exc.args)
return exceptions.InvalidStateError(*exc.args).with_traceback(exc.__traceback__)
else:
return exc

Expand Down
19 changes: 19 additions & 0 deletions Lib/test/test_asyncio/test_futures.py
Expand Up @@ -5,6 +5,7 @@
import re
import sys
import threading
import traceback
import unittest
from unittest import mock
from types import GenericAlias
Expand Down Expand Up @@ -416,6 +417,24 @@ def test_copy_state(self):
_copy_future_state(f_cancelled, newf_cancelled)
self.assertTrue(newf_cancelled.cancelled())

try:
raise concurrent.futures.InvalidStateError
except BaseException as e:
f_exc = e

f_conexc = self._new_future(loop=self.loop)
f_conexc.set_exception(f_exc)

newf_conexc = self._new_future(loop=self.loop)
_copy_future_state(f_conexc, newf_conexc)
self.assertTrue(newf_conexc.done())
try:
newf_conexc.result()
except BaseException as e:
newf_exc = e # assertRaises context manager drops the traceback
newf_tb = ''.join(traceback.format_tb(newf_exc.__traceback__))
self.assertEqual(newf_tb.count('raise concurrent.futures.InvalidStateError'), 1)

def test_iter(self):
fut = self._new_future(loop=self.loop)

Expand Down
@@ -0,0 +1 @@
:meth:`asyncio.asyncio.run_coroutine_threadsafe` now keeps the traceback of :class:`CancelledError`, :class:`TimeoutError` and :class:`InvalidStateError` which are raised in the coroutine.

0 comments on commit 7bc2f07

Please sign in to comment.