Commit e130503c authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #24134: assertRaises(), assertRaisesRegex(), assertWarns() and

assertWarnsRegex() checks are not longer successful if the callable is None.

Added tests for assertRaises().
parent ab914780
......@@ -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
......
......@@ -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.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment