gh-76785: Show the Traceback for Uncaught Subinterpreter Exceptions (gh-113034)

When an exception is uncaught in Interpreter.exec_sync(), it helps to show that exception's error display if uncaught in the calling interpreter.  We do so here by generating a TracebackException in the subinterpreter and passing it between interpreters using pickle.
This commit is contained in:
Eric Snow 2023-12-12 17:00:54 -07:00 committed by GitHub
parent 7316dfb0eb
commit 8a4c1f3ff1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 351 additions and 16 deletions

View file

@ -525,6 +525,54 @@ class TestInterpreterExecSync(TestBase):
with self.assertRaises(interpreters.ExecFailure):
interp.exec_sync('raise Exception')
def test_display_preserved_exception(self):
tempdir = self.temp_dir()
modfile = self.make_module('spam', tempdir, text="""
def ham():
raise RuntimeError('uh-oh!')
def eggs():
ham()
""")
scriptfile = self.make_script('script.py', tempdir, text="""
from test.support import interpreters
def script():
import spam
spam.eggs()
interp = interpreters.create()
interp.exec_sync(script)
""")
stdout, stderr = self.assert_python_failure(scriptfile)
self.maxDiff = None
interpmod_line, = (l for l in stderr.splitlines() if ' exec_sync' in l)
# File "{interpreters.__file__}", line 179, in exec_sync
self.assertEqual(stderr, dedent(f"""\
Traceback (most recent call last):
File "{scriptfile}", line 9, in <module>
interp.exec_sync(script)
~~~~~~~~~~~~~~~~^^^^^^^^
{interpmod_line.strip()}
raise ExecFailure(excinfo)
test.support.interpreters.ExecFailure: RuntimeError: uh-oh!
Uncaught in the interpreter:
Traceback (most recent call last):
File "{scriptfile}", line 6, in script
spam.eggs()
~~~~~~~~~^^
File "{modfile}", line 6, in eggs
ham()
~~~^^
File "{modfile}", line 3, in ham
raise RuntimeError('uh-oh!')
RuntimeError: uh-oh!
"""))
self.assertEqual(stdout, '')
def test_in_thread(self):
interp = interpreters.create()
script, file = _captured_script('print("it worked!", end="")')