]> granicus.if.org Git - python/commitdiff
Introduce test.test_support.TransientResource. It's a context manager to
authorBrett Cannon <bcannon@gmail.com>
Thu, 8 Mar 2007 23:58:11 +0000 (23:58 +0000)
committerBrett Cannon <bcannon@gmail.com>
Thu, 8 Mar 2007 23:58:11 +0000 (23:58 +0000)
surround calls to resources that may or may not be available.  Specifying the
expected exception and attributes to be raised if the resource is not available
prevents overly broad catching of exceptions.

This is meant to help suppress spurious failures by raising
test.test_support.ResourceDenied if the exception matches.  It would probably
be good to go through the various network tests and surround the calls to catch
connection timeouts (as done with test_socket_ssl in this commit).

Doc/lib/libtest.tex
Lib/test/test_socket_ssl.py
Lib/test/test_support.py
Misc/NEWS

index f30b49bcbf818d23e72383aef8d65b7f940bfe58..326c5f0e2baa0fbec162af2e16cef5e1f4d884f4 100644 (file)
@@ -285,6 +285,14 @@ originated from.
 
 The \module{test.test_support} module defines the following classes:
 
+\begin{classdesc}{TransientResource}{exc\optional{, **kwargs}}
+Create a context manager that raises \class{ResourceDenied} if the specified
+exception type is raised.  Any keyword arguments are treated as name/value
+pairs to be compared against any exception raised with the \code{with}
+statement.  Only if all pairs match is \class{ResourceDenied} raised.
+\versionadded{2.6}
+\end{classdesc}
+
 \begin{classdesc}{EnvironmentVarGuard}{}
 Class used to temporarily set or unset environment variables.  Instances can be
 used as a context manager.
index 3c9c9f03c0eb5ab4b73edb97c2efcaf071a199bc..8fb7e4c13e84b39e02ce87427b167f3c89324500 100644 (file)
@@ -27,7 +27,8 @@ def test_basic():
         print "didn't raise TypeError"
     socket.RAND_add("this is a random string", 75.0)
 
-    f = urllib.urlopen('https://sf.net')
+    with test_support.TransientResource(IOError, errno=errno.ETIMEDOUT):
+        f = urllib.urlopen('https://sf.net')
     buf = f.read()
     f.close()
 
index 82fd5f4131b5741f919f8df320504ff83fd662e2..2e47aedf214a19cf8c8f747c6f1a3772aa138a93 100644 (file)
@@ -312,6 +312,31 @@ class EnvironmentVarGuard(object):
         for unset in self._unset:
             del self._environ[unset]
 
+class TransientResource(object):
+
+    """Raise ResourceDenied if an exception is raised while the context manager
+    is in effect that matches the specified exception and attributes."""
+
+    def __init__(self, exc, **kwargs):
+        self.exc = exc
+        self.attrs = kwargs
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type_=None, value=None, traceback=None):
+        """If type_ is a subclass of self.exc and value has attributes matching
+        self.attrs, raise ResourceDenied.  Otherwise let the exception
+        propagate (if any)."""
+        if type_ is not None and issubclass(self.exc, type_):
+            for attr, attr_value in self.attrs.iteritems():
+                if not hasattr(value, attr):
+                    break
+                if getattr(value, attr) != attr_value:
+                    break
+            else:
+                raise ResourceDenied("an optional resource is not available")
+
 
 #=======================================================================
 # Decorator for running a function in a different locale, correctly resetting
index 0ceb078ee174c25fea5e552631009b79fb739f22..b80dd323f810bad418798176fd9284592ebcf867 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -516,6 +516,10 @@ Extension Modules
 Tests
 -----
 
+- Added test.test_support.TransientResource which is a context manager to
+  surround calls to resources that are not guaranteed to work even if
+  test.test_support.requires says that the resource should exist.
+
 - Added a test for slicing of an exception.
 
 - Added test.test_support.EnvironmentVarGuard.  It's a class that provides a