[Python-checkins] cpython (merge 3.6 -> default): Merge 3.6

victor.stinner python-checkins at python.org
Tue Dec 6 05:00:37 EST 2016


https://hg.python.org/cpython/rev/2bd1717b6e00
changeset:   105475:2bd1717b6e00
parent:      105473:e526780303bc
parent:      105474:726308cfe3b5
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Tue Dec 06 10:59:54 2016 +0100
summary:
  Merge 3.6

files:
  Lib/test/test_warnings/__init__.py |  45 ++++++++++++++++++
  Lib/warnings.py                    |  14 ++++-
  Misc/NEWS                          |   3 +
  3 files changed, 60 insertions(+), 2 deletions(-)


diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py
--- a/Lib/test/test_warnings/__init__.py
+++ b/Lib/test/test_warnings/__init__.py
@@ -944,6 +944,51 @@
                 self.assertTrue(wmod.filters is not orig_filters)
             self.assertTrue(wmod.filters is orig_filters)
 
+    def test_record_override_showwarning_before(self):
+        # Issue #28089: If warnings.showwarning() was overriden, make sure
+        # that catch_warnings(record=True) overrides it again.
+        text = "This is a warning"
+        wmod = self.module
+        my_log = []
+
+        def my_logger(message, category, filename, lineno, file=None, line=None):
+            nonlocal my_log
+            my_log.append(message)
+
+        # Override warnings.showwarning() before calling catch_warnings()
+        with support.swap_attr(wmod, 'showwarning', my_logger):
+            with wmod.catch_warnings(module=wmod, record=True) as log:
+                self.assertIsNot(wmod.showwarning, my_logger)
+
+                wmod.simplefilter("always")
+                wmod.warn(text)
+
+            self.assertIs(wmod.showwarning, my_logger)
+
+        self.assertEqual(len(log), 1, log)
+        self.assertEqual(log[0].message.args[0], text)
+        self.assertEqual(my_log, [])
+
+    def test_record_override_showwarning_inside(self):
+        # Issue #28089: It is possible to override warnings.showwarning()
+        # in the catch_warnings(record=True) context manager.
+        text = "This is a warning"
+        wmod = self.module
+        my_log = []
+
+        def my_logger(message, category, filename, lineno, file=None, line=None):
+            nonlocal my_log
+            my_log.append(message)
+
+        with wmod.catch_warnings(module=wmod, record=True) as log:
+            wmod.simplefilter("always")
+            wmod.showwarning = my_logger
+            wmod.warn(text)
+
+        self.assertEqual(len(my_log), 1, my_log)
+        self.assertEqual(my_log[0].args[0], text)
+        self.assertEqual(log, [])
+
     def test_check_warnings(self):
         # Explicit tests for the test.support convenience wrapper
         wmod = self.module
diff --git a/Lib/warnings.py b/Lib/warnings.py
--- a/Lib/warnings.py
+++ b/Lib/warnings.py
@@ -447,11 +447,20 @@
         self._module._filters_mutated()
         self._showwarning = self._module.showwarning
         self._showwarnmsg = self._module._showwarnmsg
+        self._showwarnmsg_impl = self._module._showwarnmsg_impl
         if self._record:
             log = []
-            def showarnmsg(msg):
+
+            def showarnmsg_logger(msg):
+                nonlocal log
                 log.append(msg)
-            self._module._showwarnmsg = showarnmsg
+
+            self._module._showwarnmsg_impl = showarnmsg_logger
+
+            # Reset showwarning() to the default implementation to make sure
+            # that _showwarnmsg() calls _showwarnmsg_impl()
+            self._module.showwarning = self._module._showwarning
+
             return log
         else:
             return None
@@ -463,6 +472,7 @@
         self._module._filters_mutated()
         self._module.showwarning = self._showwarning
         self._module._showwarnmsg = self._showwarnmsg
+        self._module._showwarnmsg_impl = self._showwarnmsg_impl
 
 
 # filters contains a sequence of filter 5-tuples
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -165,6 +165,9 @@
 Library
 -------
 
+- Issue #28089: Fix a regression introduced in warnings.catch_warnings():
+  call warnings.showwarning() if it was overriden inside the context manager.
+
 - Issue #27172: To assist with upgrades from 2.7, the previously documented
   deprecation of ``inspect.getfullargspec()`` has been reversed. This decision
   may be revisited again after the Python 2.7 branch is no longer officially

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list