]> granicus.if.org Git - python/commitdiff
Add some more test cases to be sure we do the right thing in various cases.
authorFred Drake <fdrake@acm.org>
Wed, 3 Oct 2001 21:15:32 +0000 (21:15 +0000)
committerFred Drake <fdrake@acm.org>
Wed, 3 Oct 2001 21:15:32 +0000 (21:15 +0000)
Lib/test/test_profilehooks.py

index 579443ea74ebd4f3d3a166d93003fdf85e5b6d99..33c3f534d07161264c06fcbb77e7db177301f957 100644 (file)
@@ -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"):