Commit 09f7cc8c authored by Victor Stinner's avatar Victor Stinner

Merge 3.5

Issue #21925: warnings.formatwarning() now catches exceptions when calling
linecache.getline() and tracemalloc.get_object_traceback() to be able to log
ResourceWarning emitted late during the Python shutdown process.
parents f799b2c9 75915381
...@@ -536,6 +536,14 @@ class WCmdLineTests(BaseTest): ...@@ -536,6 +536,14 @@ class WCmdLineTests(BaseTest):
self.module._setoption('error::Warning::0') self.module._setoption('error::Warning::0')
self.assertRaises(UserWarning, self.module.warn, 'convert to error') self.assertRaises(UserWarning, self.module.warn, 'convert to error')
class CWCmdLineTests(WCmdLineTests, unittest.TestCase):
module = c_warnings
class PyWCmdLineTests(WCmdLineTests, unittest.TestCase):
module = py_warnings
def test_improper_option(self): def test_improper_option(self):
# Same as above, but check that the message is printed out when # Same as above, but check that the message is printed out when
# the interpreter is executed. This also checks that options are # the interpreter is executed. This also checks that options are
...@@ -552,12 +560,6 @@ class WCmdLineTests(BaseTest): ...@@ -552,12 +560,6 @@ class WCmdLineTests(BaseTest):
self.assertFalse(out.strip()) self.assertFalse(out.strip())
self.assertNotIn(b'RuntimeWarning', err) self.assertNotIn(b'RuntimeWarning', err)
class CWCmdLineTests(WCmdLineTests, unittest.TestCase):
module = c_warnings
class PyWCmdLineTests(WCmdLineTests, unittest.TestCase):
module = py_warnings
class _WarningsTests(BaseTest, unittest.TestCase): class _WarningsTests(BaseTest, unittest.TestCase):
...@@ -976,6 +978,7 @@ class BootstrapTest(unittest.TestCase): ...@@ -976,6 +978,7 @@ class BootstrapTest(unittest.TestCase):
# Use -W to load warnings module at startup # Use -W to load warnings module at startup
assert_python_ok('-c', 'pass', '-W', 'always', PYTHONPATH=cwd) assert_python_ok('-c', 'pass', '-W', 'always', PYTHONPATH=cwd)
class FinalizationTest(unittest.TestCase): class FinalizationTest(unittest.TestCase):
def test_finalization(self): def test_finalization(self):
# Issue #19421: warnings.warn() should not crash # Issue #19421: warnings.warn() should not crash
...@@ -995,6 +998,23 @@ a=A() ...@@ -995,6 +998,23 @@ a=A()
# of the script # of the script
self.assertEqual(err, b'__main__:7: UserWarning: test') 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(): def setUpModule():
py_warnings.onceregistry.clear() py_warnings.onceregistry.clear()
......
...@@ -33,26 +33,47 @@ def _showwarnmsg_impl(msg): ...@@ -33,26 +33,47 @@ def _showwarnmsg_impl(msg):
pass pass
def _formatwarnmsg_impl(msg): def _formatwarnmsg_impl(msg):
import linecache
s = ("%s:%s: %s: %s\n" s = ("%s:%s: %s: %s\n"
% (msg.filename, msg.lineno, msg.category.__name__, % (msg.filename, msg.lineno, msg.category.__name__,
msg.message)) msg.message))
if msg.line is None: if msg.line is None:
line = linecache.getline(msg.filename, msg.lineno) try:
import linecache
line = linecache.getline(msg.filename, msg.lineno)
except Exception:
# When a warning is logged during Python shutdown, linecache
# and the improt machinery don't work anymore
line = None
linecache = None
else: else:
line = msg.line line = msg.line
if line: if line:
line = line.strip() line = line.strip()
s += " %s\n" % line s += " %s\n" % line
if msg.source is not None: if msg.source is not None:
import tracemalloc try:
tb = tracemalloc.get_object_traceback(msg.source) import tracemalloc
tb = tracemalloc.get_object_traceback(msg.source)
except Exception:
# When a warning is logged during Python shutdown, tracemalloc
# and the import machinery don't work anymore
tb = None
if tb is not None: if tb is not None:
s += 'Object allocated at (most recent call first):\n' s += 'Object allocated at (most recent call first):\n'
for frame in tb: for frame in tb:
s += (' File "%s", lineno %s\n' s += (' File "%s", lineno %s\n'
% (frame.filename, frame.lineno)) % (frame.filename, frame.lineno))
line = linecache.getline(frame.filename, frame.lineno)
try:
if linecache is not None:
line = linecache.getline(frame.filename, frame.lineno)
else:
line = None
except Exception:
line = None
if line: if line:
line = line.strip() line = line.strip()
s += ' %s\n' % line s += ' %s\n' % line
......
...@@ -232,6 +232,11 @@ Core and Builtins ...@@ -232,6 +232,11 @@ Core and Builtins
Library Library
------- -------
- Issue #21925: :func:`warnings.formatwarning` now catches exceptions when
calling :func;`linecache.getline` and
:func:`tracemalloc.get_object_traceback` to be able to log
:exc:`ResourceWarning` emitted late during the Python shutdown process.
- Issue #23848: On Windows, faulthandler.enable() now also installs an - Issue #23848: On Windows, faulthandler.enable() now also installs an
exception handler to dump the traceback of all Python threads on any Windows exception handler to dump the traceback of all Python threads on any Windows
exception, not only on UNIX signals (SIGSEGV, SIGFPE, SIGABRT). exception, not only on UNIX signals (SIGSEGV, SIGFPE, SIGABRT).
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment