web.profiler has unexpected behavior in python 2.5

Bug #133080 reported by Mythin on 2007-08-17
2
Affects Status Importance Assigned to Milestone
web.py
Medium
Anand Chitipothu

Bug Description

pstats.py was changed either in python 2.4 or 2.5 to print out to it's own self.stream which is pointed at sys.stdout when the object is first initialized. This break the capturestdout class with web.profiler. The sys.stdout needs to be redirected before the object is created:

class Profile:
    """
    Profiles `func` and returns a tuple containing its output
    and a string with human-readable profiling information.

        >>> import time
        >>> out, inf = profile(time.sleep)(.001)
        >>> out
        >>> inf[:10].strip()
        'took 0.0'
    """
    def __init__(self, func):
        self.func = func
    def __call__(self, *args): ##, **kw): kw unused
        import hotshot, hotshot.stats, tempfile ##, time already imported
        temp = tempfile.NamedTemporaryFile()
        prof = hotshot.Profile(temp.name)

        stime = time.time()
        result = prof.runcall(self.func, *args)
        stime = time.time() - stime

        prof.close()
        from cStringIO import StringIO
        # Not threadsafe!
        out = StringIO()
        oldstdout = sys.stdout
        sys.stdout = out
        try:
                stats = hotshot.stats.load(temp.name)
                stats.strip_dirs()
                stats.sort_stats('time', 'calls')
                stats.print_stats(40)
                stats.print_callers()
                x = '\n\ntook '+ str(stime) + ' seconds\n'
                x += out.getvalue()
        finally:
                sys.stdout = oldstdout
        return result, x

Mythin (mythin) on 2007-08-17
description: updated
Aaron Swartz (aaronsw) on 2007-08-17
Changed in webpy:
assignee: nobody → anandology
importance: Undecided → Medium
status: New → Confirmed
Anand Chitipothu (anandology) wrote :

The above patch does the work of capturestdout also. Here is much cleaner fix.

def print_stats():
    stats = hotshot.stats.load(temp.name)
    stats.strip_dirs()
    stats.sort_stats('time', 'calls')
    stats.print_stats(40)
    stats.print_callers()

x = '\n\ntook '+ str(stime) + ' seconds\n'
x += capturestdout(print_stats)()

Changed in webpy:
milestone: none → 0.23
status: Confirmed → Fix Committed
Changed in webpy:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers