https://github.com/python/cpython/commit/85843348c5f0b8c2f973e8bc586475e69af19cd2
commit: 85843348c5f0b8c2f973e8bc586475e69af19cd2
branch: main
author: rsp4jack <[email protected]>
committer: gvanrossum <[email protected]>
date: 2024-04-03T20:13:32-07:00
summary:
gh-117459: Keep the traceback in _convert_future_exc (#117460)
files:
A Misc/NEWS.d/next/Library/2024-04-02-13-13-46.gh-issue-117459.jiIZmH.rst
M Lib/asyncio/futures.py
M Lib/test/test_asyncio/test_futures.py
diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py
index 5d35321db7943b..9c1b5e49e1a70b 100644
--- a/Lib/asyncio/futures.py
+++ b/Lib/asyncio/futures.py
@@ -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
diff --git a/Lib/test/test_asyncio/test_futures.py
b/Lib/test/test_asyncio/test_futures.py
index d3e8efec1c04c2..458b70451a306a 100644
--- a/Lib/test/test_asyncio/test_futures.py
+++ b/Lib/test/test_asyncio/test_futures.py
@@ -5,6 +5,7 @@
import re
import sys
import threading
+import traceback
import unittest
from unittest import mock
from types import GenericAlias
@@ -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)
diff --git
a/Misc/NEWS.d/next/Library/2024-04-02-13-13-46.gh-issue-117459.jiIZmH.rst
b/Misc/NEWS.d/next/Library/2024-04-02-13-13-46.gh-issue-117459.jiIZmH.rst
new file mode 100644
index 00000000000000..549bd44112befe
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-04-02-13-13-46.gh-issue-117459.jiIZmH.rst
@@ -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.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]