@@ -20,6 +20,8 @@ class AbstractContextManager(abc.ABC):
2020
2121 __class_getitem__ = classmethod (GenericAlias )
2222
23+ __slots__ = ()
24+
2325 def __enter__ (self ):
2426 """Return `self` upon entering the runtime context."""
2527 return self
@@ -42,6 +44,8 @@ class AbstractAsyncContextManager(abc.ABC):
4244
4345 __class_getitem__ = classmethod (GenericAlias )
4446
47+ __slots__ = ()
48+
4549 async def __aenter__ (self ):
4650 """Return `self` upon entering the runtime context."""
4751 return self
@@ -565,11 +569,12 @@ def __enter__(self):
565569 return self
566570
567571 def __exit__ (self , * exc_details ):
568- received_exc = exc_details [0 ] is not None
572+ exc = exc_details [1 ]
573+ received_exc = exc is not None
569574
570575 # We manipulate the exception state so it behaves as though
571576 # we were actually nesting multiple with statements
572- frame_exc = sys .exc_info ()[ 1 ]
577+ frame_exc = sys .exception ()
573578 def _fix_exception_context (new_exc , old_exc ):
574579 # Context may not be correct, so find the end of the chain
575580 while 1 :
@@ -592,24 +597,28 @@ def _fix_exception_context(new_exc, old_exc):
592597 is_sync , cb = self ._exit_callbacks .pop ()
593598 assert is_sync
594599 try :
600+ if exc is None :
601+ exc_details = None , None , None
602+ else :
603+ exc_details = type (exc ), exc , exc .__traceback__
595604 if cb (* exc_details ):
596605 suppressed_exc = True
597606 pending_raise = False
598- exc_details = (None , None , None )
599- except :
600- new_exc_details = sys .exc_info ()
607+ exc = None
608+ except BaseException as new_exc :
601609 # simulate the stack of exceptions by setting the context
602- _fix_exception_context (new_exc_details [ 1 ], exc_details [ 1 ] )
610+ _fix_exception_context (new_exc , exc )
603611 pending_raise = True
604- exc_details = new_exc_details
612+ exc = new_exc
613+
605614 if pending_raise :
606615 try :
607- # bare "raise exc_details[1] " replaces our carefully
616+ # bare "raise exc " replaces our carefully
608617 # set-up context
609- fixed_ctx = exc_details [ 1 ] .__context__
610- raise exc_details [ 1 ]
618+ fixed_ctx = exc .__context__
619+ raise exc
611620 except BaseException :
612- exc_details [ 1 ] .__context__ = fixed_ctx
621+ exc .__context__ = fixed_ctx
613622 raise
614623 return received_exc and suppressed_exc
615624
@@ -705,11 +714,12 @@ async def __aenter__(self):
705714 return self
706715
707716 async def __aexit__ (self , * exc_details ):
708- received_exc = exc_details [0 ] is not None
717+ exc = exc_details [1 ]
718+ received_exc = exc is not None
709719
710720 # We manipulate the exception state so it behaves as though
711721 # we were actually nesting multiple with statements
712- frame_exc = sys .exc_info ()[ 1 ]
722+ frame_exc = sys .exception ()
713723 def _fix_exception_context (new_exc , old_exc ):
714724 # Context may not be correct, so find the end of the chain
715725 while 1 :
@@ -731,6 +741,10 @@ def _fix_exception_context(new_exc, old_exc):
731741 while self ._exit_callbacks :
732742 is_sync , cb = self ._exit_callbacks .pop ()
733743 try :
744+ if exc is None :
745+ exc_details = None , None , None
746+ else :
747+ exc_details = type (exc ), exc , exc .__traceback__
734748 if is_sync :
735749 cb_suppress = cb (* exc_details )
736750 else :
@@ -739,21 +753,21 @@ def _fix_exception_context(new_exc, old_exc):
739753 if cb_suppress :
740754 suppressed_exc = True
741755 pending_raise = False
742- exc_details = (None , None , None )
743- except :
744- new_exc_details = sys .exc_info ()
756+ exc = None
757+ except BaseException as new_exc :
745758 # simulate the stack of exceptions by setting the context
746- _fix_exception_context (new_exc_details [ 1 ], exc_details [ 1 ] )
759+ _fix_exception_context (new_exc , exc )
747760 pending_raise = True
748- exc_details = new_exc_details
761+ exc = new_exc
762+
749763 if pending_raise :
750764 try :
751- # bare "raise exc_details[1] " replaces our carefully
765+ # bare "raise exc " replaces our carefully
752766 # set-up context
753- fixed_ctx = exc_details [ 1 ] .__context__
754- raise exc_details [ 1 ]
767+ fixed_ctx = exc .__context__
768+ raise exc
755769 except BaseException :
756- exc_details [ 1 ] .__context__ = fixed_ctx
770+ exc .__context__ = fixed_ctx
757771 raise
758772 return received_exc and suppressed_exc
759773
0 commit comments