[Python-checkins] cpython (merge 3.4 -> default): Issue #24134: assertRaises(), assertRaisesRegex(), assertWarns() and

serhiy.storchaka python-checkins at python.org
Wed May 6 18:15:11 CEST 2015


https://hg.python.org/cpython/rev/679b5439b9a1
changeset:   95899:679b5439b9a1
parent:      95896:8bac00eadfda
parent:      95898:5418ab3e5556
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Wed May 06 19:14:47 2015 +0300
summary:
  Issue #24134: assertRaises(), assertRaisesRegex(), assertWarns() and
assertWarnsRegex() checks are not longer successful if the callable is None.

Added tests for assertRaises().

files:
  Lib/unittest/case.py           |  24 +++++----
  Lib/unittest/test/test_case.py |  52 ++++++++++++++++++++++
  Misc/NEWS                      |   3 +
  3 files changed, 68 insertions(+), 11 deletions(-)


diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py
--- a/Lib/unittest/case.py
+++ b/Lib/unittest/case.py
@@ -129,15 +129,17 @@
         msg = self.test_case._formatMessage(self.msg, standardMsg)
         raise self.test_case.failureException(msg)
 
+def _sentinel(*args, **kwargs):
+    raise AssertionError('Should never called')
 
 class _AssertRaisesBaseContext(_BaseTestCaseContext):
 
-    def __init__(self, expected, test_case, callable_obj=None,
+    def __init__(self, expected, test_case, callable_obj=_sentinel,
                  expected_regex=None):
         _BaseTestCaseContext.__init__(self, test_case)
         self.expected = expected
         self.test_case = test_case
-        if callable_obj is not None:
+        if callable_obj is not _sentinel:
             try:
                 self.obj_name = callable_obj.__name__
             except AttributeError:
@@ -151,11 +153,11 @@
 
     def handle(self, name, callable_obj, args, kwargs):
         """
-        If callable_obj is None, assertRaises/Warns is being used as a
+        If callable_obj is _sentinel, assertRaises/Warns is being used as a
         context manager, so check for a 'msg' kwarg and return self.
-        If callable_obj is not None, call it passing args and kwargs.
+        If callable_obj is not _sentinel, call it passing args and kwargs.
         """
-        if callable_obj is None:
+        if callable_obj is _sentinel:
             self.msg = kwargs.pop('msg', None)
             return self
         with self:
@@ -674,7 +676,7 @@
         except UnicodeDecodeError:
             return  '%s : %s' % (safe_repr(standardMsg), safe_repr(msg))
 
-    def assertRaises(self, excClass, callableObj=None, *args, **kwargs):
+    def assertRaises(self, excClass, callableObj=_sentinel, *args, **kwargs):
         """Fail unless an exception of class excClass is raised
            by callableObj when invoked with arguments args and keyword
            arguments kwargs. If a different type of exception is
@@ -682,7 +684,7 @@
            deemed to have suffered an error, exactly as for an
            unexpected exception.
 
-           If called with callableObj omitted or None, will return a
+           If called with callableObj omitted, will return a
            context object used like this::
 
                 with self.assertRaises(SomeException):
@@ -703,7 +705,7 @@
         context = _AssertRaisesContext(excClass, self, callableObj)
         return context.handle('assertRaises', callableObj, args, kwargs)
 
-    def assertWarns(self, expected_warning, callable_obj=None, *args, **kwargs):
+    def assertWarns(self, expected_warning, callable_obj=_sentinel, *args, **kwargs):
         """Fail unless a warning of class warnClass is triggered
            by callable_obj when invoked with arguments args and keyword
            arguments kwargs.  If a different type of warning is
@@ -711,7 +713,7 @@
            warning filtering rules in effect, it might be silenced, printed
            out, or raised as an exception.
 
-           If called with callable_obj omitted or None, will return a
+           If called with callable_obj omitted, will return a
            context object used like this::
 
                 with self.assertWarns(SomeWarning):
@@ -1219,7 +1221,7 @@
             self.fail(self._formatMessage(msg, standardMsg))
 
     def assertRaisesRegex(self, expected_exception, expected_regex,
-                          callable_obj=None, *args, **kwargs):
+                          callable_obj=_sentinel, *args, **kwargs):
         """Asserts that the message in a raised exception matches a regex.
 
         Args:
@@ -1238,7 +1240,7 @@
         return context.handle('assertRaisesRegex', callable_obj, args, kwargs)
 
     def assertWarnsRegex(self, expected_warning, expected_regex,
-                         callable_obj=None, *args, **kwargs):
+                         callable_obj=_sentinel, *args, **kwargs):
         """Asserts that the message in a triggered warning matches a regexp.
         Basic functioning is similar to assertWarns() with the addition
         that only warnings whose messages also match the regular expression
diff --git a/Lib/unittest/test/test_case.py b/Lib/unittest/test/test_case.py
--- a/Lib/unittest/test/test_case.py
+++ b/Lib/unittest/test/test_case.py
@@ -1132,6 +1132,50 @@
         self.assertRaises(self.failureException, self.assertRegex,
                           'saaas', r'aaaa')
 
+    def testAssertRaisesCallable(self):
+        class ExceptionMock(Exception):
+            pass
+        def Stub():
+            raise ExceptionMock('We expect')
+        self.assertRaises(ExceptionMock, Stub)
+        # A tuple of exception classes is accepted
+        self.assertRaises((ValueError, ExceptionMock), Stub)
+        # *args and **kwargs also work
+        self.assertRaises(ValueError, int, '19', base=8)
+        # Failure when no exception is raised
+        with self.assertRaises(self.failureException):
+            self.assertRaises(ExceptionMock, lambda: 0)
+        # Failure when the function is None
+        with self.assertRaises(TypeError):
+            self.assertRaises(ExceptionMock, None)
+        # Failure when another exception is raised
+        with self.assertRaises(ExceptionMock):
+            self.assertRaises(ValueError, Stub)
+
+    def testAssertRaisesContext(self):
+        class ExceptionMock(Exception):
+            pass
+        def Stub():
+            raise ExceptionMock('We expect')
+        with self.assertRaises(ExceptionMock):
+            Stub()
+        # A tuple of exception classes is accepted
+        with self.assertRaises((ValueError, ExceptionMock)) as cm:
+            Stub()
+        # The context manager exposes caught exception
+        self.assertIsInstance(cm.exception, ExceptionMock)
+        self.assertEqual(cm.exception.args[0], 'We expect')
+        # *args and **kwargs also work
+        with self.assertRaises(ValueError):
+            int('19', base=8)
+        # Failure when no exception is raised
+        with self.assertRaises(self.failureException):
+            with self.assertRaises(ExceptionMock):
+                pass
+        # Failure when another exception is raised
+        with self.assertRaises(ExceptionMock):
+            self.assertRaises(ValueError, Stub)
+
     def testAssertRaisesRegex(self):
         class ExceptionMock(Exception):
             pass
@@ -1141,6 +1185,8 @@
 
         self.assertRaisesRegex(ExceptionMock, re.compile('expect$'), Stub)
         self.assertRaisesRegex(ExceptionMock, 'expect$', Stub)
+        with self.assertRaises(TypeError):
+            self.assertRaisesRegex(ExceptionMock, 'expect$', None)
 
     def testAssertNotRaisesRegex(self):
         self.assertRaisesRegex(
@@ -1208,6 +1254,9 @@
         # Failure when no warning is triggered
         with self.assertRaises(self.failureException):
             self.assertWarns(RuntimeWarning, lambda: 0)
+        # Failure when the function is None
+        with self.assertRaises(TypeError):
+            self.assertWarns(RuntimeWarning, None)
         # Failure when another warning is triggered
         with warnings.catch_warnings():
             # Force default filter (in case tests are run with -We)
@@ -1269,6 +1318,9 @@
         with self.assertRaises(self.failureException):
             self.assertWarnsRegex(RuntimeWarning, "o+",
                                   lambda: 0)
+        # Failure when the function is None
+        with self.assertRaises(TypeError):
+            self.assertWarnsRegex(RuntimeWarning, "o+", None)
         # Failure when another warning is triggered
         with warnings.catch_warnings():
             # Force default filter (in case tests are run with -We)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -30,6 +30,9 @@
 Library
 -------
 
+- Issue #24134: assertRaises(), assertRaisesRegex(), assertWarns() and
+  assertWarnsRegex() checks are not longer successful if the callable is None.
+
 - Issue #23880: Tkinter's getint() and getdouble() now support Tcl_Obj.
   Tkinter's getdouble() now supports any numbers (in particular int).
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list