From 2c07c493d2eb45101312e3eb3a77f94d0c9cad1f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 13 Nov 2018 02:41:00 +0100 Subject: [PATCH] bpo-29564: warnings suggests to enable tracemalloc (GH-10486) The warnings module now suggests to enable tracemalloc if the source is specified, tracemalloc module is available, but tracemalloc is not tracing memory allocations. --- Lib/test/test_warnings/__init__.py | 25 +++++++++++++++---- Lib/warnings.py | 23 ++++++++++++----- .../2018-11-12-17-40-04.bpo-29564.SFNBT5.rst | 3 +++ 3 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-11-12-17-40-04.bpo-29564.SFNBT5.rst diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py index a4775d03f5..2c54e6137b 100644 --- a/Lib/test/test_warnings/__init__.py +++ b/Lib/test/test_warnings/__init__.py @@ -897,12 +897,27 @@ class PyWarningsDisplayTests(WarningsDisplayTests, unittest.TestCase): func() """)) - res = assert_python_ok('-Wd', '-X', 'tracemalloc=2', support.TESTFN) + def run(*args): + res = assert_python_ok(*args) + stderr = res.err.decode('ascii', 'replace') + stderr = '\n'.join(stderr.splitlines()) - stderr = res.err.decode('ascii', 'replace') - # normalize newlines - stderr = '\n'.join(stderr.splitlines()) - stderr = re.sub('<.*>', '<...>', stderr) + # normalize newlines + stderr = re.sub('<.*>', '<...>', stderr) + return stderr + + # tracemalloc disabled + stderr = run('-Wd', support.TESTFN) + expected = textwrap.dedent(''' + {fname}:5: ResourceWarning: unclosed file <...> + f = None + ResourceWarning: Enable tracemalloc to get the object allocation traceback + ''') + expected = expected.format(fname=support.TESTFN).strip() + self.assertEqual(stderr, expected) + + # tracemalloc enabled + stderr = run('-Wd', '-X', 'tracemalloc=2', support.TESTFN) expected = textwrap.dedent(''' {fname}:5: ResourceWarning: unclosed file <...> f = None diff --git a/Lib/warnings.py b/Lib/warnings.py index 6830b602de..cf88131f87 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -33,9 +33,8 @@ def _showwarnmsg_impl(msg): pass def _formatwarnmsg_impl(msg): - s = ("%s:%s: %s: %s\n" - % (msg.filename, msg.lineno, msg.category.__name__, - msg.message)) + category = msg.category.__name__ + s = f"{msg.filename}:{msg.lineno}: {category}: {msg.message}\n" if msg.line is None: try: @@ -55,11 +54,20 @@ def _formatwarnmsg_impl(msg): if msg.source is not None: try: import tracemalloc - tb = tracemalloc.get_object_traceback(msg.source) + # Logging a warning should not raise a new exception: + # catch Exception, not only ImportError and RecursionError. except Exception: - # When a warning is logged during Python shutdown, tracemalloc - # and the import machinery don't work anymore + # don't suggest to enable tracemalloc if it's not available + tracing = True tb = None + else: + tracing = tracemalloc.is_tracing() + try: + 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: s += 'Object allocated at (most recent call last):\n' @@ -77,6 +85,9 @@ def _formatwarnmsg_impl(msg): if line: line = line.strip() s += ' %s\n' % line + elif not tracing: + s += (f'{category}: Enable tracemalloc to get the object ' + f'allocation traceback\n') return s # Keep a reference to check if the function was replaced diff --git a/Misc/NEWS.d/next/Library/2018-11-12-17-40-04.bpo-29564.SFNBT5.rst b/Misc/NEWS.d/next/Library/2018-11-12-17-40-04.bpo-29564.SFNBT5.rst new file mode 100644 index 0000000000..7ef3adeb73 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-11-12-17-40-04.bpo-29564.SFNBT5.rst @@ -0,0 +1,3 @@ +The warnings module now suggests to enable tracemalloc if the source is +specified, the tracemalloc module is available, but tracemalloc is not +tracing memory allocations. -- 2.40.0