1. Prometheus Research, LLC
  2. Prometheus
  3. pbbt

Commits

Kirill Simonov  committed 5e7fa35

Added `raises()` helper function.

  • Participants
  • Parent commits 1c2be76
  • Branches default

Comments (0)

Files changed (3)

File README

View file
     Pseudo-type for ``isinstance(X, ...)``: checks if ``X`` is a
     dictionary with keys of type ``T1`` and values of type ``T2``.
 
+``pbbt.raises(E)``
+    Use with ``with`` clause to verify that the nested block raises an
+    exception of the given type.
+
+``pbbt.raises(E, fn, *args, **kwds)``
+    Verifies that the function call ``fn(*args, **kwds)`` raises an
+    exception of the given type.
+
 ``pbbt.Test(CaseType)``
     Registers the given class as a test type.
 

File src/pbbt/__init__.py

View file
 #
 
 
-from .check import maybe, oneof, choiceof, listof, tupleof, dictof
+from .check import maybe, oneof, choiceof, listof, tupleof, dictof, raises
 from .core import Test, Field, Record
 from .ctl import Control
 from .load import locate, Location

File src/pbbt/check.py

View file
                                    self.value_check.__name__)
 
 
+class ExceptionInfo(object):
+    """Information about a raised exception."""
+
+    def __init__(self):
+        self.type = None
+        self.value = None
+        self.traceback = None
+
+    def update(self, type, value, traceback):
+        self.type = type
+        self.value = value
+        self.traceback = traceback
+
+    def __nonzero__(self):
+        return (self.type is not None)
+
+    def __str__(self):
+        return "%s: %s" % (self.type.__name__, self.value)
+
+    def __repr__(self):
+        return "<%s %s>" % (self.__class__.__name__,
+                            self.type.__name__ if self.type else None)
+
+
+class ExceptionCatcher(object):
+    """Intersepts exceptions of the given type."""
+
+    def __init__(self, exc_type):
+        self.exc_type = exc_type
+        self.exc_info = ExceptionInfo()
+
+    def __enter__(self):
+        return self.exc_info
+
+    def __exit__(self, exc_type, exc_value, exc_traceback):
+        assert exc_type is not None, \
+                "expected exception %s" % self.exc_type.__name__
+        if issubclass(exc_type, self.exc_type):
+            self.exc_info.update(exc_type, exc_value, exc_traceback)
+            return True
+
+
+def raises(exc_type, callable=None, *args, **kwds):
+    """Verifies that the code produces an exception of the given type."""
+    if callable is not None:
+        with raises(exc_type) as exc_info:
+            callable(*args, **kwds)
+        return exc_info
+    else:
+        return ExceptionCatcher(exc_type)
+
+