mirror of
https://github.com/python/cpython.git
synced 2025-11-13 15:40:05 +00:00
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 changed files with 127 additions and 109 deletions
|
|
@ -4,7 +4,7 @@ from _testcapi import test_structmembersType, \
|
||||||
INT_MAX, INT_MIN, UINT_MAX, \
|
INT_MAX, INT_MIN, UINT_MAX, \
|
||||||
LONG_MAX, LONG_MIN, ULONG_MAX
|
LONG_MAX, LONG_MIN, ULONG_MAX
|
||||||
|
|
||||||
import warnings, exceptions, unittest, test.test_warnings
|
import warnings, exceptions, unittest
|
||||||
from test import test_support
|
from test import test_support
|
||||||
|
|
||||||
ts=test_structmembersType(1,2,3,4,5,6,7,8,9.99999,10.1010101010)
|
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
|
ts.T_ULONG=ULONG_MAX
|
||||||
self.assertEquals(ts.T_ULONG, ULONG_MAX)
|
self.assertEquals(ts.T_ULONG, ULONG_MAX)
|
||||||
|
|
||||||
class TestWarnings(test.test_warnings.CatchWarningTest):
|
class TestWarnings(unittest.TestCase):
|
||||||
def has_warned(self):
|
def has_warned(self, w):
|
||||||
self.assertEqual(test.test_warnings.msg.category,
|
self.assert_(w.category is RuntimeWarning)
|
||||||
exceptions.RuntimeWarning.__name__)
|
|
||||||
|
|
||||||
def test_byte_max(self):
|
def test_byte_max(self):
|
||||||
ts.T_BYTE=CHAR_MAX+1
|
with test_support.catch_warning() as w:
|
||||||
self.has_warned()
|
ts.T_BYTE=CHAR_MAX+1
|
||||||
|
self.has_warned(w)
|
||||||
|
|
||||||
def test_byte_min(self):
|
def test_byte_min(self):
|
||||||
ts.T_BYTE=CHAR_MIN-1
|
with test_support.catch_warning() as w:
|
||||||
self.has_warned()
|
ts.T_BYTE=CHAR_MIN-1
|
||||||
|
self.has_warned(w)
|
||||||
|
|
||||||
def test_ubyte_max(self):
|
def test_ubyte_max(self):
|
||||||
ts.T_UBYTE=UCHAR_MAX+1
|
with test_support.catch_warning() as w:
|
||||||
self.has_warned()
|
ts.T_UBYTE=UCHAR_MAX+1
|
||||||
|
self.has_warned(w)
|
||||||
|
|
||||||
def test_short_max(self):
|
def test_short_max(self):
|
||||||
ts.T_SHORT=SHRT_MAX+1
|
with test_support.catch_warning() as w:
|
||||||
self.has_warned()
|
ts.T_SHORT=SHRT_MAX+1
|
||||||
|
self.has_warned(w)
|
||||||
|
|
||||||
def test_short_min(self):
|
def test_short_min(self):
|
||||||
ts.T_SHORT=SHRT_MIN-1
|
with test_support.catch_warning() as w:
|
||||||
self.has_warned()
|
ts.T_SHORT=SHRT_MIN-1
|
||||||
|
self.has_warned(w)
|
||||||
|
|
||||||
def test_ushort_max(self):
|
def test_ushort_max(self):
|
||||||
ts.T_USHORT=USHRT_MAX+1
|
with test_support.catch_warning() as w:
|
||||||
self.has_warned()
|
ts.T_USHORT=USHRT_MAX+1
|
||||||
|
self.has_warned(w)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -282,6 +282,42 @@ def guard_warnings_filter():
|
||||||
finally:
|
finally:
|
||||||
warnings.filters = original_filters
|
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 EnvironmentVarGuard(object):
|
||||||
|
|
||||||
"""Class to help protect the environment variable properly. Can be used as
|
"""Class to help protect the environment variable properly. Can be used as
|
||||||
|
|
|
||||||
|
|
@ -5,121 +5,95 @@ from test import test_support
|
||||||
|
|
||||||
import warning_tests
|
import warning_tests
|
||||||
|
|
||||||
# The warnings module isn't easily tested, because it relies on module
|
class TestModule(unittest.TestCase):
|
||||||
# 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)
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
global msg
|
self.ignored = [w[2].__name__ for w in warnings.filters
|
||||||
msg = WarningMessage()
|
|
||||||
self._filters = warnings.filters[:]
|
|
||||||
self._showwarning = warnings.showwarning
|
|
||||||
warnings.showwarning = showwarning
|
|
||||||
self.ignored = [w[2].__name__ for w in self._filters
|
|
||||||
if w[0]=='ignore' and w[1] is None and w[3] is None]
|
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):
|
def test_warn_default_category(self):
|
||||||
for i in range(4):
|
with test_support.catch_warning() as w:
|
||||||
text = 'multi %d' %i # Different text on each call
|
for i in range(4):
|
||||||
warnings.warn(text)
|
text = 'multi %d' %i # Different text on each call
|
||||||
self.assertEqual(msg.message, text)
|
warnings.warn(text)
|
||||||
self.assertEqual(msg.category, 'UserWarning')
|
self.assertEqual(str(w.message), text)
|
||||||
|
self.assert_(w.category is UserWarning)
|
||||||
|
|
||||||
def test_warn_specific_category(self):
|
def test_warn_specific_category(self):
|
||||||
text = 'None'
|
with test_support.catch_warning() as w:
|
||||||
for category in [DeprecationWarning, FutureWarning,
|
text = 'None'
|
||||||
PendingDeprecationWarning, RuntimeWarning,
|
for category in [DeprecationWarning, FutureWarning,
|
||||||
SyntaxWarning, UserWarning, Warning]:
|
PendingDeprecationWarning, RuntimeWarning,
|
||||||
if category.__name__ in self.ignored:
|
SyntaxWarning, UserWarning, Warning]:
|
||||||
text = 'filtered out' + category.__name__
|
if category.__name__ in self.ignored:
|
||||||
warnings.warn(text, category)
|
text = 'filtered out' + category.__name__
|
||||||
self.assertNotEqual(msg.message, text)
|
warnings.warn(text, category)
|
||||||
else:
|
self.assertNotEqual(w.message, text)
|
||||||
text = 'unfiltered %s' % category.__name__
|
else:
|
||||||
warnings.warn(text, category)
|
text = 'unfiltered %s' % category.__name__
|
||||||
self.assertEqual(msg.message, text)
|
warnings.warn(text, category)
|
||||||
self.assertEqual(msg.category, category.__name__)
|
self.assertEqual(str(w.message), text)
|
||||||
|
self.assert_(w.category is category)
|
||||||
|
|
||||||
def test_filtering(self):
|
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)
|
warnings.resetwarnings()
|
||||||
self.assertRaises(UserWarning, warnings.warn, 'convert to error')
|
text = 'handle normally'
|
||||||
|
warnings.warn(text)
|
||||||
|
self.assertEqual(str(w.message), text)
|
||||||
|
self.assert_(w.category is UserWarning)
|
||||||
|
|
||||||
warnings.resetwarnings()
|
warnings.filterwarnings("ignore", "", Warning, "", 0)
|
||||||
text = 'handle normally'
|
text = 'filtered out'
|
||||||
warnings.warn(text)
|
warnings.warn(text)
|
||||||
self.assertEqual(msg.message, text)
|
self.assertNotEqual(str(w.message), text)
|
||||||
self.assertEqual(msg.category, 'UserWarning')
|
|
||||||
|
|
||||||
warnings.filterwarnings("ignore", "", Warning, "", 0)
|
warnings.resetwarnings()
|
||||||
text = 'filtered out'
|
warnings.filterwarnings("error", "hex*", Warning, "", 0)
|
||||||
warnings.warn(text)
|
self.assertRaises(UserWarning, warnings.warn, 'hex/oct')
|
||||||
self.assertNotEqual(msg.message, text)
|
text = 'nonmatching text'
|
||||||
|
warnings.warn(text)
|
||||||
warnings.resetwarnings()
|
self.assertEqual(str(w.message), text)
|
||||||
warnings.filterwarnings("error", "hex*", Warning, "", 0)
|
self.assert_(w.category is UserWarning)
|
||||||
self.assertRaises(UserWarning, warnings.warn, 'hex/oct')
|
|
||||||
text = 'nonmatching text'
|
|
||||||
warnings.warn(text)
|
|
||||||
self.assertEqual(msg.message, text)
|
|
||||||
self.assertEqual(msg.category, 'UserWarning')
|
|
||||||
|
|
||||||
def test_options(self):
|
def test_options(self):
|
||||||
# Uses the private _setoption() function to test the parsing
|
# Uses the private _setoption() function to test the parsing
|
||||||
# of command-line warning arguments
|
# of command-line warning arguments
|
||||||
self.assertRaises(warnings._OptionError,
|
with test_support.guard_warnings_filter():
|
||||||
warnings._setoption, '1:2:3:4:5:6')
|
self.assertRaises(warnings._OptionError,
|
||||||
self.assertRaises(warnings._OptionError,
|
warnings._setoption, '1:2:3:4:5:6')
|
||||||
warnings._setoption, 'bogus::Warning')
|
self.assertRaises(warnings._OptionError,
|
||||||
self.assertRaises(warnings._OptionError,
|
warnings._setoption, 'bogus::Warning')
|
||||||
warnings._setoption, 'ignore:2::4:-5')
|
self.assertRaises(warnings._OptionError,
|
||||||
warnings._setoption('error::Warning::0')
|
warnings._setoption, 'ignore:2::4:-5')
|
||||||
self.assertRaises(UserWarning, warnings.warn, 'convert to error')
|
warnings._setoption('error::Warning::0')
|
||||||
|
self.assertRaises(UserWarning, warnings.warn, 'convert to error')
|
||||||
|
|
||||||
def test_filename(self):
|
def test_filename(self):
|
||||||
warning_tests.inner("spam1")
|
with test_support.catch_warning() as w:
|
||||||
self.assertEqual(msg.filename, "warning_tests.py")
|
warning_tests.inner("spam1")
|
||||||
warning_tests.outer("spam2")
|
self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
|
||||||
self.assertEqual(msg.filename, "warning_tests.py")
|
warning_tests.outer("spam2")
|
||||||
|
self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
|
||||||
|
|
||||||
def test_stacklevel(self):
|
def test_stacklevel(self):
|
||||||
# Test stacklevel argument
|
# Test stacklevel argument
|
||||||
# make sure all messages are different, so the warning won't be skipped
|
# make sure all messages are different, so the warning won't be skipped
|
||||||
warning_tests.inner("spam3", stacklevel=1)
|
with test_support.catch_warning() as w:
|
||||||
self.assertEqual(msg.filename, "warning_tests.py")
|
warning_tests.inner("spam3", stacklevel=1)
|
||||||
warning_tests.outer("spam4", stacklevel=1)
|
self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
|
||||||
self.assertEqual(msg.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)
|
warning_tests.inner("spam5", stacklevel=2)
|
||||||
self.assertEqual(msg.filename, "test_warnings.py")
|
self.assertEqual(os.path.basename(w.filename), "test_warnings.py")
|
||||||
warning_tests.outer("spam6", stacklevel=2)
|
warning_tests.outer("spam6", stacklevel=2)
|
||||||
self.assertEqual(msg.filename, "warning_tests.py")
|
self.assertEqual(os.path.basename(w.filename), "warning_tests.py")
|
||||||
|
|
||||||
warning_tests.inner("spam7", stacklevel=9999)
|
warning_tests.inner("spam7", stacklevel=9999)
|
||||||
self.assertEqual(msg.filename, "sys")
|
self.assertEqual(os.path.basename(w.filename), "sys")
|
||||||
|
|
||||||
|
|
||||||
def test_main(verbose=None):
|
def test_main(verbose=None):
|
||||||
|
|
|
||||||
|
|
@ -713,6 +713,9 @@ Tests
|
||||||
- Fix bsddb test_basics.test06_Transactions to check the version
|
- Fix bsddb test_basics.test06_Transactions to check the version
|
||||||
number properly.
|
number properly.
|
||||||
|
|
||||||
|
- test.test_support.catch_warning is a new context manager that can be used
|
||||||
|
to catch the warnings issued by the warning framework.
|
||||||
|
|
||||||
|
|
||||||
Tools
|
Tools
|
||||||
-----
|
-----
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue