From 176baa326be4ec2dc70ca0c054b7e2ab7ca6a9cf Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Wed, 13 Dec 2017 17:19:17 -0800 Subject: bpo-30241: implement contextlib.AbstractAsyncContextManager (#1412) --- Lib/contextlib.py | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'Lib/contextlib.py') diff --git a/Lib/contextlib.py b/Lib/contextlib.py index c1f8a84617f..96c8c22084a 100644 --- a/Lib/contextlib.py +++ b/Lib/contextlib.py @@ -6,7 +6,8 @@ from collections import deque from functools import wraps __all__ = ["asynccontextmanager", "contextmanager", "closing", "nullcontext", - "AbstractContextManager", "ContextDecorator", "ExitStack", + "AbstractContextManager", "AbstractAsyncContextManager", + "ContextDecorator", "ExitStack", "redirect_stdout", "redirect_stderr", "suppress"] @@ -30,6 +31,27 @@ class AbstractContextManager(abc.ABC): return NotImplemented +class AbstractAsyncContextManager(abc.ABC): + + """An abstract base class for asynchronous context managers.""" + + async def __aenter__(self): + """Return `self` upon entering the runtime context.""" + return self + + @abc.abstractmethod + async def __aexit__(self, exc_type, exc_value, traceback): + """Raise any exception triggered within the runtime context.""" + return None + + @classmethod + def __subclasshook__(cls, C): + if cls is AbstractAsyncContextManager: + return _collections_abc._check_methods(C, "__aenter__", + "__aexit__") + return NotImplemented + + class ContextDecorator(object): "A base class or mixin that enables context managers to work as decorators." @@ -136,7 +158,8 @@ class _GeneratorContextManager(_GeneratorContextManagerBase, raise RuntimeError("generator didn't stop after throw()") -class _AsyncGeneratorContextManager(_GeneratorContextManagerBase): +class _AsyncGeneratorContextManager(_GeneratorContextManagerBase, + AbstractAsyncContextManager): """Helper for @asynccontextmanager.""" async def __aenter__(self): -- cgit v1.2.3