8000 gh-102799: use sys.exception() instead of sys.exc_info() in contextli… · python/cpython@eeff8e7 · GitHub
[go: up one dir, main page]

Skip to content

Commit eeff8e7

Browse files
gh-102799: use sys.exception() instead of sys.exc_info() in contextlib (#103311)
Co-authored-by: Kumar Aditya <kumaraditya@python.org>
1 parent 832c37d commit eeff8e7

File tree

3 files changed

+34
-24
lines changed

3 files changed

+34
-24
lines changed

Lib/contextlib.py

+32-22
Original file line numberDiff line numberDiff line change
@@ -557,11 +557,12 @@ def __enter__(self):
557557
return self
558558

559559
def __exit__(self, *exc_details):
560-
received_exc = exc_details[0] is not None
560+
exc = exc_details[1]
561+
received_exc = exc is not None
561562

562563
# We manipulate the exception state so it behaves as though
563564
# we were actually nesting multiple with statements
564-
frame_exc = sys.exc_info()[1]
565+
frame_exc = sys.exception()
565566
def _fix_exception_context(new_exc, old_exc):
566567
# Context may not be correct, so find the end of the chain
567568
while 1:
@@ -584,24 +585,28 @@ def _fix_exception_context(new_exc, old_exc):
584585
is_sync, cb = self._exit_callbacks.pop()
585586
assert is_sync
586587
try:
588+
if exc is None:
589+
exc_details = None, None, None
590+
else:
591+
exc_details = type(exc), exc, exc.__traceback__
587592
if cb(*exc_details):
588593
suppressed_exc = True
589594
pending_raise = False
590-
exc_details = (None, None, None)
591-
except:
592-
new_exc_details = sys.exc_info()
595+
exc = None
596+
except BaseException as new_exc:
593597
# simulate the stack of exceptions by setting the context
594-
_fix_exception_context(new_exc_details[1], exc_details[1])
598+
_fix_exception_context(new_exc, exc)
595599
pending_raise = True
596-
exc_details = new_exc_details
600+
exc = new_exc
601+
597602
if pending_raise:
598603
try:
599-
# bare "raise exc_details[1]" replaces our carefully
604+
# bare "raise exc" replaces our carefully
600605
# set-up context
601-
fixed_ctx = exc_details[1].__context__
602-
raise exc_details[1]
606+
fixed_ctx = exc.__context__
607+
raise exc
603608
except BaseException:
604-
exc_details[1].__context__ = fixed_ctx
609+
exc.__context__ = fixed_ctx
605610
raise
606611
return received_exc and suppressed_exc
607612

@@ -697,11 +702,12 @@ async def __aenter__(self):
697702
return self
698703

699704
async def __aexit__(self, *exc_details):
700-
received_exc = exc_details[0] is not None
705+
exc = exc_details[1]
706+
received_exc = exc is not None
701707

702708
# We manipulate the exception state so it behaves as though
703709
# we were actually nesting multiple with statements
704-
frame_exc = sys.exc_info()[1]
710+
frame_exc = sys.exception()
705711
def _fix_exception_context(new_exc, old_exc):
706712
# Context may not be correct, so find the end of the chain
707713
while 1:
@@ -723,6 +729,10 @@ def _fix_exception_context(new_exc, old_exc):
723729
while self._exit_callbacks:
724730
is_sync, cb = self._exit_callbacks.pop()
725731
try:
732+
if exc is None:
733+
exc_details = None, None, None
734+
else:
735+
exc_details = type(exc), exc, exc.__traceback__
726736
if is_sync:
727737
cb_suppress = cb(*exc_details)
728738
else:
@@ -731,21 +741,21 @@ def _fix_exception_context(new_exc, old_exc):
731741
if cb_suppress:
732742
suppressed_exc = True
733743
pending_raise = False
734-
exc_details = (None, None, None)
735-
except:
736-
new_exc_details = sys.exc_info()
744+
exc = None
745+
except BaseException as new_exc:
737746
# simulate the stack of exceptions by setting the context
738-
_fix_exception_context(new_exc_details[1], exc_details[1])
747+
_fix_exception_context(new_exc, exc)
739748
pending_raise = True
740-
exc_details = new_exc_details
749+
exc = new_exc
750+
741751
if pending_raise:
742752
try:
743-
# bare "raise exc_details[1]" replaces our carefully
753+
# bare "raise exc" replaces our carefully
744754
# set-up context
745-
fixed_ctx = exc_details[1].__context__
746-
raise exc_details[1]
755+
fixed_ctx = exc.__context__
756+
raise exc
747757
except BaseException:
748-
exc_details[1].__context__ = fixed_ctx
758+
exc.__context__ = fixed_ctx
749759
raise
750760
return received_exc and suppressed_exc
751761

Lib/test/test_contextlib.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1085,7 +1085,7 @@ def first():
10851085
class TestExitStack(TestBaseExitStack, unittest.TestCase):
10861086
exit_stack = ExitStack
10871087
callback_error_internal_frames = [
1088-
('__exit__', 'raise exc_details[1]'),
1088+
('__exit__', 'raise exc'),
10891089
('__exit__', 'if cb(*exc_details):'),
10901090
]
10911091

Lib/test/test_contextlib_async.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ def __exit__(self, *exc_details):
557557
('__exit__', 'return self.run_coroutine(self.__aexit__(*exc_details))'),
558558
('run_coroutine', 'raise exc'),
559559
('run_coroutine', 'raise exc'),
560-
('__aexit__', 'raise exc_details[1]'),
560+
('__aexit__', 'raise exc'),
561561
('__aexit__', 'cb_suppress = cb(*exc_details)'),
562562
]
563563

0 commit comments

Comments
 (0)
0