blob: 93ad55269e552fa1e58c5307c5ed4cbff69640e1 [file] [log] [blame]
Fred Drake3208d4b2001-09-22 04:28:19 +00001import pprint
2import sys
3import unittest
4
5import test_support
6
7
8class HookWatcher:
9 def __init__(self):
10 self.frames = []
11 self.events = []
12
13 def callback(self, frame, event, arg):
14 self.add_event(event, frame)
15
16 def add_event(self, event, frame=None):
17 """Add an event to the log."""
18 if frame is None:
19 frame = sys._getframe(1)
20
21 try:
22 frameno = self.frames.index(frame)
23 except ValueError:
24 frameno = len(self.frames)
25 self.frames.append(frame)
26
27 self.events.append((frameno, event, ident(frame)))
28
29 def get_events(self):
30 """Remove calls to add_event()."""
31 add_event = self.add_event.im_func.func_code
32 disallowed = (add_event.co_firstlineno, add_event.co_name)
33
34 return [item for item in self.events if item[2] != disallowed]
35
36
37class ProfileHookTestCase(unittest.TestCase):
38
39 def check_events(self, callable, expected):
40 events = capture_events(callable)
41 if events != expected:
42 self.fail("Expected events:\n%s\nReceived events:\n%s"
43 % (pprint.pformat(expected), pprint.pformat(events)))
44
45 def test_simple(self):
46 def f(p):
47 pass
48 f_ident = ident(f)
49 self.check_events(f, [(0, 'call', f_ident),
50 (0, 'return', f_ident),
51 ])
52
53 def test_exception(self):
54 def f(p):
55 try:
56 1/0
57 except:
58 pass
59 f_ident = ident(f)
60 self.check_events(f, [(0, 'call', f_ident),
61 (0, 'exception', f_ident),
62 (0, 'return', f_ident),
63 ])
64
65 def test_nested_exception(self):
66 def f(p):
67 1/0
68 def g(p):
69 try:
70 f(p)
71 except:
72 pass
73 f_ident = ident(f)
74 g_ident = ident(g)
75 self.check_events(g, [(0, 'call', g_ident),
76 (1, 'call', f_ident),
77 (1, 'exception', f_ident),
78 # This isn't what I expected:
79 (0, 'exception', g_ident),
80 (0, 'return', g_ident),
81 ])
82
83
84def ident(function):
85 if hasattr(function, "f_code"):
86 code = function.f_code
87 else:
88 code = function.func_code
89 return code.co_firstlineno, code.co_name
90
91
92def capture_events(callable):
93 p = HookWatcher()
94 sys.setprofile(p.callback)
95 callable(p)
96 sys.setprofile(None)
97 return p.get_events()
98
99
100def show_events(callable):
101 import pprint
102 pprint.pprint(capture_events(callable))
103
104
105def test_main():
106 test_support.run_unittest(ProfileHookTestCase)
107
108
109if __name__ == "__main__":
110 test_main()