[Python-checkins] r83523 - in python/branches/py3k: Lib/pstats.py Misc/NEWS

georg.brandl python-checkins at python.org
Mon Aug 2 14:06:18 CEST 2010


Author: georg.brandl
Date: Mon Aug  2 14:06:18 2010
New Revision: 83523

Log:
#9209 and #7781: fix two crashes in pstats interactive browser.

Modified:
   python/branches/py3k/Lib/pstats.py
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Lib/pstats.py
==============================================================================
--- python/branches/py3k/Lib/pstats.py	(original)
+++ python/branches/py3k/Lib/pstats.py	Mon Aug  2 14:06:18 2010
@@ -5,7 +5,7 @@
 # Based on prior profile module by Sjoerd Mullender...
 #   which was hacked somewhat by: Guido van Rossum
 #
-# see profile.doc and profile.py for more info.
+# see profile.py for more info.
 
 # Copyright 1994, by InfoSeek Corporation, all rights reserved.
 # Written by James Roskind
@@ -66,7 +66,7 @@
     minor key of 'the name of the function'.  Look at the two tables in
     sort_stats() and get_sort_arg_defs(self) for more examples.
 
-    All methods return self,  so you can string together commands like:
+    All methods return self, so you can string together commands like:
         Stats('foo', 'goo').strip_dirs().sort_stats('calls').\
                             print_stats(5).print_callers(5)
     """
@@ -138,7 +138,7 @@
         if not arg_list: return self
         if len(arg_list) > 1: self.add(*arg_list[1:])
         other = arg_list[0]
-        if type(self) != type(other) or self.__class__ != other.__class__:
+        if type(self) != type(other):
             other = Stats(other)
         self.files += other.files
         self.total_calls += other.total_calls
@@ -206,12 +206,12 @@
         if not field:
             self.fcn_list = 0
             return self
-        if len(field) == 1 and type(field[0]) == type(1):
+        if len(field) == 1 and isinstance(field[0], int):
             # Be compatible with old profiler
             field = [ {-1: "stdname",
-                      0:"calls",
-                      1:"time",
-                      2: "cumulative" }  [ field[0] ] ]
+                       0:  "calls",
+                       1:  "time",
+                       2:  "cumulative"}[field[0]] ]
 
         sort_arg_defs = self.get_sort_arg_defs()
         sort_tuple = ()
@@ -288,48 +288,53 @@
 
     def eval_print_amount(self, sel, list, msg):
         new_list = list
-        if type(sel) == type(""):
+        if isinstance(sel, str):
+            try:
+                rex = re.compile(sel)
+            except re.error:
+                msg += "   <Invalid regular expression %r>\n" % sel
+                return new_list, msg
             new_list = []
             for func in list:
-                if re.search(sel, func_std_string(func)):
+                if rex.search(func_std_string(func)):
                     new_list.append(func)
         else:
             count = len(list)
-            if type(sel) == type(1.0) and 0.0 <= sel < 1.0:
+            if isinstance(sel, float) and 0.0 <= sel < 1.0:
                 count = int(count * sel + .5)
                 new_list = list[:count]
-            elif type(sel) == type(1) and 0 <= sel < count:
+            elif isinstance(sel, int) and 0 <= sel < count:
                 count = sel
                 new_list = list[:count]
         if len(list) != len(new_list):
-            msg = msg + "   List reduced from %r to %r due to restriction <%r>\n" % (
-                         len(list), len(new_list), sel)
+            msg += "   List reduced from %r to %r due to restriction <%r>\n" % (
+                len(list), len(new_list), sel)
 
         return new_list, msg
 
     def get_print_list(self, sel_list):
         width = self.max_name_len
         if self.fcn_list:
-            list = self.fcn_list[:]
+            stat_list = self.fcn_list[:]
             msg = "   Ordered by: " + self.sort_type + '\n'
         else:
-            list = self.stats.keys()
+            stat_list = list(self.stats.keys())
             msg = "   Random listing order was used\n"
 
         for selection in sel_list:
-            list, msg = self.eval_print_amount(selection, list, msg)
+            stat_list, msg = self.eval_print_amount(selection, stat_list, msg)
 
-        count = len(list)
+        count = len(stat_list)
 
-        if not list:
-            return 0, list
+        if not stat_list:
+            return 0, stat_list
         print(msg, file=self.stream)
         if count < len(self.stats):
             width = 0
-            for func in list:
+            for func in stat_list:
                 if  len(func_std_string(func)) > width:
                     width = len(func_std_string(func))
-        return width+2, list
+        return width+2, stat_list
 
     def print_stats(self, *amount):
         for filename in self.files:
@@ -536,12 +541,10 @@
         def __init__(self, profile=None):
             cmd.Cmd.__init__(self)
             self.prompt = "% "
+            self.stats = None
+            self.stream = sys.stdout
             if profile is not None:
-                self.stats = Stats(profile)
-                self.stream = self.stats.stream
-            else:
-                self.stats = None
-                self.stream = sys.stdout
+                self.do_read(profile)
 
         def generic(self, fn, line):
             args = line.split()

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Mon Aug  2 14:06:18 2010
@@ -29,6 +29,12 @@
 Library
 -------
 
+- Issue #7781: Fix restricting stats by entry counts in the pstats
+  interactive browser.
+
+- Issue #9209: Do not crash in the pstats interactive browser on invalid
+  regular expressions.
+
 - Update collections.OrderedDict to match the implementation in Py2.7
   (based on lists instead of weakly referenced Link objects).
 


More information about the Python-checkins mailing list