Implement a contextmanager test.test_support.catch_warning that can
be used to catch the last warning issued by the warning framework. Change test_warnings.py and test_structmembers.py to use this new contextmanager.
This commit is contained in:
parent
c4a106733c
commit
e6dae6c655
|
@ -4,7 +4,7 @@ from _testcapi import test_structmembersType, \
|
|||
INT_MAX, INT_MIN, UINT_MAX, \
|
||||
LONG_MAX, LONG_MIN, ULONG_MAX
|
||||
|
||||
import warnings, exceptions, unittest, test.test_warnings
|
||||
import warnings, exceptions, unittest
|
||||
from test import test_support
|
||||
|
||||
ts=test_structmembersType(1,2,3,4,5,6,7,8,9.99999,10.1010101010)
|
||||
|
@ -39,34 +39,39 @@ class ReadWriteTests(unittest.TestCase):
|
|||
ts.T_ULONG=ULONG_MAX
|
||||
self.assertEquals(ts.T_ULONG, ULONG_MAX)
|
||||
|
||||
class TestWarnings(test.test_warnings.CatchWarningTest):
|
||||
def has_warned(self):
|
||||
self.assertEqual(test.test_warnings.msg.category,
|
||||
exceptions.RuntimeWarning.__name__)
|
||||
class TestWarnings(unittest.TestCase):
|
||||
def has_warned(self, w):
|
||||
self.assert_(w.category is RuntimeWarning)
|
||||
|
||||
def test_byte_max(self):
|
||||
ts.T_BYTE=CHAR_MAX+1
|
||||
self.has_warned()
|
||||
with test_support.catch_warning() as w:
|
||||
ts.T_BYTE=CHAR_MAX+1
|
||||
self.has_warned(w)
|
||||
|
||||
def test_byte_min(self):
|
||||
ts.T_BYTE=CHAR_MIN-1
|
||||
self.has_warned()
|
||||
with test_support.catch_warning() as w:
|
||||
ts.T_BYTE=CHAR_MIN-1
|
||||
self.has_warned(w)
|
||||
|
||||
def test_ubyte_max(self):
|
||||
ts.T_UBYTE=UCHAR_MAX+1
|
||||
self.has_warned()
|
||||
with test_support.catch_warning() as w:
|
||||
ts.T_UBYTE=UCHAR_MAX+1
|
||||
self.has_warned(w)
|
||||
|
||||
def test_short_max(self):
|
||||
ts.T_SHORT=SHRT_MAX+1
|
||||
self.has_warned()
|
||||
with test_support.catch_warning() as w:
|
||||
ts.T_SHORT=SHRT_MAX+1
|
||||
self.has_warned(w)
|
||||
|
||||
def test_short_min(self):
|
||||
ts.T_SHORT=SHRT_MIN-1
|
||||
self.has_warned()
|
||||
with test_support.catch_warning() as w:
|
||||
ts.T_SHORT=SHRT_MIN-1
|
||||
self.has_warned(w)
|
||||
|
||||
def test_ushort_max(self):
|
||||
ts.T_USHORT=USHRT_MAX+1
|
||||
self.has_warned()
|
||||
with test_support.catch_warning() as w:
|
||||
ts.T_USHORT=USHRT_MAX+1
|
||||
self.has_warned(w)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -282,6 +282,42 @@ def guard_warnings_filter():
|
|||
finally:
|
||||
warnings.filters = original_filters
|
||||
|
||||
class WarningMessage(object):
|
||||
"Holds the result of the latest showwarning() call"
|
||||
def __init__(self):
|
||||
self.message = None
|
||||
self.category = None
|
||||
self.filename = None
|
||||
self.lineno = None
|
||||
|
||||
def _showwarning(self, message, category, filename, lineno, file=None):
|
||||
self.message = message
|
||||
self.category = category
|
||||
self.filename = filename
|
||||
self.lineno = lineno
|
||||
|
||||
@contextlib.contextmanager
|
||||
def catch_warning():
|
||||
"""
|
||||
Guard the warnings filter from being permanently changed and record the
|
||||
data of the last warning that has been issued.
|
||||
|
||||
Use like this:
|
||||
|
||||
with catch_warning as w:
|
||||
warnings.warn("foo")
|
||||
assert str(w.message) == "foo"
|
||||
"""
|
||||
warning = WarningMessage()
|
||||
original_filters = warnings.filters[:]
|
||||
original_showwarning = warnings.showwarning
|
||||
warnings.showwarning = warning._showwarning
|
||||
try:
|
||||
yield warning
|
||||
finally:
|
||||
warnings.showwarning = original_showwarning
|
||||
warnings.filters = original_filters
|
||||
|
||||
class EnvironmentVarGuard(object):
|
||||
|
||||
"""Class to help protect the environment variable properly. Can be used as
|
||||
|
|
|
@ -5,121 +5,95 @@ from test import test_support
|
|||
|
||||
import warning_tests
|
||||
|
||||
# The warnings module isn't easily tested, because it relies on module
|
||||
# globals to store configuration information. setUp() and tearDown()
|
||||
# preserve the current settings to avoid bashing them while running tests.
|
||||
|
||||
# To capture the warning messages, a replacement for showwarning() is
|
||||
# used to save warning information in a global variable.
|
||||
|
||||
class WarningMessage:
|
||||
"Holds results of latest showwarning() call"
|
||||
pass
|
||||
|
||||
def showwarning(message, category, filename, lineno, file=None):
|
||||
msg.message = str(message)
|
||||
msg.category = category.__name__
|
||||
msg.filename = os.path.basename(filename)
|
||||
msg.lineno = lineno
|
||||
|
||||
class CatchWarningTest(unittest.TestCase):
|
||||
# base class used for catching warnings issued by the
|
||||
# warning framework (this is reused by test_structmembers.py)
|
||||
|
||||
class TestModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
global msg
|
||||
msg = WarningMessage()
|
||||
self._filters = warnings.filters[:]
|
||||
self._showwarning = warnings.showwarning
|
||||
warnings.showwarning = showwarning
|
||||
self.ignored = [w[2].__name__ for w in self._filters
|
||||
self.ignored = [w[2].__name__ for w in warnings.filters
|
||||
if w[0]=='ignore' and w[1] is None and w[3] is None]
|
||||
|
||||
def tearDown(self):
|
||||
warnings.filters = self._filters[:]
|
||||
warnings.showwarning = self._showwarning
|
||||
|
||||
class TestModule(CatchWarningTest):
|
||||
|
||||
def test_warn_default_category(self):
|
||||
for i in range(4):
|
||||
text = 'multi %d' %i # Different text on each call
|
||||
warnings.warn(text)
|
||||
self.assertEqual(msg.message, text)
|
||||
self.assertEqual(msg.category, 'UserWarning')
|
||||
with test_support.catch_warning() as w:
|
||||
for i in range(4):
|
||||
text = 'multi %d' %i # Different text on each call
|
||||
warnings.warn(text)
|
||||
self.assertEqual(str(w.message), text)
|
||||
self.assert_(w.category is UserWarning)
|
||||
|
||||
def test_warn_specific_category(self):
|
||||
text = 'None'
|
||||
for category in [DeprecationWarning, FutureWarning,
|
||||
PendingDeprecationWarning, RuntimeWarning,
|
||||
SyntaxWarning, UserWarning, Warning]:
|
||||
if category.__name__ in self.ignored:
|
||||
text = 'filtered out' + category.__name__
|
||||
warnings.warn(text, category)
|
||||
self.assertNotEqual(msg.message, text)
|
||||
else:
|
||||
text = 'unfiltered %s' % category.__name__
|
||||
warnings.warn(text, category)
|
||||
self.assertEqual(msg.message, text)
|
||||
self.assertEqual(msg.category, category.__name__)
|
||||
with test_support.catch_warning() as w:
|
||||
text = 'None'
|
||||
for category in [DeprecationWarning, FutureWarning,
|
||||
PendingDeprecationWarning, RuntimeWarning,
|
||||
SyntaxWarning, UserWarning, Warning]:
|
||||
if category.__name__ in self.ignored:
|
||||
text = 'filtered out' + category.__name__
|
||||
warnings.warn(text, category)
|
||||
self.assertNotEqual(w.message, text)
|
||||
else:
|
||||
text = 'unfiltered %s' % category.__name__
|
||||
warnings.warn(text, category)
|
||||
self.assertEqual(str(w.message), text)
|
||||
self.assert_(w.category is category)
|
||||
|
||||
def test_filtering(self):
|
||||
with test_support.catch_warning() as w:
|
||||
warnings.filterwarnings("error", "", Warning, "", 0)
|
||||
self.assertRaises(UserWarning, warnings.warn, 'convert to error')
|
||||
|
||||
warnings.filterwarnings("error", "", Warning, "", 0)
|
||||
self.assertRaises(UserWarning, warnings.warn, 'convert to error')
|
||||
warnings.resetwarnings()
|
||||
text = 'handle normally'
|
||||
warnings.warn(text)
|
||||
self.assertEqual(str(w.message), text)
|
||||
self.assert_(w.category is UserWarning)
|
||||
|
||||
warnings.resetwarnings()
|
||||
text = 'handle normally'
|
||||
warnings.warn(text)
|
||||
self.assertEqual(msg.message, text)
|
||||
self.assertEqual(msg.category, 'UserWarning')
|
||||
warnings.filterwarnings("ignore", "", Warning, "", 0)
|
||||
text = 'filtered out'
|
||||
warnings.warn(text)
|
||||
self.assertNotEqual(str(w.message), text)
|
||||
|
||||
warnings.filterwarnings("ignore", "", Warning, "", 0)
|
||||
text = 'filtered out'
|
||||
warnings.warn(text)
|
||||
self.assertNotEqual(msg.message, text)
|
||||
|
||||
warnings.resetwarnings()
|
||||
warnings.filterwarnings("error", "hex*", Warning, "", 0)
|
||||
self.assertRaises(UserWarning, warnings.warn, 'hex/oct')
|
||||
text = 'nonmatching text'
|
||||
warnings.warn(text)
|
||||
self.assertEqual(msg.message, text)
|
||||
self.assertEqual(msg.category, 'UserWarning')
|
||||
warnings.resetwarnings()
|
||||
warnings.filterwarnings("error", "hex*", Warning, "", 0)
|
||||
self.assertRaises(UserWarning, warnings.warn, 'hex/oct')
|
||||
text = 'nonmatching text'
|
||||
warnings.warn(text)
|
||||
self.assertEqual(str(w.message), text)
|
||||
self.assert_(w.category is UserWarning)
|
||||
|
||||
def test_options(self):
|
||||
# Uses the private _setoption() function to test the parsing
|
||||
# of command-line warning arguments
|
||||
self.assertRaises(warnings._OptionError,
|
||||
warnings._setoption, '1:2:3:4:5:6')
|
||||
self.assertRaises(warnings._OptionError,
|
||||
warnings._setoption, 'bogus::Warning')
|
||||
self.assertRaises(warnings._OptionError,
|
||||
warnings._setoption, 'ignore:2::4:-5')
|
||||
warnings._setoption('error::Warning::0')
|
||||
self.assertRaises(UserWarning, warnings.warn, 'convert to error')
|
||||
with test_support.guard_warnings_filter():
|
||||
self.assertRaises(warnings._OptionError,
|
||||
warnings._setoption, '1:2:3:4:5:6')
|
||||
self.assertRaises(warnings._OptionError,
|
||||
warnings._setoption, 'bogus::Warning')
|
||||
self.assertRaises(warnings._OptionError,
|
||||
warnings._setoption, 'ignore:2::4:-5')
|
||||
warnings._setoption('error::Warning::0')
|
||||
self.assertRaises(UserWarning, warnings.warn, 'convert to error')
|
||||
|
||||
def test_filename(self):
|
||||
warning_tests.inner("spam1")
|
||||
self.assertEqual(msg.filename, "warning_tests.py")
|
||||
warning_tests.outer("spam2")
|
||||
self.assertEqual(msg.filename, "warning_tests.py")
|
||||
with test_support.catch_warning() as w:
|
||||
warning_tests.inner("spam1")
|
||||
self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
|
||||
warning_tests.outer("spam2")
|
||||
self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
|
||||
|
||||
def test_stacklevel(self):
|
||||
# Test stacklevel argument
|
||||
# make sure all messages are different, so the warning won't be skipped
|
||||
warning_tests.inner("spam3", stacklevel=1)
|
||||
self.assertEqual(msg.filename, "warning_tests.py")
|
||||
warning_tests.outer("spam4", stacklevel=1)
|
||||
self.assertEqual(msg.filename, "warning_tests.py")
|
||||
with test_support.catch_warning() as w:
|
||||
warning_tests.inner("spam3", stacklevel=1)
|
||||
self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
|
||||
warning_tests.outer("spam4", stacklevel=1)
|
||||
self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
|
||||
|
||||
warning_tests.inner("spam5", stacklevel=2)
|
||||
self.assertEqual(msg.filename, "test_warnings.py")
|
||||
warning_tests.outer("spam6", stacklevel=2)
|
||||
self.assertEqual(msg.filename, "warning_tests.py")
|
||||
warning_tests.inner("spam5", stacklevel=2)
|
||||
self.assertEqual(os.path.basename(w.filename), "test_warnings.py")
|
||||
warning_tests.outer("spam6", stacklevel=2)
|
||||
self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
|
||||
|
||||
warning_tests.inner("spam7", stacklevel=9999)
|
||||
self.assertEqual(msg.filename, "sys")
|
||||
warning_tests.inner("spam7", stacklevel=9999)
|
||||
self.assertEqual(os.path.basename(w.filename), "sys")
|
||||
|
||||
|
||||
def test_main(verbose=None):
|
||||
|
|
Loading…
Reference in New Issue