diff -r a2bf6d1e018e Doc/library/contextlib.rst --- a/Doc/library/contextlib.rst Fri Mar 18 13:24:15 2016 -0700 +++ b/Doc/library/contextlib.rst Fri Mar 18 15:48:04 2016 -0700 @@ -18,6 +18,26 @@ Functions and classes provided: +.. class:: AbstractContextManager + + An abstract base class for context managers. To learn the purposes of the + abstract methods of this class, see :ref:`typecontextmanager`. + + .. abstractmethod:: __enter__(self) + + Returns ``self``. + + .. abstractmethod:: __exit__(self, exc_type, exc_value, traceback) + + Returns ``None``. + + +.. class:: ContextManagerType(typing.Generic[T]) + + A type representing context managers. The type that the :meth:`__enter__` + method returns can be specified, e.g. ``ContextManagerType[TextIO]``. + + .. decorator:: contextmanager This function is a :term:`decorator` that can be used to define a factory diff -r a2bf6d1e018e Lib/contextlib.py --- a/Lib/contextlib.py Fri Mar 18 13:24:15 2016 -0700 +++ b/Lib/contextlib.py Fri Mar 18 15:48:04 2016 -0700 @@ -1,6 +1,8 @@ """Utilities for with-statement contexts. See PEP 343.""" +import abc import sys +import typing as t from collections import deque from functools import wraps @@ -8,6 +10,28 @@ "redirect_stdout", "redirect_stderr", "suppress"] +class AbstractContextManager(abc.ABC): + + """An abstract base class for context managers.""" + + @abc.abstractmethod + def __enter__(self): + """Return `self` upon entering the runtime context.""" + return self + + @abc.abstractmethod + def __exit__(self, exc_type, exc_value, traceback): + """Raise any exception triggered within the runtime context.""" + return None + + +class ContextManagerType(t.Generic[t.T], extra=AbstractContextManager): + + """Context manager type.""" + + __slots__ = () + + class ContextDecorator(object): "A base class or mixin that enables context managers to work as decorators." @@ -31,7 +55,7 @@ return inner -class _GeneratorContextManager(ContextDecorator): +class _GeneratorContextManager(ContextDecorator, AbstractContextManager): """Helper for @contextmanager decorator.""" def __init__(self, func, args, kwds): @@ -134,7 +158,7 @@ return helper -class closing(object): +class closing(AbstractContextManager): """Context to automatically close something at the end of a block. Code like this: @@ -159,7 +183,7 @@ self.thing.close() -class _RedirectStream: +class _RedirectStream(AbstractContextManager): _stream = None @@ -199,7 +223,7 @@ _stream = "stderr" -class suppress: +class suppress(AbstractContextManager): """Context manager to suppress specified exceptions After the exception is suppressed, execution proceeds with the next @@ -230,7 +254,7 @@ # Inspired by discussions on http://bugs.python.org/issue13585 -class ExitStack(object): +class ExitStack(AbstractContextManager): """Context manager for dynamic management of a stack of exit callbacks For example: