mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	Issue #7849: Now the utility `check_warnings` verifies if the warnings are
				
					
				
			effectively raised. A new utility ``check_py3k_warnings`` deals with py3k warnings.
This commit is contained in:
		
							parent
							
								
									1f3b4e12e8
								
							
						
					
					
						commit
						6de9e938a5
					
				
					 8 changed files with 102 additions and 27 deletions
				
			
		| 
						 | 
					@ -715,8 +715,7 @@ def test_replace(self):
 | 
				
			||||||
        EQ("bobobXbobob", "bobobobXbobobob", "replace", "bobob", "bob")
 | 
					        EQ("bobobXbobob", "bobobobXbobobob", "replace", "bobob", "bob")
 | 
				
			||||||
        EQ("BOBOBOB", "BOBOBOB", "replace", "bob", "bobby")
 | 
					        EQ("BOBOBOB", "BOBOBOB", "replace", "bob", "bobby")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Silence Py3k warning
 | 
					        with test_support.check_py3k_warnings():
 | 
				
			||||||
        with test_support.check_warnings():
 | 
					 | 
				
			||||||
            ba = buffer('a')
 | 
					            ba = buffer('a')
 | 
				
			||||||
            bb = buffer('b')
 | 
					            bb = buffer('b')
 | 
				
			||||||
        EQ("bbc", "abc", "replace", ba, bb)
 | 
					        EQ("bbc", "abc", "replace", ba, bb)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,14 +17,11 @@ def testFormatDeprecation(self):
 | 
				
			||||||
        PyOS_ascii_formatd = pythonapi.PyOS_ascii_formatd
 | 
					        PyOS_ascii_formatd = pythonapi.PyOS_ascii_formatd
 | 
				
			||||||
        buf = create_string_buffer(' ' * 100)
 | 
					        buf = create_string_buffer(' ' * 100)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        with check_warnings() as w:
 | 
					        with check_warnings():
 | 
				
			||||||
            warnings.simplefilter('default')
 | 
					 | 
				
			||||||
            PyOS_ascii_formatd(byref(buf), sizeof(buf), '%+.10f',
 | 
					            PyOS_ascii_formatd(byref(buf), sizeof(buf), '%+.10f',
 | 
				
			||||||
                               c_double(10.0))
 | 
					                               c_double(10.0))
 | 
				
			||||||
            self.assertEqual(buf.value, '+10.0000000000')
 | 
					            self.assertEqual(buf.value, '+10.0000000000')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(w.category, DeprecationWarning)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class FormatTests(unittest.TestCase):
 | 
					class FormatTests(unittest.TestCase):
 | 
				
			||||||
    # ensure that, for the restricted set of format codes,
 | 
					    # ensure that, for the restricted set of format codes,
 | 
				
			||||||
    # %-formatting returns the same values os PyOS_ascii_formatd
 | 
					    # %-formatting returns the same values os PyOS_ascii_formatd
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -390,7 +390,7 @@ def testInvalidInit(self):
 | 
				
			||||||
        self.assertRaises(TypeError, _FileIO, "1", 0, 0)
 | 
					        self.assertRaises(TypeError, _FileIO, "1", 0, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def testWarnings(self):
 | 
					    def testWarnings(self):
 | 
				
			||||||
        with check_warnings() as w:
 | 
					        with check_warnings(quiet=True) as w:
 | 
				
			||||||
            self.assertEqual(w.warnings, [])
 | 
					            self.assertEqual(w.warnings, [])
 | 
				
			||||||
            self.assertRaises(TypeError, _FileIO, [])
 | 
					            self.assertRaises(TypeError, _FileIO, [])
 | 
				
			||||||
            self.assertEqual(w.warnings, [])
 | 
					            self.assertEqual(w.warnings, [])
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -279,16 +279,14 @@ def __getslice__(self, i, j):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_getitem(self):
 | 
					    def test_getitem(self):
 | 
				
			||||||
        self._getitem_helper(object)
 | 
					        self._getitem_helper(object)
 | 
				
			||||||
        # Silence Py3k warning
 | 
					        with test_support.check_py3k_warnings():
 | 
				
			||||||
        with test_support.check_warnings():
 | 
					 | 
				
			||||||
            self._getslice_helper_deprecated(object)
 | 
					            self._getslice_helper_deprecated(object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_getitem_classic(self):
 | 
					    def test_getitem_classic(self):
 | 
				
			||||||
        class Empty: pass
 | 
					        class Empty: pass
 | 
				
			||||||
        # XXX This test fails (see bug #7532)
 | 
					        # XXX This test fails (see bug #7532)
 | 
				
			||||||
        #self._getitem_helper(Empty)
 | 
					        #self._getitem_helper(Empty)
 | 
				
			||||||
        # Silence Py3k warning
 | 
					        with test_support.check_py3k_warnings():
 | 
				
			||||||
        with test_support.check_warnings():
 | 
					 | 
				
			||||||
            self._getslice_helper_deprecated(Empty)
 | 
					            self._getslice_helper_deprecated(Empty)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_sequence_repeat(self):
 | 
					    def test_sequence_repeat(self):
 | 
				
			||||||
| 
						 | 
					@ -308,8 +306,7 @@ def test_main():
 | 
				
			||||||
        XRangeTestCase,
 | 
					        XRangeTestCase,
 | 
				
			||||||
        OverflowTestCase,
 | 
					        OverflowTestCase,
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    # Silence Py3k warning
 | 
					    with test_support.check_py3k_warnings():
 | 
				
			||||||
    with test_support.check_warnings():
 | 
					 | 
				
			||||||
        test_support.run_unittest(
 | 
					        test_support.run_unittest(
 | 
				
			||||||
            ClassicSeqDeprecatedTestCase,
 | 
					            ClassicSeqDeprecatedTestCase,
 | 
				
			||||||
            NewSeqDeprecatedTestCase,
 | 
					            NewSeqDeprecatedTestCase,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,8 +53,7 @@ def test_jumpahead(self):
 | 
				
			||||||
        state3 = self.gen.getstate()    # s/b distinct from state2
 | 
					        state3 = self.gen.getstate()    # s/b distinct from state2
 | 
				
			||||||
        self.assertNotEqual(state2, state3)
 | 
					        self.assertNotEqual(state2, state3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Silence py3k warnings
 | 
					        with test_support.check_py3k_warnings(quiet=True):
 | 
				
			||||||
        with test_support.check_warnings():
 | 
					 | 
				
			||||||
            self.assertRaises(TypeError, self.gen.jumpahead)  # needs an arg
 | 
					            self.assertRaises(TypeError, self.gen.jumpahead)  # needs an arg
 | 
				
			||||||
            self.assertRaises(TypeError, self.gen.jumpahead, "ick")  # wrong type
 | 
					            self.assertRaises(TypeError, self.gen.jumpahead, "ick")  # wrong type
 | 
				
			||||||
            self.assertRaises(TypeError, self.gen.jumpahead, 2.3)  # wrong type
 | 
					            self.assertRaises(TypeError, self.gen.jumpahead, 2.3)  # wrong type
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,7 @@
 | 
				
			||||||
import unittest
 | 
					import unittest
 | 
				
			||||||
import importlib
 | 
					import importlib
 | 
				
			||||||
import UserDict
 | 
					import UserDict
 | 
				
			||||||
 | 
					import re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__all__ = ["Error", "TestFailed", "ResourceDenied", "import_module",
 | 
					__all__ = ["Error", "TestFailed", "ResourceDenied", "import_module",
 | 
				
			||||||
           "verbose", "use_resources", "max_memuse", "record_original_stdout",
 | 
					           "verbose", "use_resources", "max_memuse", "record_original_stdout",
 | 
				
			||||||
| 
						 | 
					@ -23,8 +24,8 @@
 | 
				
			||||||
           "is_resource_enabled", "requires", "find_unused_port", "bind_port",
 | 
					           "is_resource_enabled", "requires", "find_unused_port", "bind_port",
 | 
				
			||||||
           "fcmp", "have_unicode", "is_jython", "TESTFN", "HOST", "FUZZ",
 | 
					           "fcmp", "have_unicode", "is_jython", "TESTFN", "HOST", "FUZZ",
 | 
				
			||||||
           "SAVEDCWD", "temp_cwd", "findfile", "sortdict", "check_syntax_error",
 | 
					           "SAVEDCWD", "temp_cwd", "findfile", "sortdict", "check_syntax_error",
 | 
				
			||||||
           "open_urlresource", "check_warnings", "CleanImport",
 | 
					           "open_urlresource", "check_warnings", "check_py3k_warnings",
 | 
				
			||||||
           "EnvironmentVarGuard", "captured_output",
 | 
					           "CleanImport", "EnvironmentVarGuard", "captured_output",
 | 
				
			||||||
           "captured_stdout", "TransientResource", "transient_internet",
 | 
					           "captured_stdout", "TransientResource", "transient_internet",
 | 
				
			||||||
           "run_with_locale", "set_memlimit", "bigmemtest", "bigaddrspacetest",
 | 
					           "run_with_locale", "set_memlimit", "bigmemtest", "bigaddrspacetest",
 | 
				
			||||||
           "BasicTestRunner", "run_unittest", "run_doctest", "threading_setup",
 | 
					           "BasicTestRunner", "run_unittest", "run_doctest", "threading_setup",
 | 
				
			||||||
| 
						 | 
					@ -488,22 +489,103 @@ class WarningsRecorder(object):
 | 
				
			||||||
       entry to the warnings.catch_warnings() context manager.
 | 
					       entry to the warnings.catch_warnings() context manager.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    def __init__(self, warnings_list):
 | 
					    def __init__(self, warnings_list):
 | 
				
			||||||
        self.warnings = warnings_list
 | 
					        self._warnings = warnings_list
 | 
				
			||||||
 | 
					        self._last = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __getattr__(self, attr):
 | 
					    def __getattr__(self, attr):
 | 
				
			||||||
        if self.warnings:
 | 
					        if len(self._warnings) > self._last:
 | 
				
			||||||
            return getattr(self.warnings[-1], attr)
 | 
					            return getattr(self._warnings[-1], attr)
 | 
				
			||||||
        elif attr in warnings.WarningMessage._WARNING_DETAILS:
 | 
					        elif attr in warnings.WarningMessage._WARNING_DETAILS:
 | 
				
			||||||
            return None
 | 
					            return None
 | 
				
			||||||
        raise AttributeError("%r has no attribute %r" % (self, attr))
 | 
					        raise AttributeError("%r has no attribute %r" % (self, attr))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def warnings(self):
 | 
				
			||||||
 | 
					        return self._warnings[self._last:]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def reset(self):
 | 
					    def reset(self):
 | 
				
			||||||
        del self.warnings[:]
 | 
					        self._last = len(self._warnings)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _filterwarnings(filters, quiet=False):
 | 
				
			||||||
 | 
					    """Catch the warnings, then check if all the expected
 | 
				
			||||||
 | 
					    warnings have been raised and re-raise unexpected warnings.
 | 
				
			||||||
 | 
					    If 'quiet' is True, only re-raise the unexpected warnings.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    # Clear the warning registry of the calling module
 | 
				
			||||||
 | 
					    # in order to re-raise the warnings.
 | 
				
			||||||
 | 
					    frame = sys._getframe(2)
 | 
				
			||||||
 | 
					    registry = frame.f_globals.get('__warningregistry__')
 | 
				
			||||||
 | 
					    if registry:
 | 
				
			||||||
 | 
					        registry.clear()
 | 
				
			||||||
 | 
					    with warnings.catch_warnings(record=True) as w:
 | 
				
			||||||
 | 
					        # Disable filters, to record all warnings.  Because
 | 
				
			||||||
 | 
					        # test_warnings swap the module, we need to look up
 | 
				
			||||||
 | 
					        # in the sys.modules dictionary.
 | 
				
			||||||
 | 
					        sys.modules['warnings'].resetwarnings()
 | 
				
			||||||
 | 
					        yield WarningsRecorder(w)
 | 
				
			||||||
 | 
					    # Filter the recorded warnings
 | 
				
			||||||
 | 
					    reraise = [warning.message for warning in w]
 | 
				
			||||||
 | 
					    missing = []
 | 
				
			||||||
 | 
					    for msg, cat in filters:
 | 
				
			||||||
 | 
					        seen = False
 | 
				
			||||||
 | 
					        for exc in reraise[:]:
 | 
				
			||||||
 | 
					            message = str(exc)
 | 
				
			||||||
 | 
					            # Filter out the matching messages
 | 
				
			||||||
 | 
					            if (re.match(msg, message, re.I) and
 | 
				
			||||||
 | 
					                issubclass(exc.__class__, cat)):
 | 
				
			||||||
 | 
					                seen = True
 | 
				
			||||||
 | 
					                reraise.remove(exc)
 | 
				
			||||||
 | 
					        if not seen and not quiet:
 | 
				
			||||||
 | 
					            # This filter caught nothing
 | 
				
			||||||
 | 
					            missing.append((msg, cat.__name__))
 | 
				
			||||||
 | 
					    for exc in reraise:
 | 
				
			||||||
 | 
					        raise AssertionError("unhandled warning %r" % exc)
 | 
				
			||||||
 | 
					    for filter in missing:
 | 
				
			||||||
 | 
					        raise AssertionError("filter (%r, %s) did not caught any warning" %
 | 
				
			||||||
 | 
					                             filter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@contextlib.contextmanager
 | 
					@contextlib.contextmanager
 | 
				
			||||||
def check_warnings():
 | 
					def check_warnings(*filters, **kwargs):
 | 
				
			||||||
    with warnings.catch_warnings(record=True) as w:
 | 
					    """Context manager to silence warnings.
 | 
				
			||||||
        yield WarningsRecorder(w)
 | 
					
 | 
				
			||||||
 | 
					    Accept 2-tuples as positional arguments:
 | 
				
			||||||
 | 
					        ("message regexp", WarningCategory)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Optional argument:
 | 
				
			||||||
 | 
					     - if 'quiet' is True, it does not fail if a filter catches nothing
 | 
				
			||||||
 | 
					        (default False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Without argument, it defaults to:
 | 
				
			||||||
 | 
					        check_warnings(("", Warning), quiet=False)
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    if not filters:
 | 
				
			||||||
 | 
					        filters = (("", Warning),)
 | 
				
			||||||
 | 
					    return _filterwarnings(filters, kwargs.get('quiet'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@contextlib.contextmanager
 | 
				
			||||||
 | 
					def check_py3k_warnings(*filters, **kwargs):
 | 
				
			||||||
 | 
					    """Context manager to silence py3k warnings.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Accept 2-tuples as positional arguments:
 | 
				
			||||||
 | 
					        ("message regexp", WarningCategory)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Optional argument:
 | 
				
			||||||
 | 
					     - if 'quiet' is True, it does not fail if a filter catches nothing
 | 
				
			||||||
 | 
					        (default False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Without argument, it defaults to:
 | 
				
			||||||
 | 
					        check_py3k_warnings(("", DeprecationWarning), quiet=False)
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    if sys.py3kwarning:
 | 
				
			||||||
 | 
					        if not filters:
 | 
				
			||||||
 | 
					            filters = (("", DeprecationWarning),)
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        # It should not raise any py3k warning
 | 
				
			||||||
 | 
					        filters = ()
 | 
				
			||||||
 | 
					    return _filterwarnings(filters, kwargs.get('quiet'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CleanImport(object):
 | 
					class CleanImport(object):
 | 
				
			||||||
| 
						 | 
					@ -735,7 +817,6 @@ def inner(*args, **kwds):
 | 
				
			||||||
MAX_Py_ssize_t = sys.maxsize
 | 
					MAX_Py_ssize_t = sys.maxsize
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def set_memlimit(limit):
 | 
					def set_memlimit(limit):
 | 
				
			||||||
    import re
 | 
					 | 
				
			||||||
    global max_memuse
 | 
					    global max_memuse
 | 
				
			||||||
    global real_max_memuse
 | 
					    global real_max_memuse
 | 
				
			||||||
    sizes = {
 | 
					    sizes = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -512,8 +512,7 @@ def __str__(self):
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not sys.platform.startswith('java'):
 | 
					        if not sys.platform.startswith('java'):
 | 
				
			||||||
            # Silence Py3k warning
 | 
					            with test_support.check_py3k_warnings():
 | 
				
			||||||
            with test_support.check_warnings():
 | 
					 | 
				
			||||||
                buf = buffer('character buffers are decoded to unicode')
 | 
					                buf = buffer('character buffers are decoded to unicode')
 | 
				
			||||||
            self.assertEqual(
 | 
					            self.assertEqual(
 | 
				
			||||||
                unicode(
 | 
					                unicode(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -138,6 +138,9 @@ Extension Modules
 | 
				
			||||||
Tests
 | 
					Tests
 | 
				
			||||||
-----
 | 
					-----
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Issue #7849: Now the utility ``check_warnings`` verifies if the warnings are
 | 
				
			||||||
 | 
					  effectively raised.  A new utility ``check_py3k_warnings`` is available.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- The four path modules (genericpath, macpath, ntpath, posixpath) share a
 | 
					- The four path modules (genericpath, macpath, ntpath, posixpath) share a
 | 
				
			||||||
  common TestCase for some tests: test_genericpath.CommonTest.
 | 
					  common TestCase for some tests: test_genericpath.CommonTest.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue