]> granicus.if.org Git - python/commitdiff
warnings.formatwarning(): catch exceptions
authorVictor Stinner <victor.stinner@gmail.com>
Thu, 24 Mar 2016 23:30:32 +0000 (00:30 +0100)
committerVictor Stinner <victor.stinner@gmail.com>
Thu, 24 Mar 2016 23:30:32 +0000 (00:30 +0100)
Issue #21925: warnings.formatwarning() now catches exceptions on
linecache.getline(...) to be able to log ResourceWarning emitted late during
the Python shutdown process.

Lib/test/test_warnings/__init__.py
Lib/warnings.py
Misc/NEWS

index eda755dbc2156ec4d521282a03e4e4e214ea9650..633b2ac9f6130a87572ba56ecfe013801db06d3b 100644 (file)
@@ -953,6 +953,23 @@ a=A()
         # of the script
         self.assertEqual(err, b'__main__:7: UserWarning: test')
 
+    def test_late_resource_warning(self):
+        # Issue #21925: Emitting a ResourceWarning late during the Python
+        # shutdown must be logged.
+
+        expected = b"sys:1: ResourceWarning: unclosed file "
+
+        # don't import the warnings module
+        # (_warnings will try to import it)
+        code = "f = open(%a)" % __file__
+        rc, out, err = assert_python_ok("-c", code)
+        self.assertTrue(err.startswith(expected), ascii(err))
+
+        # import the warnings module
+        code = "import warnings; f = open(%a)" % __file__
+        rc, out, err = assert_python_ok("-c", code)
+        self.assertTrue(err.startswith(expected), ascii(err))
+
 
 def setUpModule():
     py_warnings.onceregistry.clear()
index 1d4fb208f831c8ec92472114e5127bfbf09c0554..cf9f5b282acdd66884994b377ec397bd91b96dd3 100644 (file)
@@ -21,9 +21,15 @@ def showwarning(message, category, filename, lineno, file=None, line=None):
 
 def formatwarning(message, category, filename, lineno, line=None):
     """Function to format a warning the standard way."""
-    import linecache
     s =  "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message)
-    line = linecache.getline(filename, lineno) if line is None else line
+    if line is None:
+        try:
+            import linecache
+            line = linecache.getline(filename, lineno)
+        except Exception:
+            # When a warning is logged during Python shutdown, linecache
+            # and the improt machinery don't work anymore
+            line = None
     if line:
         line = line.strip()
         s += "  %s\n" % line
index 0058124e570dcea5f6f94612621fbc1690d46fb6..3baeeecae9dd2484de58eb5fd72229b3475389b8 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -94,6 +94,10 @@ Core and Builtins
 Library
 -------
 
+- Issue #21925: :func:`warnings.formatwarning` now catches exceptions on
+  ``linecache.getline(...)`` to be able to log :exc:`ResourceWarning` emitted
+  late during the Python shutdown process.
+
 - Issue #24266: Ctrl+C during Readline history search now cancels the search
   mode when compiled with Readline 7.