MCPcopy Index your code
hub / github.com/RustPython/RustPython / ExitStack

Class ExitStack

Lib/contextlib.py:557–627  ·  view source on GitHub ↗

Context manager for dynamic management of a stack of exit callbacks. For example: with ExitStack() as stack: files = [stack.enter_context(open(fname)) for fname in filenames] # All opened files will automatically be closed at the end of # the with sta

Source from the content-addressed store, hash-verified

555
556# Inspired by discussions on http://bugs.python.org/issue13585
557class ExitStack(_BaseExitStack, AbstractContextManager):
558 """Context manager for dynamic management of a stack of exit callbacks.
559
560 For example:
561 with ExitStack() as stack:
562 files = [stack.enter_context(open(fname)) for fname in filenames]
563 # All opened files will automatically be closed at the end of
564 # the with statement, even if attempts to open files later
565 # in the list raise an exception.
566 """
567
568 def __enter__(self):
569 return self
570
571 def __exit__(self, *exc_details):
572 exc = exc_details[1]
573 received_exc = exc is not None
574
575 # We manipulate the exception state so it behaves as though
576 # we were actually nesting multiple with statements
577 frame_exc = sys.exception()
578 def _fix_exception_context(new_exc, old_exc):
579 # Context may not be correct, so find the end of the chain
580 while 1:
581 exc_context = new_exc.__context__
582 if exc_context is None or exc_context is old_exc:
583 # Context is already set correctly (see issue 20317)
584 return
585 if exc_context is frame_exc:
586 break
587 new_exc = exc_context
588 # Change the end of the chain to point to the exception
589 # we expect it to reference
590 new_exc.__context__ = old_exc
591
592 # Callbacks are invoked in LIFO order to match the behaviour of
593 # nested context managers
594 suppressed_exc = False
595 pending_raise = False
596 while self._exit_callbacks:
597 is_sync, cb = self._exit_callbacks.pop()
598 assert is_sync
599 try:
600 if exc is None:
601 exc_details = None, None, None
602 else:
603 exc_details = type(exc), exc, exc.__traceback__
604 if cb(*exc_details):
605 suppressed_exc = True
606 pending_raise = False
607 exc = None
608 except BaseException as new_exc:
609 # simulate the stack of exceptions by setting the context
610 _fix_exception_context(new_exc, exc)
611 pending_raise = True
612 exc = new_exc
613
614 if pending_raise:

Callers 5

stream_contextMethod · 0.90
setUpMethod · 0.90
mock_sysMethod · 0.90
setUpClassMethod · 0.90
run_ptyFunction · 0.90

Calls

no outgoing calls

Tested by 4

stream_contextMethod · 0.72
setUpMethod · 0.72
mock_sysMethod · 0.72
setUpClassMethod · 0.72