[Python-checkins] CVS: python/dist/src/Lib/test test_profilehooks.py,NONE,1.1

Fred L. Drake fdrake@users.sourceforge.net
Fri, 21 Sep 2001 21:28:21 -0700


Update of /cvsroot/python/python/dist/src/Lib/test
In directory usw-pr-cvs1:/tmp/cvs-serv27436

Added Files:
	test_profilehooks.py 
Log Message:
Start of a test to make sure the profiler/tracer support in the core
interpreter is reporting what we expect to see.


--- NEW FILE: test_profilehooks.py ---
import pprint
import sys
import unittest

import test_support


class HookWatcher:
    def __init__(self):
        self.frames = []
        self.events = []

    def callback(self, frame, event, arg):
        self.add_event(event, frame)

    def add_event(self, event, frame=None):
        """Add an event to the log."""
        if frame is None:
            frame = sys._getframe(1)

        try:
            frameno = self.frames.index(frame)
        except ValueError:
            frameno = len(self.frames)
            self.frames.append(frame)

        self.events.append((frameno, event, ident(frame)))

    def get_events(self):
        """Remove calls to add_event()."""
        add_event = self.add_event.im_func.func_code
        disallowed = (add_event.co_firstlineno, add_event.co_name)

        return [item for item in self.events if item[2] != disallowed]


class ProfileHookTestCase(unittest.TestCase):

    def check_events(self, callable, expected):
        events = capture_events(callable)
        if events != expected:
            self.fail("Expected events:\n%s\nReceived events:\n%s"
                      % (pprint.pformat(expected), pprint.pformat(events)))

    def test_simple(self):
        def f(p):
            pass
        f_ident = ident(f)
        self.check_events(f, [(0, 'call', f_ident),
                              (0, 'return', f_ident),
                              ])

    def test_exception(self):
        def f(p):
            try:
                1/0
            except:
                pass
        f_ident = ident(f)
        self.check_events(f, [(0, 'call', f_ident),
                              (0, 'exception', f_ident),
                              (0, 'return', f_ident),
                              ])

    def test_nested_exception(self):
        def f(p):
            1/0
        def g(p):
            try:
                f(p)
            except:
                pass
        f_ident = ident(f)
        g_ident = ident(g)
        self.check_events(g, [(0, 'call', g_ident),
                              (1, 'call', f_ident),
                              (1, 'exception', f_ident),
                              # This isn't what I expected:
                              (0, 'exception', g_ident),
                              (0, 'return', g_ident),
                              ])


def ident(function):
    if hasattr(function, "f_code"):
        code = function.f_code
    else:
        code = function.func_code
    return code.co_firstlineno, code.co_name


def capture_events(callable):
    p = HookWatcher()
    sys.setprofile(p.callback)
    callable(p)
    sys.setprofile(None)
    return p.get_events()


def show_events(callable):
    import pprint
    pprint.pprint(capture_events(callable))


def test_main():
    test_support.run_unittest(ProfileHookTestCase)


if __name__ == "__main__":
    test_main()