summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2013-03-11 05:26:51 (GMT)
committerRaymond Hettinger <python@rcn.com>2013-03-11 05:26:51 (GMT)
commite318a883fece5d9a45165670b5f995886f524820 (patch)
treebc9a655a3d7c0636940f6decf9b1f73f5bb97856
parentc0417357d14b72763ba919728a1449373d122647 (diff)
downloadcpython-e318a883fece5d9a45165670b5f995886f524820.zip
cpython-e318a883fece5d9a45165670b5f995886f524820.tar.gz
cpython-e318a883fece5d9a45165670b5f995886f524820.tar.bz2
Issue #15806: Add contextlib.ignored().
-rw-r--r--Doc/library/contextlib.rst20
-rw-r--r--Lib/contextlib.py14
-rw-r--r--Lib/test/test_contextlib.py22
-rw-r--r--Misc/NEWS3
4 files changed, 58 insertions, 1 deletions
diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst
index 41dfded..4c8fe78 100644
--- a/Doc/library/contextlib.rst
+++ b/Doc/library/contextlib.rst
@@ -94,6 +94,26 @@ Functions and classes provided:
without needing to explicitly close ``page``. Even if an error occurs,
``page.close()`` will be called when the :keyword:`with` block is exited.
+.. function:: ignored(*exceptions)
+
+ Return a context manager that ignores the specified expections if they
+ occur in the body of a with-statement.
+
+ For example::
+
+ from contextlib import ignored
+
+ with ignored(OSError):
+ os.remove('somefile.tmp')
+
+ This code is equivalent to::
+
+ try:
+ os.remove('somefile.tmp')
+ except OSError:
+ pass
+
+ .. versionadded:: 3.4
.. class:: ContextDecorator()
diff --git a/Lib/contextlib.py b/Lib/contextlib.py
index 0b6bf71..03c56da 100644
--- a/Lib/contextlib.py
+++ b/Lib/contextlib.py
@@ -4,7 +4,7 @@ import sys
from collections import deque
from functools import wraps
-__all__ = ["contextmanager", "closing", "ContextDecorator", "ExitStack"]
+__all__ = ["contextmanager", "closing", "ContextDecorator", "ExitStack", "ignored"]
class ContextDecorator(object):
@@ -140,6 +140,18 @@ class closing(object):
def __exit__(self, *exc_info):
self.thing.close()
+@contextmanager
+def ignored(*exceptions):
+ """Context manager to ignore specifed exceptions
+
+ with ignored(OSError):
+ os.remove(somefile)
+
+ """
+ try:
+ yield
+ except exceptions:
+ pass
# Inspired by discussions on http://bugs.python.org/issue13585
class ExitStack(object):
diff --git a/Lib/test/test_contextlib.py b/Lib/test/test_contextlib.py
index e52ed91..d13659d 100644
--- a/Lib/test/test_contextlib.py
+++ b/Lib/test/test_contextlib.py
@@ -594,6 +594,28 @@ class TestExitStack(unittest.TestCase):
stack.push(cm)
self.assertIs(stack._exit_callbacks[-1], cm)
+class TestIgnored(unittest.TestCase):
+
+ def test_no_exception(self):
+
+ with ignored(ValueError):
+ self.assertEqual(pow(2, 5), 32)
+
+ def test_exact_exception(self):
+
+ with ignored(TypeError):
+ len(5)
+
+ def test_multiple_exception_args(self):
+
+ with ignored(ZeroDivisionError, TypeError):
+ len(5)
+
+ def test_exception_hierarchy(self):
+
+ with ignored(LookupError):
+ 'Hello'[50]
+
# This is needed to make the test actually run under regrtest.py!
def test_main():
diff --git a/Misc/NEWS b/Misc/NEWS
index dcf4812..607ad5e 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -280,6 +280,9 @@ Library
_ Issue #17385: Fix quadratic behavior in threading.Condition. The FIFO
queue now uses a deque instead of a list.
+- Issue #15806: Add contextlib.ignored(). This creates a context manager
+ to ignore specified exceptions, replacing the "except Exc: pass" idiom.
+
- Issue #14645: The email generator classes now produce output using the
specified linesep throughout. Previously if the prolog, epilog, or
body were stored with a different linesep, that linesep was used. This