mirror of
https://github.com/python/cpython.git
synced 2025-08-28 20:56:54 +00:00
gh-92118: Add test for traceback when exception is modified by (Async)ExitStack.__exit__ (GH-92339)
This commit is contained in:
parent
ae553b3561
commit
e65e587f93
2 changed files with 43 additions and 0 deletions
|
@ -748,6 +748,38 @@ class TestBaseExitStack:
|
||||||
stack.push(lambda *exc: True)
|
stack.push(lambda *exc: True)
|
||||||
1/0
|
1/0
|
||||||
|
|
||||||
|
def test_exit_exception_traceback(self):
|
||||||
|
# This test captures the current behavior of ExitStack so that we know
|
||||||
|
# if we ever unintendedly change it. It is not a statement of what the
|
||||||
|
# desired behavior is (for instance, we may want to remove some of the
|
||||||
|
# internal contextlib frames).
|
||||||
|
|
||||||
|
def raise_exc(exc):
|
||||||
|
raise exc
|
||||||
|
|
||||||
|
try:
|
||||||
|
with self.exit_stack() as stack:
|
||||||
|
stack.callback(raise_exc, ValueError)
|
||||||
|
1/0
|
||||||
|
except ValueError as e:
|
||||||
|
exc = e
|
||||||
|
|
||||||
|
self.assertIsInstance(exc, ValueError)
|
||||||
|
ve_frames = traceback.extract_tb(exc.__traceback__)
|
||||||
|
expected = \
|
||||||
|
[('test_exit_exception_traceback', 'with self.exit_stack() as stack:')] + \
|
||||||
|
self.callback_error_internal_frames + \
|
||||||
|
[('_exit_wrapper', 'callback(*args, **kwds)'),
|
||||||
|
('raise_exc', 'raise exc')]
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
[(f.name, f.line) for f in ve_frames], expected)
|
||||||
|
|
||||||
|
self.assertIsInstance(exc.__context__, ZeroDivisionError)
|
||||||
|
zde_frames = traceback.extract_tb(exc.__context__.__traceback__)
|
||||||
|
self.assertEqual([(f.name, f.line) for f in zde_frames],
|
||||||
|
[('test_exit_exception_traceback', '1/0')])
|
||||||
|
|
||||||
def test_exit_exception_chaining_reference(self):
|
def test_exit_exception_chaining_reference(self):
|
||||||
# Sanity check to make sure that ExitStack chaining matches
|
# Sanity check to make sure that ExitStack chaining matches
|
||||||
# actual nested with statements
|
# actual nested with statements
|
||||||
|
@ -1017,6 +1049,10 @@ class TestBaseExitStack:
|
||||||
|
|
||||||
class TestExitStack(TestBaseExitStack, unittest.TestCase):
|
class TestExitStack(TestBaseExitStack, unittest.TestCase):
|
||||||
exit_stack = ExitStack
|
exit_stack = ExitStack
|
||||||
|
callback_error_internal_frames = [
|
||||||
|
('__exit__', 'raise exc_details[1]'),
|
||||||
|
('__exit__', 'if cb(*exc_details):'),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class TestRedirectStream:
|
class TestRedirectStream:
|
||||||
|
|
|
@ -487,6 +487,13 @@ class TestAsyncExitStack(TestBaseExitStack, unittest.TestCase):
|
||||||
return self.run_coroutine(self.__aexit__(*exc_details))
|
return self.run_coroutine(self.__aexit__(*exc_details))
|
||||||
|
|
||||||
exit_stack = SyncAsyncExitStack
|
exit_stack = SyncAsyncExitStack
|
||||||
|
callback_error_internal_frames = [
|
||||||
|
('__exit__', 'return self.run_coroutine(self.__aexit__(*exc_details))'),
|
||||||
|
('run_coroutine', 'raise exc'),
|
||||||
|
('run_coroutine', 'raise exc'),
|
||||||
|
('__aexit__', 'raise exc_details[1]'),
|
||||||
|
('__aexit__', 'cb_suppress = cb(*exc_details)'),
|
||||||
|
]
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.loop = asyncio.new_event_loop()
|
self.loop = asyncio.new_event_loop()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue