Add some more test cases to be sure we do the right thing in various cases.
This commit is contained in:
parent
a0bc9993e7
commit
0099ba73de
|
@ -1,3 +1,5 @@
|
|||
from __future__ import generators
|
||||
|
||||
import pprint
|
||||
import sys
|
||||
import unittest
|
||||
|
@ -40,6 +42,7 @@ class ProfileSimulator(HookWatcher):
|
|||
HookWatcher.__init__(self)
|
||||
|
||||
def callback(self, frame, event, arg):
|
||||
# Callback registered with sys.setprofile()/sys.settrace()
|
||||
self.dispatch[event](self, frame)
|
||||
|
||||
def trace_call(self, frame):
|
||||
|
@ -55,6 +58,8 @@ class ProfileSimulator(HookWatcher):
|
|||
self.add_event('propogate-from', self.stack[-1])
|
||||
self.stack.pop()
|
||||
else:
|
||||
# Either an exception was raised in Python or a C function
|
||||
# raised an exception; this does not represent propogation.
|
||||
self.add_event('ignore', frame)
|
||||
|
||||
dispatch = {
|
||||
|
@ -192,6 +197,79 @@ class ProfileHookTestCase(TestCaseBase):
|
|||
(0, 'exception', protect_ident)
|
||||
])
|
||||
|
||||
def test_distant_exception(self):
|
||||
def f():
|
||||
1/0
|
||||
def g():
|
||||
f()
|
||||
def h():
|
||||
g()
|
||||
def i():
|
||||
h()
|
||||
def j(p):
|
||||
i()
|
||||
f_ident = ident(f)
|
||||
g_ident = ident(g)
|
||||
h_ident = ident(h)
|
||||
i_ident = ident(i)
|
||||
j_ident = ident(j)
|
||||
self.check_events(j, [(1, 'call', j_ident),
|
||||
(2, 'call', i_ident),
|
||||
(3, 'call', h_ident),
|
||||
(4, 'call', g_ident),
|
||||
(5, 'call', f_ident),
|
||||
(5, 'exception', f_ident),
|
||||
(4, 'exception', g_ident),
|
||||
(3, 'exception', h_ident),
|
||||
(2, 'exception', i_ident),
|
||||
(1, 'exception', j_ident),
|
||||
(0, 'exception', protect_ident),
|
||||
])
|
||||
|
||||
def test_generator(self):
|
||||
def f():
|
||||
for i in range(2):
|
||||
yield i
|
||||
def g(p):
|
||||
for i in f():
|
||||
pass
|
||||
f_ident = ident(f)
|
||||
g_ident = ident(g)
|
||||
self.check_events(g, [(1, 'call', g_ident),
|
||||
# call the iterator twice to generate values
|
||||
(2, 'call', f_ident),
|
||||
(2, 'return', f_ident),
|
||||
(2, 'call', f_ident),
|
||||
(2, 'return', f_ident),
|
||||
# once more; returns end-of-iteration with
|
||||
# actually raising an exception
|
||||
(2, 'call', f_ident),
|
||||
(2, 'return', f_ident),
|
||||
(1, 'return', g_ident),
|
||||
])
|
||||
|
||||
def test_stop_iteration(self):
|
||||
def f():
|
||||
for i in range(2):
|
||||
yield i
|
||||
raise StopIteration
|
||||
def g(p):
|
||||
for i in f():
|
||||
pass
|
||||
f_ident = ident(f)
|
||||
g_ident = ident(g)
|
||||
self.check_events(g, [(1, 'call', g_ident),
|
||||
# call the iterator twice to generate values
|
||||
(2, 'call', f_ident),
|
||||
(2, 'return', f_ident),
|
||||
(2, 'call', f_ident),
|
||||
(2, 'return', f_ident),
|
||||
# once more to hit the raise:
|
||||
(2, 'call', f_ident),
|
||||
(2, 'exception', f_ident),
|
||||
(1, 'return', g_ident),
|
||||
])
|
||||
|
||||
|
||||
class ProfileSimulatorTestCase(TestCaseBase):
|
||||
def new_watcher(self):
|
||||
|
@ -214,6 +292,45 @@ class ProfileSimulatorTestCase(TestCaseBase):
|
|||
(1, 'propogate-from', f_ident),
|
||||
])
|
||||
|
||||
def test_caught_exception(self):
|
||||
def f(p):
|
||||
try: 1/0
|
||||
except: pass
|
||||
f_ident = ident(f)
|
||||
self.check_events(f, [(1, 'call', f_ident),
|
||||
(1, 'ignore', f_ident),
|
||||
(1, 'return', f_ident),
|
||||
])
|
||||
|
||||
def test_distant_exception(self):
|
||||
def f():
|
||||
1/0
|
||||
def g():
|
||||
f()
|
||||
def h():
|
||||
g()
|
||||
def i():
|
||||
h()
|
||||
def j(p):
|
||||
i()
|
||||
f_ident = ident(f)
|
||||
g_ident = ident(g)
|
||||
h_ident = ident(h)
|
||||
i_ident = ident(i)
|
||||
j_ident = ident(j)
|
||||
self.check_events(j, [(1, 'call', j_ident),
|
||||
(2, 'call', i_ident),
|
||||
(3, 'call', h_ident),
|
||||
(4, 'call', g_ident),
|
||||
(5, 'call', f_ident),
|
||||
(5, 'ignore', f_ident),
|
||||
(5, 'propogate-from', f_ident),
|
||||
(4, 'propogate-from', g_ident),
|
||||
(3, 'propogate-from', h_ident),
|
||||
(2, 'propogate-from', i_ident),
|
||||
(1, 'propogate-from', j_ident),
|
||||
])
|
||||
|
||||
|
||||
def ident(function):
|
||||
if hasattr(function, "f_code"):
|
||||
|
|
Loading…
Reference in New Issue