web.profiler has unexpected behavior in python 2.5

Bug #133080 reported by Mythin
2
Affects Status Importance Assigned to Milestone
web.py
Fix Released
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)
description: updated
Aaron Swartz (aaronsw)
Changed in webpy:
assignee: nobody → anandology
importance: Undecided → Medium
status: New → Confirmed
Revision history for this message
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  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.