MCPcopy Index your code
hub / github.com/python/cpython / AsyncExitStack

Class AsyncExitStack

Lib/contextlib.py:628–755  ·  view source on GitHub ↗

Async context manager for dynamic management of a stack of exit callbacks. For example: async with AsyncExitStack() as stack: connections = [await stack.enter_async_context(get_connection()) for i in range(5)] # All opened connections will aut

Source from the content-addressed store, hash-verified

626
627# Inspired by discussions on https://bugs.python.org/issue29302
628class AsyncExitStack(_BaseExitStack, AbstractAsyncContextManager):
629 """Async context manager for dynamic management of a stack of exit
630 callbacks.
631
632 For example:
633 async with AsyncExitStack() as stack:
634 connections = [await stack.enter_async_context(get_connection())
635 for i in range(5)]
636 # All opened connections will automatically be released at the
637 # end of the async with statement, even if attempts to open a
638 # connection later in the list raise an exception.
639 """
640
641 @staticmethod
642 def _create_async_cb_wrapper(callback, /, *args, **kwds):
643 async def _exit_wrapper(exc_type, exc, tb):
644 await callback(*args, **kwds)
645 return _exit_wrapper
646
647 async def enter_async_context(self, cm):
648 """Enters the supplied async context manager.
649
650 If successful, also pushes its __aexit__ method as a callback and
651 returns the result of the __aenter__ method.
652 """
653 _enter = _lookup_special(cm, '__aenter__', _sentinel)
654 if _enter is _sentinel:
655 cls = type(cm)
656 raise TypeError(f"'{cls.__module__}.{cls.__qualname__}' object does "
657 f"not support the asynchronous context manager protocol")
658 _exit = _lookup_special(cm, '__aexit__', _sentinel)
659 if _exit is _sentinel:
660 cls = type(cm)
661 raise TypeError(f"'{cls.__module__}.{cls.__qualname__}' object does "
662 f"not support the asynchronous context manager protocol")
663 result = await _enter()
664 self._push_exit_callback(_exit, False)
665 return result
666
667 def push_async_exit(self, exit):
668 """Registers a coroutine function with the standard __aexit__ method
669 signature.
670
671 Can suppress exceptions the same way __aexit__ method can.
672 Also accepts any object with an __aexit__ method (registering a call
673 to the method instead of the object itself).
674 """
675 exit_method = _lookup_special(exit, '__aexit__', exit)
676 self._push_exit_callback(exit_method, False)
677 return exit # Allow use as a decorator
678
679 def push_async_callback(self, callback, /, *args, **kwds):
680 """Registers an arbitrary coroutine function and arguments.
681
682 Cannot suppress exceptions.
683 """
684 _exit_wrapper = self._create_async_cb_wrapper(callback, *args, **kwds)
685

Callers 2

test_async_callbackMethod · 0.90

Calls

no outgoing calls

Tested by 2

test_async_callbackMethod · 0.72

Used in the wild real call sites across dependent graphs

searching dependent graphs…