18ce8ff9ac77bdf202bf39bb98203d26cd40d8e04Victor Stinnerfrom collections import Sequence, Iterable 2ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinnerfrom functools import total_ordering 3ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinnerimport fnmatch 423f628de4ab75acde14de9593793e67ec74d851cVictor Stinnerimport linecache 5ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinnerimport os.path 6ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinnerimport pickle 7ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 8ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner# Import types and functions implemented in C 9ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinnerfrom _tracemalloc import * 10ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinnerfrom _tracemalloc import _get_object_traceback, _get_traces 11ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 12ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 13ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinnerdef _format_size(size, sign): 14ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner for unit in ('B', 'KiB', 'MiB', 'GiB', 'TiB'): 15ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if abs(size) < 100 and unit != 'B': 16ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner # 3 digits (xx.x UNIT) 17ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if sign: 18ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return "%+.1f %s" % (size, unit) 19ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner else: 20ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return "%.1f %s" % (size, unit) 21ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if abs(size) < 10 * 1024 or unit == 'TiB': 22ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner # 4 or 5 digits (xxxx UNIT) 23ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if sign: 24ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return "%+.0f %s" % (size, unit) 25ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner else: 26ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return "%.0f %s" % (size, unit) 27ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner size /= 1024 28ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 29ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 30ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinnerclass Statistic: 31ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 32ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner Statistic difference on memory allocations between two Snapshot instance. 33ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 34ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 35ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner __slots__ = ('traceback', 'size', 'count') 36ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 37ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __init__(self, traceback, size, count): 38ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self.traceback = traceback 39ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self.size = size 40ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self.count = count 41ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 42ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __hash__(self): 43802a484e2482c72a62dc2daeb9dc8e8ebbf1a000Victor Stinner return hash((self.traceback, self.size, self.count)) 44ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 45ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __eq__(self, other): 46ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return (self.traceback == other.traceback 47ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner and self.size == other.size 48ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner and self.count == other.count) 49ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 50ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __str__(self): 51ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner text = ("%s: size=%s, count=%i" 52ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner % (self.traceback, 53ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner _format_size(self.size, False), 54ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self.count)) 55ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if self.count: 56ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner average = self.size / self.count 57ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner text += ", average=%s" % _format_size(average, False) 58ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return text 59ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 60ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __repr__(self): 61ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return ('<Statistic traceback=%r size=%i count=%i>' 62ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner % (self.traceback, self.size, self.count)) 63ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 64ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def _sort_key(self): 65ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return (self.size, self.count, self.traceback) 66ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 67ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 68ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinnerclass StatisticDiff: 69ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 70ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner Statistic difference on memory allocations between an old and a new 71ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner Snapshot instance. 72ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 73ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner __slots__ = ('traceback', 'size', 'size_diff', 'count', 'count_diff') 74ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 75ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __init__(self, traceback, size, size_diff, count, count_diff): 76ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self.traceback = traceback 77ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self.size = size 78ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self.size_diff = size_diff 79ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self.count = count 80ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self.count_diff = count_diff 81ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 82ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __hash__(self): 83802a484e2482c72a62dc2daeb9dc8e8ebbf1a000Victor Stinner return hash((self.traceback, self.size, self.size_diff, 84802a484e2482c72a62dc2daeb9dc8e8ebbf1a000Victor Stinner self.count, self.count_diff)) 85ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 86ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __eq__(self, other): 87ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return (self.traceback == other.traceback 88ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner and self.size == other.size 89ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner and self.size_diff == other.size_diff 90ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner and self.count == other.count 91ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner and self.count_diff == other.count_diff) 92ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 93ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __str__(self): 94ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner text = ("%s: size=%s (%s), count=%i (%+i)" 95ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner % (self.traceback, 96ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner _format_size(self.size, False), 97ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner _format_size(self.size_diff, True), 98ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self.count, 99ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self.count_diff)) 100ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if self.count: 101ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner average = self.size / self.count 102ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner text += ", average=%s" % _format_size(average, False) 103ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return text 104ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 105ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __repr__(self): 106ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return ('<StatisticDiff traceback=%r size=%i (%+i) count=%i (%+i)>' 107ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner % (self.traceback, self.size, self.size_diff, 108ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self.count, self.count_diff)) 109ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 110ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def _sort_key(self): 111ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return (abs(self.size_diff), self.size, 112ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner abs(self.count_diff), self.count, 113ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self.traceback) 114ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 115ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 116ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinnerdef _compare_grouped_stats(old_group, new_group): 117ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner statistics = [] 118ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner for traceback, stat in new_group.items(): 119ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner previous = old_group.pop(traceback, None) 120ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if previous is not None: 121ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner stat = StatisticDiff(traceback, 122d81999a0742f3fc29c2ed9682c38799e6c45c831Victor Stinner stat.size, stat.size - previous.size, 123d81999a0742f3fc29c2ed9682c38799e6c45c831Victor Stinner stat.count, stat.count - previous.count) 124ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner else: 125ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner stat = StatisticDiff(traceback, 126d81999a0742f3fc29c2ed9682c38799e6c45c831Victor Stinner stat.size, stat.size, 127d81999a0742f3fc29c2ed9682c38799e6c45c831Victor Stinner stat.count, stat.count) 128ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner statistics.append(stat) 129ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 130ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner for traceback, stat in old_group.items(): 131ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner stat = StatisticDiff(traceback, 0, -stat.size, 0, -stat.count) 132ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner statistics.append(stat) 133ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return statistics 134ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 135ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 136ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner@total_ordering 137ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinnerclass Frame: 138ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 139ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner Frame of a traceback. 140ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 141ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner __slots__ = ("_frame",) 142ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 143ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __init__(self, frame): 144733e50ad9ee2885323c39080b42716fa5d1fd8c1Victor Stinner # frame is a tuple: (filename: str, lineno: int) 145ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self._frame = frame 146ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 147ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner @property 148ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def filename(self): 149ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return self._frame[0] 150ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 151ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner @property 152ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def lineno(self): 153ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return self._frame[1] 154ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 155ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __eq__(self, other): 156ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return (self._frame == other._frame) 157ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 158ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __lt__(self, other): 159ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return (self._frame < other._frame) 160ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 161ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __hash__(self): 162ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return hash(self._frame) 163ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 164ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __str__(self): 165ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return "%s:%s" % (self.filename, self.lineno) 166ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 167ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __repr__(self): 168ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return "<Frame filename=%r lineno=%r>" % (self.filename, self.lineno) 169ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 170ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 171ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner@total_ordering 172ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinnerclass Traceback(Sequence): 173ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 174ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner Sequence of Frame instances sorted from the most recent frame 175ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner to the oldest frame. 176ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 177ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner __slots__ = ("_frames",) 178ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 179ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __init__(self, frames): 180ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner Sequence.__init__(self) 181733e50ad9ee2885323c39080b42716fa5d1fd8c1Victor Stinner # frames is a tuple of frame tuples: see Frame constructor for the 182733e50ad9ee2885323c39080b42716fa5d1fd8c1Victor Stinner # format of a frame tuple 183ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self._frames = frames 184ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 185ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __len__(self): 186ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return len(self._frames) 187ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 188ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __getitem__(self, index): 189524be3056e29a86741ba355c759ff304adf6cc3cVictor Stinner if isinstance(index, slice): 190524be3056e29a86741ba355c759ff304adf6cc3cVictor Stinner return tuple(Frame(trace) for trace in self._frames[index]) 191524be3056e29a86741ba355c759ff304adf6cc3cVictor Stinner else: 192524be3056e29a86741ba355c759ff304adf6cc3cVictor Stinner return Frame(self._frames[index]) 193ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 194ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __contains__(self, frame): 195ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return frame._frame in self._frames 196ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 197ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __hash__(self): 198ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return hash(self._frames) 199ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 200ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __eq__(self, other): 201ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return (self._frames == other._frames) 202ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 203ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __lt__(self, other): 204ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return (self._frames < other._frames) 205ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 206ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __str__(self): 207ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return str(self[0]) 208ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 209ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __repr__(self): 210ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return "<Traceback %r>" % (tuple(self),) 211ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 21223f628de4ab75acde14de9593793e67ec74d851cVictor Stinner def format(self, limit=None): 21323f628de4ab75acde14de9593793e67ec74d851cVictor Stinner lines = [] 21423f628de4ab75acde14de9593793e67ec74d851cVictor Stinner if limit is not None and limit < 0: 21523f628de4ab75acde14de9593793e67ec74d851cVictor Stinner return lines 21623f628de4ab75acde14de9593793e67ec74d851cVictor Stinner for frame in self[:limit]: 21723f628de4ab75acde14de9593793e67ec74d851cVictor Stinner lines.append(' File "%s", line %s' 21823f628de4ab75acde14de9593793e67ec74d851cVictor Stinner % (frame.filename, frame.lineno)) 21923f628de4ab75acde14de9593793e67ec74d851cVictor Stinner line = linecache.getline(frame.filename, frame.lineno).strip() 22023f628de4ab75acde14de9593793e67ec74d851cVictor Stinner if line: 22123f628de4ab75acde14de9593793e67ec74d851cVictor Stinner lines.append(' %s' % line) 22223f628de4ab75acde14de9593793e67ec74d851cVictor Stinner return lines 22323f628de4ab75acde14de9593793e67ec74d851cVictor Stinner 224ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 225ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinnerdef get_object_traceback(obj): 226ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 227ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner Get the traceback where the Python object *obj* was allocated. 228ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner Return a Traceback instance. 229ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 230ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner Return None if the tracemalloc module is not tracing memory allocations or 231ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner did not trace the allocation of the object. 232ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 233ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner frames = _get_object_traceback(obj) 234ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if frames is not None: 235ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return Traceback(frames) 236ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner else: 237ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return None 238ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 239ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 240ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinnerclass Trace: 241ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 242ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner Trace of a memory block. 243ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 244ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner __slots__ = ("_trace",) 245ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 246ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __init__(self, trace): 247e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner # trace is a tuple: (domain: int, size: int, traceback: tuple). 248e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner # See Traceback constructor for the format of the traceback tuple. 249ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self._trace = trace 250ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 251ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner @property 252e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner def domain(self): 253ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return self._trace[0] 254ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 255ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner @property 256e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner def size(self): 257e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner return self._trace[1] 258e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner 259e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner @property 260ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def traceback(self): 261e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner return Traceback(self._trace[2]) 262ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 263ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __eq__(self, other): 264ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return (self._trace == other._trace) 265ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 266ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __hash__(self): 267ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return hash(self._trace) 268ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 269ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __str__(self): 270ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return "%s: %s" % (self.traceback, _format_size(self.size, False)) 271ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 272ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __repr__(self): 273e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner return ("<Trace domain=%s size=%s, traceback=%r>" 274e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner % (self.domain, _format_size(self.size, False), self.traceback)) 275ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 276ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 277ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinnerclass _Traces(Sequence): 278ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __init__(self, traces): 279ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner Sequence.__init__(self) 280733e50ad9ee2885323c39080b42716fa5d1fd8c1Victor Stinner # traces is a tuple of trace tuples: see Trace constructor 281ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self._traces = traces 282ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 283ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __len__(self): 284ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return len(self._traces) 285ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 286ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __getitem__(self, index): 287524be3056e29a86741ba355c759ff304adf6cc3cVictor Stinner if isinstance(index, slice): 288524be3056e29a86741ba355c759ff304adf6cc3cVictor Stinner return tuple(Trace(trace) for trace in self._traces[index]) 289524be3056e29a86741ba355c759ff304adf6cc3cVictor Stinner else: 290524be3056e29a86741ba355c759ff304adf6cc3cVictor Stinner return Trace(self._traces[index]) 291ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 292ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __contains__(self, trace): 293ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return trace._trace in self._traces 294ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 295ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __eq__(self, other): 296ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return (self._traces == other._traces) 297ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 298ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __repr__(self): 299ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return "<Traces len=%s>" % len(self) 300ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 301ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 302ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinnerdef _normalize_filename(filename): 303ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner filename = os.path.normcase(filename) 304f299abdafa0f2b6eb7abae274861b19b361c96bcBrett Cannon if filename.endswith('.pyc'): 305ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner filename = filename[:-1] 306ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return filename 307ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 308ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 309e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinnerclass BaseFilter: 310e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner def __init__(self, inclusive): 311e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner self.inclusive = inclusive 312e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner 313e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner def _match(self, trace): 314e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner raise NotImplementedError 315e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner 316e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner 317e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinnerclass Filter(BaseFilter): 318ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __init__(self, inclusive, filename_pattern, 319e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner lineno=None, all_frames=False, domain=None): 320e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner super().__init__(inclusive) 321ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self.inclusive = inclusive 322ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self._filename_pattern = _normalize_filename(filename_pattern) 323ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self.lineno = lineno 324ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self.all_frames = all_frames 325e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner self.domain = domain 326ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 327ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner @property 328ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def filename_pattern(self): 329ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return self._filename_pattern 330ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 331e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner def _match_frame_impl(self, filename, lineno): 332ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner filename = _normalize_filename(filename) 333ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if not fnmatch.fnmatch(filename, self._filename_pattern): 334ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return False 335ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if self.lineno is None: 336ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return True 337ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner else: 338ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return (lineno == self.lineno) 339ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 340ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def _match_frame(self, filename, lineno): 341e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner return self._match_frame_impl(filename, lineno) ^ (not self.inclusive) 342ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 343ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def _match_traceback(self, traceback): 344ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if self.all_frames: 345e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner if any(self._match_frame_impl(filename, lineno) 346ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner for filename, lineno in traceback): 347ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return self.inclusive 348ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner else: 349ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return (not self.inclusive) 350ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner else: 351ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner filename, lineno = traceback[0] 352ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return self._match_frame(filename, lineno) 353ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 354e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner def _match(self, trace): 355e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner domain, size, traceback = trace 356e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner res = self._match_traceback(traceback) 357e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner if self.domain is not None: 358e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner if self.inclusive: 359e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner return res and (domain == self.domain) 360e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner else: 361e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner return res or (domain != self.domain) 362e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner return res 363e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner 364e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner 365e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinnerclass DomainFilter(BaseFilter): 366e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner def __init__(self, inclusive, domain): 367e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner super().__init__(inclusive) 368e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner self._domain = domain 369e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner 370e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner @property 371e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner def domain(self): 372e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner return self._domain 373e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner 374e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner def _match(self, trace): 375e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner domain, size, traceback = trace 376e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner return (domain == self.domain) ^ (not self.inclusive) 377e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner 378ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 379ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinnerclass Snapshot: 380ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 381ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner Snapshot of traces of memory blocks allocated by Python. 382ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 383ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 384ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def __init__(self, traces, traceback_limit): 385733e50ad9ee2885323c39080b42716fa5d1fd8c1Victor Stinner # traces is a tuple of trace tuples: see _Traces constructor for 386733e50ad9ee2885323c39080b42716fa5d1fd8c1Victor Stinner # the exact format 387ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self.traces = _Traces(traces) 388ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner self.traceback_limit = traceback_limit 389ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 390ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def dump(self, filename): 391ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 392ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner Write the snapshot into a file. 393ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 394ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner with open(filename, "wb") as fp: 395ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner pickle.dump(self, fp, pickle.HIGHEST_PROTOCOL) 396ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 397ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner @staticmethod 398ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def load(filename): 399ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 400ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner Load a snapshot from a file. 401ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 402ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner with open(filename, "rb") as fp: 403ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return pickle.load(fp) 404ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 405ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def _filter_trace(self, include_filters, exclude_filters, trace): 406ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if include_filters: 407e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner if not any(trace_filter._match(trace) 408ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner for trace_filter in include_filters): 409ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return False 410ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if exclude_filters: 411e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner if any(not trace_filter._match(trace) 412ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner for trace_filter in exclude_filters): 413ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return False 414ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return True 415ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 416ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def filter_traces(self, filters): 417ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 418ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner Create a new Snapshot instance with a filtered traces sequence, filters 419e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner is a list of Filter or DomainFilter instances. If filters is an empty 420e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner list, return a new Snapshot instance with a copy of the traces. 421ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 4228ce8ff9ac77bdf202bf39bb98203d26cd40d8e04Victor Stinner if not isinstance(filters, Iterable): 4238ce8ff9ac77bdf202bf39bb98203d26cd40d8e04Victor Stinner raise TypeError("filters must be a list of filters, not %s" 4248ce8ff9ac77bdf202bf39bb98203d26cd40d8e04Victor Stinner % type(filters).__name__) 425ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if filters: 426ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner include_filters = [] 427ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner exclude_filters = [] 428ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner for trace_filter in filters: 429ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if trace_filter.inclusive: 430ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner include_filters.append(trace_filter) 431ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner else: 432ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner exclude_filters.append(trace_filter) 433ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner new_traces = [trace for trace in self.traces._traces 434ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if self._filter_trace(include_filters, 435ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner exclude_filters, 436ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner trace)] 437ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner else: 438ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner new_traces = self.traces._traces.copy() 439ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return Snapshot(new_traces, self.traceback_limit) 440ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 441ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def _group_by(self, key_type, cumulative): 442ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if key_type not in ('traceback', 'filename', 'lineno'): 443ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner raise ValueError("unknown key_type: %r" % (key_type,)) 444ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if cumulative and key_type not in ('lineno', 'filename'): 445ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner raise ValueError("cumulative mode cannot by used " 446ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner "with key type %r" % key_type) 447ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 448ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner stats = {} 449ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner tracebacks = {} 450ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if not cumulative: 451ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner for trace in self.traces._traces: 452e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner domain, size, trace_traceback = trace 453ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner try: 454ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner traceback = tracebacks[trace_traceback] 455ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner except KeyError: 456ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if key_type == 'traceback': 457ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner frames = trace_traceback 458ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner elif key_type == 'lineno': 459ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner frames = trace_traceback[:1] 460ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner else: # key_type == 'filename': 461ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner frames = ((trace_traceback[0][0], 0),) 462ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner traceback = Traceback(frames) 463ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner tracebacks[trace_traceback] = traceback 464ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner try: 465ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner stat = stats[traceback] 466ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner stat.size += size 467ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner stat.count += 1 468ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner except KeyError: 469ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner stats[traceback] = Statistic(traceback, size, 1) 470ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner else: 471ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner # cumulative statistics 472ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner for trace in self.traces._traces: 473e492ae50e251c4fcd48bc37b1eaa4821894f1fdbVictor Stinner domain, size, trace_traceback = trace 474ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner for frame in trace_traceback: 475ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner try: 476ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner traceback = tracebacks[frame] 477ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner except KeyError: 478ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if key_type == 'lineno': 479ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner frames = (frame,) 480ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner else: # key_type == 'filename': 481ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner frames = ((frame[0], 0),) 482ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner traceback = Traceback(frames) 483ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner tracebacks[frame] = traceback 484ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner try: 485ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner stat = stats[traceback] 486ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner stat.size += size 487ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner stat.count += 1 488ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner except KeyError: 489ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner stats[traceback] = Statistic(traceback, size, 1) 490ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return stats 491ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 492ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def statistics(self, key_type, cumulative=False): 493ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 494ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner Group statistics by key_type. Return a sorted list of Statistic 495ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner instances. 496ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 497ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner grouped = self._group_by(key_type, cumulative) 498ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner statistics = list(grouped.values()) 499ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner statistics.sort(reverse=True, key=Statistic._sort_key) 500ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return statistics 501ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 502ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner def compare_to(self, old_snapshot, key_type, cumulative=False): 503ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 504ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner Compute the differences with an old snapshot old_snapshot. Get 505ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner statistics as a sorted list of StatisticDiff instances, grouped by 506ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner group_by. 507ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 508ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner new_group = self._group_by(key_type, cumulative) 509ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner old_group = old_snapshot._group_by(key_type, cumulative) 510ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner statistics = _compare_grouped_stats(old_group, new_group) 511ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner statistics.sort(reverse=True, key=StatisticDiff._sort_key) 512ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return statistics 513ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 514ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner 515ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinnerdef take_snapshot(): 516ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 517ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner Take a snapshot of traces of memory blocks allocated by Python. 518ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner """ 519ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner if not is_tracing(): 520ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner raise RuntimeError("the tracemalloc module must be tracing memory " 521ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner "allocations to take a snapshot") 522ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner traces = _get_traces() 523ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner traceback_limit = get_traceback_limit() 524ed3b0bca3ef9d7bdbb8bd8e67e60e85f5a336da0Victor Stinner return Snapshot(traces, traceback_limit) 525