Widespread random code cleanup.
Most of this code was old enough to vote. Examples of cleanups: + Backslashes were used for line continuation even inside unclosed bracket structures, from back in the days that was still needed. + There was no use of % formats, and e.g. the old fpformat module was still used to format floats "by hand" in conjunction with rjust(). + There was even use of a do-nothing .ignore() method to tack on to the end of a chain of method calls, else way back when Python would print the non-None result (as it does now in an interactive session -- it *used* to do that in batch mode too). + Perhaps controversial (although I can't imagine why for real <wink>), used augmented assignment where helpful. Stuff like self.total_calls = self.total_calls + other.total_calls is just plain harder to follow than self.total_calls += other.total_calls
This commit is contained in:
parent
03290ecbf1
commit
7d01685738
141
Lib/pstats.py
141
Lib/pstats.py
|
@ -37,8 +37,6 @@ import time
|
||||||
import marshal
|
import marshal
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import fpformat
|
|
||||||
|
|
||||||
__all__ = ["Stats"]
|
__all__ = ["Stats"]
|
||||||
|
|
||||||
class Stats:
|
class Stats:
|
||||||
|
@ -78,7 +76,7 @@ class Stats:
|
||||||
arg = args[0]
|
arg = args[0]
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
self.init(arg)
|
self.init(arg)
|
||||||
apply(self.add, args).ignore()
|
apply(self.add, args)
|
||||||
|
|
||||||
def init(self, arg):
|
def init(self, arg):
|
||||||
self.all_callees = None # calc only if needed
|
self.all_callees = None # calc only if needed
|
||||||
|
@ -102,7 +100,6 @@ class Stats:
|
||||||
if self.files: print self.files[-1],
|
if self.files: print self.files[-1],
|
||||||
print
|
print
|
||||||
|
|
||||||
|
|
||||||
def load_stats(self, arg):
|
def load_stats(self, arg):
|
||||||
if not arg: self.stats = {}
|
if not arg: self.stats = {}
|
||||||
elif type(arg) == type(""):
|
elif type(arg) == type(""):
|
||||||
|
@ -126,11 +123,10 @@ class Stats:
|
||||||
return
|
return
|
||||||
|
|
||||||
def get_top_level_stats(self):
|
def get_top_level_stats(self):
|
||||||
for func in self.stats.keys():
|
for func, (cc, nc, tt, ct, callers) in self.stats.items():
|
||||||
cc, nc, tt, ct, callers = self.stats[func]
|
self.total_calls += nc
|
||||||
self.total_calls = self.total_calls + nc
|
self.prim_calls += cc
|
||||||
self.prim_calls = self.prim_calls + cc
|
self.total_tt += tt
|
||||||
self.total_tt = self.total_tt + tt
|
|
||||||
if callers.has_key(("jprofile", 0, "profiler")):
|
if callers.has_key(("jprofile", 0, "profiler")):
|
||||||
self.top_level[func] = None
|
self.top_level[func] = None
|
||||||
if len(func_std_string(func)) > self.max_name_len:
|
if len(func_std_string(func)) > self.max_name_len:
|
||||||
|
@ -140,13 +136,12 @@ class Stats:
|
||||||
if not arg_list: return self
|
if not arg_list: return self
|
||||||
if len(arg_list) > 1: apply(self.add, arg_list[1:])
|
if len(arg_list) > 1: apply(self.add, arg_list[1:])
|
||||||
other = arg_list[0]
|
other = arg_list[0]
|
||||||
if type(self) != type(other) or \
|
if type(self) != type(other) or self.__class__ != other.__class__:
|
||||||
self.__class__ != other.__class__:
|
|
||||||
other = Stats(other)
|
other = Stats(other)
|
||||||
self.files = self.files + other.files
|
self.files += other.files
|
||||||
self.total_calls = self.total_calls + other.total_calls
|
self.total_calls += other.total_calls
|
||||||
self.prim_calls = self.prim_calls + other.prim_calls
|
self.prim_calls += other.prim_calls
|
||||||
self.total_tt = self.total_tt + other.total_tt
|
self.total_tt += other.total_tt
|
||||||
for func in other.top_level.keys():
|
for func in other.top_level.keys():
|
||||||
self.top_level[func] = None
|
self.top_level[func] = None
|
||||||
|
|
||||||
|
@ -160,25 +155,22 @@ class Stats:
|
||||||
old_func_stat = self.stats[func]
|
old_func_stat = self.stats[func]
|
||||||
else:
|
else:
|
||||||
old_func_stat = (0, 0, 0, 0, {},)
|
old_func_stat = (0, 0, 0, 0, {},)
|
||||||
self.stats[func] = add_func_stats(old_func_stat, \
|
self.stats[func] = add_func_stats(old_func_stat, other.stats[func])
|
||||||
other.stats[func])
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# list the tuple indices and directions for sorting,
|
# list the tuple indices and directions for sorting,
|
||||||
# along with some printable description
|
# along with some printable description
|
||||||
sort_arg_dict_default = {\
|
sort_arg_dict_default = {
|
||||||
"calls" : (((1,-1), ), "call count"),\
|
"calls" : (((1,-1), ), "call count"),
|
||||||
"cumulative": (((3,-1), ), "cumulative time"),\
|
"cumulative": (((3,-1), ), "cumulative time"),
|
||||||
"file" : (((4, 1), ), "file name"),\
|
"file" : (((4, 1), ), "file name"),
|
||||||
"line" : (((5, 1), ), "line number"),\
|
"line" : (((5, 1), ), "line number"),
|
||||||
"module" : (((4, 1), ), "file name"),\
|
"module" : (((4, 1), ), "file name"),
|
||||||
"name" : (((6, 1), ), "function name"),\
|
"name" : (((6, 1), ), "function name"),
|
||||||
"nfl" : (((6, 1),(4, 1),(5, 1),), "name/file/line"), \
|
"nfl" : (((6, 1),(4, 1),(5, 1),), "name/file/line"),
|
||||||
"pcalls" : (((0,-1), ), "call count"),\
|
"pcalls" : (((0,-1), ), "call count"),
|
||||||
"stdname" : (((7, 1), ), "standard name"),\
|
"stdname" : (((7, 1), ), "standard name"),
|
||||||
"time" : (((2,-1), ), "internal time"),\
|
"time" : (((2,-1), ), "internal time"),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_sort_arg_defs(self):
|
def get_sort_arg_defs(self):
|
||||||
|
@ -194,23 +186,21 @@ class Stats:
|
||||||
if dict.has_key(fragment):
|
if dict.has_key(fragment):
|
||||||
bad_list[fragment] = 0
|
bad_list[fragment] = 0
|
||||||
break
|
break
|
||||||
dict[fragment] = self. \
|
dict[fragment] = self.sort_arg_dict_default[word]
|
||||||
sort_arg_dict_default[word]
|
|
||||||
fragment = fragment[:-1]
|
fragment = fragment[:-1]
|
||||||
for word in bad_list.keys():
|
for word in bad_list.keys():
|
||||||
del dict[word]
|
del dict[word]
|
||||||
return self.sort_arg_dict
|
return self.sort_arg_dict
|
||||||
|
|
||||||
|
|
||||||
def sort_stats(self, *field):
|
def sort_stats(self, *field):
|
||||||
if not field:
|
if not field:
|
||||||
self.fcn_list = 0
|
self.fcn_list = 0
|
||||||
return self
|
return self
|
||||||
if len(field) == 1 and type(field[0]) == type(1):
|
if len(field) == 1 and type(field[0]) == type(1):
|
||||||
# Be compatible with old profiler
|
# Be compatible with old profiler
|
||||||
field = [ {-1: "stdname", \
|
field = [ {-1: "stdname",
|
||||||
0:"calls", \
|
0:"calls",
|
||||||
1:"time", \
|
1:"time",
|
||||||
2: "cumulative" } [ field[0] ] ]
|
2: "cumulative" } [ field[0] ] ]
|
||||||
|
|
||||||
sort_arg_defs = self.get_sort_arg_defs()
|
sort_arg_defs = self.get_sort_arg_defs()
|
||||||
|
@ -219,15 +209,14 @@ class Stats:
|
||||||
connector = ""
|
connector = ""
|
||||||
for word in field:
|
for word in field:
|
||||||
sort_tuple = sort_tuple + sort_arg_defs[word][0]
|
sort_tuple = sort_tuple + sort_arg_defs[word][0]
|
||||||
self.sort_type = self.sort_type + connector + \
|
self.sort_type += connector + sort_arg_defs[word][1]
|
||||||
sort_arg_defs[word][1]
|
|
||||||
connector = ", "
|
connector = ", "
|
||||||
|
|
||||||
stats_list = []
|
stats_list = []
|
||||||
for func in self.stats.keys():
|
for func in self.stats.keys():
|
||||||
cc, nc, tt, ct, callers = self.stats[func]
|
cc, nc, tt, ct, callers = self.stats[func]
|
||||||
stats_list.append((cc, nc, tt, ct) + func_split(func) \
|
stats_list.append((cc, nc, tt, ct) + func +
|
||||||
+ (func_std_string(func), func,) )
|
(func_std_string(func), func))
|
||||||
|
|
||||||
stats_list.sort(TupleComp(sort_tuple).compare)
|
stats_list.sort(TupleComp(sort_tuple).compare)
|
||||||
|
|
||||||
|
@ -236,9 +225,9 @@ class Stats:
|
||||||
fcn_list.append(tuple[-1])
|
fcn_list.append(tuple[-1])
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
def reverse_order(self):
|
def reverse_order(self):
|
||||||
if self.fcn_list: self.fcn_list.reverse()
|
if self.fcn_list:
|
||||||
|
self.fcn_list.reverse()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def strip_dirs(self):
|
def strip_dirs(self):
|
||||||
|
@ -252,13 +241,12 @@ class Stats:
|
||||||
max_name_len = len(func_std_string(newfunc))
|
max_name_len = len(func_std_string(newfunc))
|
||||||
newcallers = {}
|
newcallers = {}
|
||||||
for func2 in callers.keys():
|
for func2 in callers.keys():
|
||||||
newcallers[func_strip_path(func2)] = \
|
newcallers[func_strip_path(func2)] = callers[func2]
|
||||||
callers[func2]
|
|
||||||
|
|
||||||
if newstats.has_key(newfunc):
|
if newstats.has_key(newfunc):
|
||||||
newstats[newfunc] = add_func_stats( \
|
newstats[newfunc] = add_func_stats(
|
||||||
newstats[newfunc],\
|
newstats[newfunc],
|
||||||
(cc, nc, tt, ct, newcallers))
|
(cc, nc, tt, ct, newcallers))
|
||||||
else:
|
else:
|
||||||
newstats[newfunc] = (cc, nc, tt, ct, newcallers)
|
newstats[newfunc] = (cc, nc, tt, ct, newcallers)
|
||||||
old_top = self.top_level
|
old_top = self.top_level
|
||||||
|
@ -272,8 +260,6 @@ class Stats:
|
||||||
self.all_callees = None
|
self.all_callees = None
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def calc_callees(self):
|
def calc_callees(self):
|
||||||
if self.all_callees: return
|
if self.all_callees: return
|
||||||
self.all_callees = all_callees = {}
|
self.all_callees = all_callees = {}
|
||||||
|
@ -303,7 +289,7 @@ class Stats:
|
||||||
else:
|
else:
|
||||||
count = len(list)
|
count = len(list)
|
||||||
if type(sel) == type(1.0) and 0.0 <= sel < 1.0:
|
if type(sel) == type(1.0) and 0.0 <= sel < 1.0:
|
||||||
count = int (count * sel + .5)
|
count = int(count * sel + .5)
|
||||||
new_list = list[:count]
|
new_list = list[:count]
|
||||||
elif type(sel) == type(1) and 0 <= sel < count:
|
elif type(sel) == type(1) and 0 <= sel < count:
|
||||||
count = sel
|
count = sel
|
||||||
|
@ -315,8 +301,6 @@ class Stats:
|
||||||
|
|
||||||
return new_list, msg
|
return new_list, msg
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_print_list(self, sel_list):
|
def get_print_list(self, sel_list):
|
||||||
width = self.max_name_len
|
width = self.max_name_len
|
||||||
if self.fcn_list:
|
if self.fcn_list:
|
||||||
|
@ -327,7 +311,7 @@ class Stats:
|
||||||
msg = " Random listing order was used\n"
|
msg = " Random listing order was used\n"
|
||||||
|
|
||||||
for selection in sel_list:
|
for selection in sel_list:
|
||||||
list,msg = self.eval_print_amount(selection, list, msg)
|
list, msg = self.eval_print_amount(selection, list, msg)
|
||||||
|
|
||||||
count = len(list)
|
count = len(list)
|
||||||
|
|
||||||
|
@ -345,14 +329,14 @@ class Stats:
|
||||||
for filename in self.files:
|
for filename in self.files:
|
||||||
print filename
|
print filename
|
||||||
if self.files: print
|
if self.files: print
|
||||||
indent = " "
|
indent = ' ' * 8
|
||||||
for func in self.top_level.keys():
|
for func in self.top_level.keys():
|
||||||
print indent, func_get_function_name(func)
|
print indent, func_get_function_name(func)
|
||||||
|
|
||||||
print indent, self.total_calls, "function calls",
|
print indent, self.total_calls, "function calls",
|
||||||
if self.total_calls != self.prim_calls:
|
if self.total_calls != self.prim_calls:
|
||||||
print "(" + `self.prim_calls`, "primitive calls)",
|
print "(%d primitive calls)" % self.prim_calls,
|
||||||
print "in", fpformat.fix(self.total_tt, 3), "CPU seconds"
|
print "in %.3f CPU seconds" % self.total_tt
|
||||||
print
|
print
|
||||||
width, list = self.get_print_list(amount)
|
width, list = self.get_print_list(amount)
|
||||||
if list:
|
if list:
|
||||||
|
@ -363,7 +347,6 @@ class Stats:
|
||||||
print
|
print
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
def print_callees(self, *amount):
|
def print_callees(self, *amount):
|
||||||
width, list = self.get_print_list(amount)
|
width, list = self.get_print_list(amount)
|
||||||
if list:
|
if list:
|
||||||
|
@ -372,8 +355,7 @@ class Stats:
|
||||||
self.print_call_heading(width, "called...")
|
self.print_call_heading(width, "called...")
|
||||||
for func in list:
|
for func in list:
|
||||||
if self.all_callees.has_key(func):
|
if self.all_callees.has_key(func):
|
||||||
self.print_call_line(width, \
|
self.print_call_line(width, func, self.all_callees[func])
|
||||||
func, self.all_callees[func])
|
|
||||||
else:
|
else:
|
||||||
self.print_call_line(width, func, {})
|
self.print_call_line(width, func, {})
|
||||||
print
|
print
|
||||||
|
@ -394,7 +376,6 @@ class Stats:
|
||||||
def print_call_heading(self, name_size, column_title):
|
def print_call_heading(self, name_size, column_title):
|
||||||
print "Function ".ljust(name_size) + column_title
|
print "Function ".ljust(name_size) + column_title
|
||||||
|
|
||||||
|
|
||||||
def print_call_line(self, name_size, source, call_dict):
|
def print_call_line(self, name_size, source, call_dict):
|
||||||
print func_std_string(source).ljust(name_size),
|
print func_std_string(source).ljust(name_size),
|
||||||
if not call_dict:
|
if not call_dict:
|
||||||
|
@ -411,22 +392,15 @@ class Stats:
|
||||||
f8(self.stats[func][3])
|
f8(self.stats[func][3])
|
||||||
indent = " "
|
indent = " "
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def print_title(self):
|
def print_title(self):
|
||||||
print 'ncalls'.rjust(9),
|
print ' ncalls tottime percall cumtime percall', \
|
||||||
print 'tottime'.rjust(8),
|
'filename:lineno(function)'
|
||||||
print 'percall'.rjust(8),
|
|
||||||
print 'cumtime'.rjust(8),
|
|
||||||
print 'percall'.rjust(8),
|
|
||||||
print 'filename:lineno(function)'
|
|
||||||
|
|
||||||
|
|
||||||
def print_line(self, func): # hack : should print percentages
|
def print_line(self, func): # hack : should print percentages
|
||||||
cc, nc, tt, ct, callers = self.stats[func]
|
cc, nc, tt, ct, callers = self.stats[func]
|
||||||
c = `nc`
|
c = str(nc)
|
||||||
if nc != cc:
|
if nc != cc:
|
||||||
c = c + '/' + `cc`
|
c = c + '/' + str(cc)
|
||||||
print c.rjust(9),
|
print c.rjust(9),
|
||||||
print f8(tt),
|
print f8(tt),
|
||||||
if nc == 0:
|
if nc == 0:
|
||||||
|
@ -440,11 +414,6 @@ class Stats:
|
||||||
print f8(ct/cc),
|
print f8(ct/cc),
|
||||||
print func_std_string(func)
|
print func_std_string(func)
|
||||||
|
|
||||||
|
|
||||||
def ignore(self):
|
|
||||||
pass # has no return value, so use at end of line :-)
|
|
||||||
|
|
||||||
|
|
||||||
class TupleComp:
|
class TupleComp:
|
||||||
"""This class provides a generic function for comparing any two tuples.
|
"""This class provides a generic function for comparing any two tuples.
|
||||||
Each instance records a list of tuple-indices (from most significant
|
Each instance records a list of tuple-indices (from most significant
|
||||||
|
@ -466,9 +435,12 @@ class TupleComp:
|
||||||
return direction
|
return direction
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
def ignore(self):
|
||||||
|
# Deprecated since 1.5.1 -- see the docs.
|
||||||
|
pass # has no return value, so use at end of line :-)
|
||||||
|
|
||||||
#**************************************************************************
|
#**************************************************************************
|
||||||
|
# func_name is a triple (file:string, line:int, name:string)
|
||||||
|
|
||||||
def func_strip_path(func_name):
|
def func_strip_path(func_name):
|
||||||
file, line, name = func_name
|
file, line, name = func_name
|
||||||
|
@ -478,11 +450,7 @@ def func_get_function_name(func):
|
||||||
return func[2]
|
return func[2]
|
||||||
|
|
||||||
def func_std_string(func_name): # match what old profile produced
|
def func_std_string(func_name): # match what old profile produced
|
||||||
file, line, name = func_name
|
return "%s:%d(%s)" % func_name
|
||||||
return file + ":" + `line` + "(" + name + ")"
|
|
||||||
|
|
||||||
def func_split(func_name):
|
|
||||||
return func_name
|
|
||||||
|
|
||||||
#**************************************************************************
|
#**************************************************************************
|
||||||
# The following functions combine statists for pairs functions.
|
# The following functions combine statists for pairs functions.
|
||||||
|
@ -494,10 +462,9 @@ def add_func_stats(target, source):
|
||||||
"""Add together all the stats for two profile entries."""
|
"""Add together all the stats for two profile entries."""
|
||||||
cc, nc, tt, ct, callers = source
|
cc, nc, tt, ct, callers = source
|
||||||
t_cc, t_nc, t_tt, t_ct, t_callers = target
|
t_cc, t_nc, t_tt, t_ct, t_callers = target
|
||||||
return (cc+t_cc, nc+t_nc, tt+t_tt, ct+t_ct, \
|
return (cc+t_cc, nc+t_nc, tt+t_tt, ct+t_ct,
|
||||||
add_callers(t_callers, callers))
|
add_callers(t_callers, callers))
|
||||||
|
|
||||||
|
|
||||||
def add_callers(target, source):
|
def add_callers(target, source):
|
||||||
"""Combine two caller lists in a single list."""
|
"""Combine two caller lists in a single list."""
|
||||||
new_callers = {}
|
new_callers = {}
|
||||||
|
@ -514,7 +481,7 @@ def count_calls(callers):
|
||||||
"""Sum the caller statistics to get total number of calls received."""
|
"""Sum the caller statistics to get total number of calls received."""
|
||||||
nc = 0
|
nc = 0
|
||||||
for func in callers.keys():
|
for func in callers.keys():
|
||||||
nc = nc + callers[func]
|
nc += callers[func]
|
||||||
return nc
|
return nc
|
||||||
|
|
||||||
#**************************************************************************
|
#**************************************************************************
|
||||||
|
@ -522,7 +489,7 @@ def count_calls(callers):
|
||||||
#**************************************************************************
|
#**************************************************************************
|
||||||
|
|
||||||
def f8(x):
|
def f8(x):
|
||||||
return fpformat.fix(x, 3).rjust(8)
|
return "%8.3f" % x
|
||||||
|
|
||||||
#**************************************************************************
|
#**************************************************************************
|
||||||
# Statistics browser added by ESR, April 2001
|
# Statistics browser added by ESR, April 2001
|
||||||
|
|
Loading…
Reference in New Issue