summaryrefslogtreecommitdiff
path: root/Lib/contextlib.py
diff options
context:
space:
mode:
authorMartin Panter <vadmium+py@gmail.com>2016-08-27 04:03:26 +0000
committerMartin Panter <vadmium+py@gmail.com>2016-08-27 04:03:26 +0000
commitc87b0b55733a717d67b88e622fd250b2cb33baec (patch)
tree7b45f4cd812c6793c7e4f009acaa12114d6d9891 /Lib/contextlib.py
parent1e57a267d3d6b0c901726fb81c63a2345c5b6910 (diff)
parent058e6a49c6e7b2847286eea5284a89b2757148d9 (diff)
downloadcpython-c87b0b55733a717d67b88e622fd250b2cb33baec.tar.gz
Issue #19884: Merge Readline updates from 3.5
Diffstat (limited to 'Lib/contextlib.py')
-rw-r--r--Lib/contextlib.py42
1 files changed, 31 insertions, 11 deletions
diff --git a/Lib/contextlib.py b/Lib/contextlib.py
index d44edd6e19..7d94a579c8 100644
--- a/Lib/contextlib.py
+++ b/Lib/contextlib.py
@@ -1,11 +1,34 @@
"""Utilities for with-statement contexts. See PEP 343."""
-
+import abc
import sys
from collections import deque
from functools import wraps
-__all__ = ["contextmanager", "closing", "ContextDecorator", "ExitStack",
- "redirect_stdout", "redirect_stderr", "suppress"]
+__all__ = ["contextmanager", "closing", "AbstractContextManager",
+ "ContextDecorator", "ExitStack", "redirect_stdout",
+ "redirect_stderr", "suppress"]
+
+
+class AbstractContextManager(abc.ABC):
+
+ """An abstract base class for context managers."""
+
+ 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
+
+ @classmethod
+ def __subclasshook__(cls, C):
+ if cls is AbstractContextManager:
+ if (any("__enter__" in B.__dict__ for B in C.__mro__) and
+ any("__exit__" in B.__dict__ for B in C.__mro__)):
+ return True
+ return NotImplemented
class ContextDecorator(object):
@@ -31,7 +54,7 @@ class ContextDecorator(object):
return inner
-class _GeneratorContextManager(ContextDecorator):
+class _GeneratorContextManager(ContextDecorator, AbstractContextManager):
"""Helper for @contextmanager decorator."""
def __init__(self, func, args, kwds):
@@ -137,7 +160,7 @@ def contextmanager(func):
return helper
-class closing(object):
+class closing(AbstractContextManager):
"""Context to automatically close something at the end of a block.
Code like this:
@@ -162,7 +185,7 @@ class closing(object):
self.thing.close()
-class _RedirectStream:
+class _RedirectStream(AbstractContextManager):
_stream = None
@@ -202,7 +225,7 @@ class redirect_stderr(_RedirectStream):
_stream = "stderr"
-class suppress:
+class suppress(AbstractContextManager):
"""Context manager to suppress specified exceptions
After the exception is suppressed, execution proceeds with the next
@@ -233,7 +256,7 @@ class suppress:
# 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:
@@ -312,9 +335,6 @@ class ExitStack(object):
"""Immediately unwind the context stack"""
self.__exit__(None, None, None)
- def __enter__(self):
- return self
-
def __exit__(self, *exc_details):
received_exc = exc_details[0] is not None