diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2015-05-06 16:13:11 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2015-05-06 16:13:11 (GMT) |
commit | e130503c7bc87023d20a353e2ab5081983a40917 (patch) | |
tree | c2dc4747a2d458de91f9a65c69929957aa2c3108 | |
parent | ab914780ba6165620e3db81d11cb631de58b655a (diff) | |
download | cpython-e130503c7bc87023d20a353e2ab5081983a40917.zip cpython-e130503c7bc87023d20a353e2ab5081983a40917.tar.gz cpython-e130503c7bc87023d20a353e2ab5081983a40917.tar.bz2 |
Issue #24134: assertRaises(), assertRaisesRegex(), assertWarns() and
assertWarnsRegex() checks are not longer successful if the callable is None.
Added tests for assertRaises().
-rw-r--r-- | Lib/unittest/case.py | 24 | ||||
-rw-r--r-- | Lib/unittest/test/test_case.py | 52 | ||||
-rw-r--r-- | Misc/NEWS | 3 |
3 files changed, 68 insertions, 11 deletions
diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index 69888a5..f99c4e5 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -129,15 +129,17 @@ class _BaseTestCaseContext: 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 @@ class _AssertRaisesBaseContext(_BaseTestCaseContext): 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 @@ class TestCase(object): 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 @@ class TestCase(object): 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 @@ class TestCase(object): 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 @@ class TestCase(object): 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 @@ class TestCase(object): 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 @@ class TestCase(object): 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 index c7ff3b0..08f2ae8 100644 --- a/Lib/unittest/test/test_case.py +++ b/Lib/unittest/test/test_case.py @@ -1134,6 +1134,50 @@ test case 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 @@ -1143,6 +1187,8 @@ test case 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( @@ -1210,6 +1256,9 @@ test case # 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) @@ -1271,6 +1320,9 @@ test case 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) @@ -42,6 +42,9 @@ Core and Builtins Library ------- +- Issue #24134: assertRaises(), assertRaisesRegex(), assertWarns() and + assertWarnsRegex() checks are not longer successful if the callable is None. + - Issue #24094: Fix possible crash in json.encode with poorly behaved dict subclasses. |