Skip to content

Commit 7591538

Browse files
committed
warnings.formatwarning(): catch exceptions
Issue #21925: warnings.formatwarning() now catches exceptions on linecache.getline(...) to be able to log ResourceWarning emitted late during the Python shutdown process.
1 parent 6af5fa3 commit 7591538

File tree

3 files changed

+29
-2
lines changed

3 files changed

+29
-2
lines changed

Lib/test/test_warnings/__init__.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,23 @@ def __del__(self):
953953
# of the script
954954
self.assertEqual(err, b'__main__:7: UserWarning: test')
955955

956+
def test_late_resource_warning(self):
957+
# Issue #21925: Emitting a ResourceWarning late during the Python
958+
# shutdown must be logged.
959+
960+
expected = b"sys:1: ResourceWarning: unclosed file "
961+
962+
# don't import the warnings module
963+
# (_warnings will try to import it)
964+
code = "f = open(%a)" % __file__
965+
rc, out, err = assert_python_ok("-c", code)
966+
self.assertTrue(err.startswith(expected), ascii(err))
967+
968+
# import the warnings module
969+
code = "import warnings; f = open(%a)" % __file__
970+
rc, out, err = assert_python_ok("-c", code)
971+
self.assertTrue(err.startswith(expected), ascii(err))
972+
956973

957974
def setUpModule():
958975
py_warnings.onceregistry.clear()

Lib/warnings.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,15 @@ def showwarning(message, category, filename, lineno, file=None, line=None):
2121

2222
def formatwarning(message, category, filename, lineno, line=None):
2323
"""Function to format a warning the standard way."""
24-
import linecache
2524
s = "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message)
26-
line = linecache.getline(filename, lineno) if line is None else line
25+
if line is None:
26+
try:
27+
import linecache
28+
line = linecache.getline(filename, lineno)
29+
except Exception:
30+
# When a warning is logged during Python shutdown, linecache
31+
# and the improt machinery don't work anymore
32+
line = None
2733
if line:
2834
line = line.strip()
2935
s += " %s\n" % line

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ Core and Builtins
9494
Library
9595
-------
9696

97+
- Issue #21925: :func:`warnings.formatwarning` now catches exceptions on
98+
``linecache.getline(...)`` to be able to log :exc:`ResourceWarning` emitted
99+
late during the Python shutdown process.
100+
97101
- Issue #24266: Ctrl+C during Readline history search now cancels the search
98102
mode when compiled with Readline 7.
99103

0 commit comments

Comments
 (0)