summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/tracemalloc.rst31
-rw-r--r--Lib/test/test_tracemalloc.py20
-rw-r--r--Lib/tracemalloc.py13
-rw-r--r--Misc/NEWS2
4 files changed, 59 insertions, 7 deletions
diff --git a/Doc/library/tracemalloc.rst b/Doc/library/tracemalloc.rst
index e49d4ca..b79c5f6 100644
--- a/Doc/library/tracemalloc.rst
+++ b/Doc/library/tracemalloc.rst
@@ -118,7 +118,6 @@ Get the traceback of a memory block
Code to display the traceback of the biggest memory block::
- import linecache
import tracemalloc
# Store 25 frames
@@ -132,12 +131,8 @@ Code to display the traceback of the biggest memory block::
# pick the biggest memory block
stat = top_stats[0]
print("%s memory blocks: %.1f KiB" % (stat.count, stat.size / 1024))
- for frame in stat.traceback:
- print(' File "%s", line %s' % (frame.filename, frame.lineno))
- line = linecache.getline(frame.filename, frame.lineno)
- line = line.strip()
- if line:
- print(' ' + line)
+ for line in stat.traceback.format():
+ print(line)
Example of output of the Python test suite (traceback limited to 25 frames)::
@@ -602,4 +597,26 @@ Traceback
The :attr:`Trace.traceback` attribute is an instance of :class:`Traceback`
instance.
+ .. method:: format(limit=None)
+
+ Format the traceback as a list of lines with newlines. Use the
+ :mod:`linecache` module to retrieve lines from the source code. If
+ *limit* is set, only format the *limit* most recent frames.
+
+ Similar to the :func:`traceback.format_tb` function, except that
+ :meth:`format` does not include newlines.
+
+ Example::
+
+ print("Traceback (most recent call first):")
+ for line in traceback:
+ print(line)
+
+ Output::
+
+ Traceback (most recent call first):
+ File "test.py", line 9
+ obj = Object()
+ File "test.py", line 12
+ tb = tracemalloc.get_object_traceback(f())
diff --git a/Lib/test/test_tracemalloc.py b/Lib/test/test_tracemalloc.py
index 3d2333f..d1e5aef 100644
--- a/Lib/test/test_tracemalloc.py
+++ b/Lib/test/test_tracemalloc.py
@@ -510,6 +510,26 @@ class TestSnapshot(unittest.TestCase):
self.assertEqual(traceback[:2],
(traceback[0], traceback[1]))
+ def test_format_traceback(self):
+ snapshot, snapshot2 = create_snapshots()
+ def getline(filename, lineno):
+ return ' <%s, %s>' % (filename, lineno)
+ with unittest.mock.patch('tracemalloc.linecache.getline',
+ side_effect=getline):
+ tb = snapshot.traces[0].traceback
+ self.assertEqual(tb.format(),
+ [' File "a.py", line 2',
+ ' <a.py, 2>',
+ ' File "b.py", line 4',
+ ' <b.py, 4>'])
+
+ self.assertEqual(tb.format(limit=1),
+ [' File "a.py", line 2',
+ ' <a.py, 2>'])
+
+ self.assertEqual(tb.format(limit=-1),
+ [])
+
class TestFilters(unittest.TestCase):
maxDiff = 2048
diff --git a/Lib/tracemalloc.py b/Lib/tracemalloc.py
index b075946..6f0a234 100644
--- a/Lib/tracemalloc.py
+++ b/Lib/tracemalloc.py
@@ -1,6 +1,7 @@
from collections import Sequence
from functools import total_ordering
import fnmatch
+import linecache
import os.path
import pickle
@@ -205,6 +206,18 @@ class Traceback(Sequence):
def __repr__(self):
return "<Traceback %r>" % (tuple(self),)
+ def format(self, limit=None):
+ lines = []
+ if limit is not None and limit < 0:
+ return lines
+ for frame in self[:limit]:
+ lines.append(' File "%s", line %s'
+ % (frame.filename, frame.lineno))
+ line = linecache.getline(frame.filename, frame.lineno).strip()
+ if line:
+ lines.append(' %s' % line)
+ return lines
+
def get_object_traceback(obj):
"""
diff --git a/Misc/NEWS b/Misc/NEWS
index 4a717fc..48b2b89 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -23,6 +23,8 @@ Core and Builtins
Library
-------
+- Issue #20616: Add a format() method to tracemalloc.Traceback.
+
- Issue #19744: the ensurepip installation step now just prints a warning to
stderr rather than failing outright if SSL/TLS is unavailable. This allows
local installation of POSIX builds without SSL/TLS support.