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