home *** CD-ROM | disk | FTP | other *** search
/ Chip 2011 November / CHIP_2011_11.iso / Programy / Narzedzia / Calibre / calibre-0.8.18.msi / file_262 / pstats.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2011-09-09  |  20.5 KB  |  705 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.7)
  3.  
  4. import sys
  5. import os
  6. import time
  7. import marshal
  8. import re
  9. from functools import cmp_to_key
  10. __all__ = [
  11.     'Stats']
  12.  
  13. class Stats:
  14.     
  15.     def __init__(self, *args, **kwds):
  16.         self.stream = sys.stdout
  17.         if 'stream' in kwds:
  18.             self.stream = kwds['stream']
  19.             del kwds['stream']
  20.         if kwds:
  21.             keys = kwds.keys()
  22.             keys.sort()
  23.             extras = ', '.join([ '%s=%s' % (k, kwds[k]) for k in keys ])
  24.             raise ValueError, 'unrecognized keyword args: %s' % extras
  25.         if not len(args):
  26.             arg = None
  27.         else:
  28.             arg = args[0]
  29.             args = args[1:]
  30.         self.init(arg)
  31.         self.add(*args)
  32.  
  33.     
  34.     def init(self, arg):
  35.         self.all_callees = None
  36.         self.files = []
  37.         self.fcn_list = None
  38.         self.total_tt = 0
  39.         self.total_calls = 0
  40.         self.prim_calls = 0
  41.         self.max_name_len = 0
  42.         self.top_level = { }
  43.         self.stats = { }
  44.         self.sort_arg_dict = { }
  45.         self.load_stats(arg)
  46.         trouble = 1
  47.         
  48.         try:
  49.             self.get_top_level_stats()
  50.             trouble = 0
  51.         finally:
  52.             if trouble:
  53.                 print >>self.stream, 'Invalid timing data',
  54.                 if self.files:
  55.                     print >>self.stream, self.files[-1],
  56.                 print >>self.stream
  57.  
  58.  
  59.     
  60.     def load_stats(self, arg):
  61.         if not arg:
  62.             self.stats = { }
  63.         elif isinstance(arg, basestring):
  64.             f = open(arg, 'rb')
  65.             self.stats = marshal.load(f)
  66.             f.close()
  67.             
  68.             try:
  69.                 file_stats = os.stat(arg)
  70.                 arg = time.ctime(file_stats.st_mtime) + '    ' + arg
  71.             except:
  72.                 pass
  73.  
  74.             self.files = [
  75.                 arg]
  76.         elif hasattr(arg, 'create_stats'):
  77.             arg.create_stats()
  78.             self.stats = arg.stats
  79.             arg.stats = { }
  80.         if not self.stats:
  81.             raise TypeError, "Cannot create or construct a %r object from '%r''" % (self.__class__, arg)
  82.  
  83.     
  84.     def get_top_level_stats(self):
  85.         for cc, nc, tt, ct, callers in self.stats.items():
  86.             self.total_calls += nc
  87.             self.prim_calls += cc
  88.             self.total_tt += tt
  89.             if ('jprofile', 0, 'profiler') in callers:
  90.                 self.top_level[func] = None
  91.             if len(func_std_string(func)) > self.max_name_len:
  92.                 self.max_name_len = len(func_std_string(func))
  93.                 continue
  94.  
  95.     
  96.     def add(self, *arg_list):
  97.         if not arg_list:
  98.             return self
  99.         if None(arg_list) > 1:
  100.             self.add(*arg_list[1:])
  101.         other = arg_list[0]
  102.         if type(self) != type(other) or self.__class__ != other.__class__:
  103.             other = Stats(other)
  104.         self.files += other.files
  105.         self.total_calls += other.total_calls
  106.         self.prim_calls += other.prim_calls
  107.         self.total_tt += other.total_tt
  108.         for func in other.top_level:
  109.             self.top_level[func] = None
  110.         
  111.         if self.max_name_len < other.max_name_len:
  112.             self.max_name_len = other.max_name_len
  113.         self.fcn_list = None
  114.         for func, stat in other.stats.iteritems():
  115.             self.stats[func] = add_func_stats(old_func_stat, stat)
  116.         
  117.         return self
  118.  
  119.     
  120.     def dump_stats(self, filename):
  121.         f = file(filename, 'wb')
  122.         
  123.         try:
  124.             marshal.dump(self.stats, f)
  125.         finally:
  126.             f.close()
  127.  
  128.  
  129.     sort_arg_dict_default = {
  130.         'calls': (((1, -1),), 'call count'),
  131.         'cumulative': (((3, -1),), 'cumulative time'),
  132.         'file': (((4, 1),), 'file name'),
  133.         'line': (((5, 1),), 'line number'),
  134.         'module': (((4, 1),), 'file name'),
  135.         'name': (((6, 1),), 'function name'),
  136.         'nfl': (((6, 1), (4, 1), (5, 1)), 'name/file/line'),
  137.         'pcalls': (((0, -1),), 'call count'),
  138.         'stdname': (((7, 1),), 'standard name'),
  139.         'time': (((2, -1),), 'internal time') }
  140.     
  141.     def get_sort_arg_defs(self):
  142.         if not self.sort_arg_dict:
  143.             self.sort_arg_dict = dict = { }
  144.             bad_list = { }
  145.             for word, tup in self.sort_arg_dict_default.iteritems():
  146.                 fragment = word
  147.                 while fragment:
  148.                     if not fragment:
  149.                         break
  150.                     if fragment in dict:
  151.                         bad_list[fragment] = 0
  152.                         break
  153.                     dict[fragment] = tup
  154.                     fragment = fragment[:-1]
  155.             
  156.             for word in bad_list:
  157.                 del dict[word]
  158.             
  159.         return self.sort_arg_dict
  160.  
  161.     
  162.     def sort_stats(self, *field):
  163.         if not field:
  164.             self.fcn_list = 0
  165.             return self
  166.         if None(field) == 1 and isinstance(field[0], (int, long)):
  167.             field = [
  168.                 {
  169.                     -1: 'stdname',
  170.                     0: 'calls',
  171.                     1: 'time',
  172.                     2: 'cumulative' }[field[0]]]
  173.         sort_arg_defs = self.get_sort_arg_defs()
  174.         sort_tuple = ()
  175.         self.sort_type = ''
  176.         connector = ''
  177.         for word in field:
  178.             sort_tuple = sort_tuple + sort_arg_defs[word][0]
  179.             self.sort_type += connector + sort_arg_defs[word][1]
  180.             connector = ', '
  181.         
  182.         stats_list = []
  183.         for cc, nc, tt, ct, callers in self.stats.iteritems():
  184.             stats_list.append((cc, nc, tt, ct) + func + (func_std_string(func), func))
  185.         
  186.         stats_list.sort(key = cmp_to_key(TupleComp(sort_tuple).compare))
  187.         self.fcn_list = fcn_list = []
  188.         for tuple in stats_list:
  189.             fcn_list.append(tuple[-1])
  190.         
  191.         return self
  192.  
  193.     
  194.     def reverse_order(self):
  195.         if self.fcn_list:
  196.             self.fcn_list.reverse()
  197.         return self
  198.  
  199.     
  200.     def strip_dirs(self):
  201.         oldstats = self.stats
  202.         self.stats = newstats = { }
  203.         max_name_len = 0
  204.         for cc, nc, tt, ct, callers in oldstats.iteritems():
  205.             newfunc = func_strip_path(func)
  206.             if len(func_std_string(newfunc)) > max_name_len:
  207.                 max_name_len = len(func_std_string(newfunc))
  208.             newcallers = { }
  209.             for func2, caller in callers.iteritems():
  210.                 newcallers[func_strip_path(func2)] = caller
  211.             
  212.             if newfunc in newstats:
  213.                 newstats[newfunc] = add_func_stats(newstats[newfunc], (cc, nc, tt, ct, newcallers))
  214.                 continue
  215.             newstats[newfunc] = (cc, nc, tt, ct, newcallers)
  216.         
  217.         old_top = self.top_level
  218.         self.top_level = new_top = { }
  219.         for func in old_top:
  220.             new_top[func_strip_path(func)] = None
  221.         
  222.         self.max_name_len = max_name_len
  223.         self.fcn_list = None
  224.         self.all_callees = None
  225.         return self
  226.  
  227.     
  228.     def calc_callees(self):
  229.         if self.all_callees:
  230.             return None
  231.         self.all_callees = None
  232.         all_callees = None
  233.         for cc, nc, tt, ct, callers in self.stats.iteritems():
  234.             if func not in all_callees:
  235.                 all_callees[func] = { }
  236.             for func2, caller in callers.iteritems():
  237.                 if func2 not in all_callees:
  238.                     all_callees[func2] = { }
  239.                 all_callees[func2][func] = caller
  240.             
  241.         
  242.  
  243.     
  244.     def eval_print_amount(self, sel, list, msg):
  245.         new_list = list
  246.         if isinstance(sel, basestring):
  247.             
  248.             try:
  249.                 rex = re.compile(sel)
  250.             except re.error:
  251.                 msg += '   <Invalid regular expression %r>\n' % sel
  252.                 return (new_list, msg)
  253.  
  254.             new_list = []
  255.             for func in list:
  256.                 if rex.search(func_std_string(func)):
  257.                     new_list.append(func)
  258.                     continue
  259.         count = len(list)
  260.         if isinstance(sel, float):
  261.             if sel <= sel:
  262.                 pass
  263.             elif sel < 1:
  264.                 count = int(count * sel + 0.5)
  265.                 new_list = list[:count]
  266.             elif isinstance(sel, (int, long)):
  267.                 if sel <= sel:
  268.                     pass
  269.                 elif sel < count:
  270.                     count = sel
  271.                     new_list = list[:count]
  272.         if len(list) != len(new_list):
  273.             msg += '   List reduced from %r to %r due to restriction <%r>\n' % (len(list), len(new_list), sel)
  274.         return (new_list, msg)
  275.  
  276.     
  277.     def get_print_list(self, sel_list):
  278.         width = self.max_name_len
  279.         if self.fcn_list:
  280.             stat_list = self.fcn_list[:]
  281.             msg = '   Ordered by: ' + self.sort_type + '\n'
  282.         else:
  283.             stat_list = self.stats.keys()
  284.             msg = '   Random listing order was used\n'
  285.         for selection in sel_list:
  286.             (stat_list, msg) = self.eval_print_amount(selection, stat_list, msg)
  287.         
  288.         count = len(stat_list)
  289.         if not stat_list:
  290.             return (0, stat_list)
  291.         print >>None.stream, msg
  292.         if count < len(self.stats):
  293.             width = 0
  294.             for func in stat_list:
  295.                 if len(func_std_string(func)) > width:
  296.                     width = len(func_std_string(func))
  297.                     continue
  298.         return (width + 2, stat_list)
  299.  
  300.     
  301.     def print_stats(self, *amount):
  302.         for filename in self.files:
  303.             print >>self.stream, filename
  304.         
  305.         if self.files:
  306.             print >>self.stream
  307.         indent = '        '
  308.         for func in self.top_level:
  309.             print >>self.stream, indent, func_get_function_name(func)
  310.         
  311.         print >>self.stream, indent, self.total_calls, 'function calls',
  312.         if self.total_calls != self.prim_calls:
  313.             print >>self.stream, '(%d primitive calls)' % self.prim_calls,
  314.         print >>self.stream, 'in %.3f seconds' % self.total_tt
  315.         print >>self.stream
  316.         (width, list) = self.get_print_list(amount)
  317.         if list:
  318.             self.print_title()
  319.             for func in list:
  320.                 self.print_line(func)
  321.             
  322.             print >>self.stream
  323.             print >>self.stream
  324.         return self
  325.  
  326.     
  327.     def print_callees(self, *amount):
  328.         (width, list) = self.get_print_list(amount)
  329.         if list:
  330.             self.calc_callees()
  331.             self.print_call_heading(width, 'called...')
  332.             for func in list:
  333.                 if func in self.all_callees:
  334.                     self.print_call_line(width, func, self.all_callees[func])
  335.                     continue
  336.                 self.print_call_line(width, func, { })
  337.             
  338.             print >>self.stream
  339.             print >>self.stream
  340.         return self
  341.  
  342.     
  343.     def print_callers(self, *amount):
  344.         (width, list) = self.get_print_list(amount)
  345.         if list:
  346.             self.print_call_heading(width, 'was called by...')
  347.             for func in list:
  348.                 (cc, nc, tt, ct, callers) = self.stats[func]
  349.                 self.print_call_line(width, func, callers, '<-')
  350.             
  351.             print >>self.stream
  352.             print >>self.stream
  353.         return self
  354.  
  355.     
  356.     def print_call_heading(self, name_size, column_title):
  357.         print >>self.stream, 'Function '.ljust(name_size) + column_title
  358.         subheader = False
  359.         for cc, nc, tt, ct, callers in self.stats.itervalues():
  360.             if callers:
  361.                 value = callers.itervalues().next()
  362.                 subheader = isinstance(value, tuple)
  363.                 break
  364.                 continue
  365.         if subheader:
  366.             print >>self.stream, ' ' * name_size + '    ncalls  tottime  cumtime'
  367.  
  368.     
  369.     def print_call_line(self, name_size, source, call_dict, arrow = '->'):
  370.         print >>self.stream, func_std_string(source).ljust(name_size) + arrow,
  371.         if not call_dict:
  372.             print >>self.stream
  373.             return None
  374.         clist = None.keys()
  375.         clist.sort()
  376.         indent = ''
  377.         for func in clist:
  378.             name = func_std_string(func)
  379.             value = call_dict[func]
  380.             if isinstance(value, tuple):
  381.                 (nc, cc, tt, ct) = value
  382.                 if nc != cc:
  383.                     substats = '%d/%d' % (nc, cc)
  384.                 else:
  385.                     substats = '%d' % (nc,)
  386.                 substats = '%s %s %s  %s' % (substats.rjust(7 + 2 * len(indent)), f8(tt), f8(ct), name)
  387.                 left_width = name_size + 1
  388.             else:
  389.                 substats = '%s(%r) %s' % (name, value, f8(self.stats[func][3]))
  390.                 left_width = name_size + 3
  391.             print >>self.stream, indent * left_width + substats
  392.             indent = ' '
  393.         
  394.  
  395.     
  396.     def print_title(self):
  397.         print >>self.stream, '   ncalls  tottime  percall  cumtime  percall',
  398.         print >>self.stream, 'filename:lineno(function)'
  399.  
  400.     
  401.     def print_line(self, func):
  402.         (cc, nc, tt, ct, callers) = self.stats[func]
  403.         c = str(nc)
  404.         if nc != cc:
  405.             c = c + '/' + str(cc)
  406.         print >>self.stream, c.rjust(9),
  407.         print >>self.stream, f8(tt),
  408.         if nc == 0:
  409.             print >>self.stream, '        ',
  410.         else:
  411.             print >>self.stream, f8(float(tt) / nc),
  412.         print >>self.stream, f8(ct),
  413.         if cc == 0:
  414.             print >>self.stream, '        ',
  415.         else:
  416.             print >>self.stream, f8(float(ct) / cc),
  417.         print >>self.stream, func_std_string(func)
  418.  
  419.  
  420.  
  421. class TupleComp:
  422.     
  423.     def __init__(self, comp_select_list):
  424.         self.comp_select_list = comp_select_list
  425.  
  426.     
  427.     def compare(self, left, right):
  428.         for index, direction in self.comp_select_list:
  429.             l = left[index]
  430.             r = right[index]
  431.             if l < r:
  432.                 return -direction
  433.             if None > r:
  434.                 return direction
  435.         
  436.         return 0
  437.  
  438.  
  439.  
  440. def func_strip_path(func_name):
  441.     (filename, line, name) = func_name
  442.     return (os.path.basename(filename), line, name)
  443.  
  444.  
  445. def func_get_function_name(func):
  446.     return func[2]
  447.  
  448.  
  449. def func_std_string(func_name):
  450.     if func_name[:2] == ('~', 0):
  451.         name = func_name[2]
  452.         if name.startswith('<') and name.endswith('>'):
  453.             return '{%s}' % name[1:-1]
  454.         return None
  455.     return '%s:%d(%s)' % func_name
  456.  
  457.  
  458. def add_func_stats(target, source):
  459.     (cc, nc, tt, ct, callers) = source
  460.     (t_cc, t_nc, t_tt, t_ct, t_callers) = target
  461.     return (cc + t_cc, nc + t_nc, tt + t_tt, ct + t_ct, add_callers(t_callers, callers))
  462.  
  463.  
  464. def add_callers(target, source):
  465.     new_callers = { }
  466.     for func, caller in target.iteritems():
  467.         new_callers[func] = caller
  468.     
  469.     for func, caller in source.iteritems():
  470.         if func in new_callers:
  471.             if isinstance(caller, tuple):
  472.                 new_callers[func] = tuple([ i[0] + i[1] for i in zip(caller, new_callers[func]) ])
  473.             else:
  474.                 new_callers[func] += caller
  475.         new_callers[func] = caller
  476.     
  477.     return new_callers
  478.  
  479.  
  480. def count_calls(callers):
  481.     nc = 0
  482.     for calls in callers.itervalues():
  483.         nc += calls
  484.     
  485.     return nc
  486.  
  487.  
  488. def f8(x):
  489.     return '%8.3f' % x
  490.  
  491. if __name__ == '__main__':
  492.     import cmd
  493.     
  494.     try:
  495.         import readline
  496.     except ImportError:
  497.         pass
  498.  
  499.     
  500.     class ProfileBrowser(cmd.Cmd):
  501.         
  502.         def __init__(self, profile = None):
  503.             cmd.Cmd.__init__(self)
  504.             self.prompt = '% '
  505.             self.stats = None
  506.             self.stream = sys.stdout
  507.             if profile is not None:
  508.                 self.do_read(profile)
  509.  
  510.         
  511.         def generic(self, fn, line):
  512.             args = line.split()
  513.             processed = []
  514.             for term in args:
  515.                 
  516.                 try:
  517.                     processed.append(int(term))
  518.                 except ValueError:
  519.                     pass
  520.  
  521.                 
  522.                 try:
  523.                     frac = float(term)
  524.                     if frac > 1 or frac < 0:
  525.                         print >>self.stream, 'Fraction argument must be in [0, 1]'
  526.                         continue
  527.                     processed.append(frac)
  528.                 except ValueError:
  529.                     pass
  530.  
  531.                 processed.append(term)
  532.             
  533.             if self.stats:
  534.                 getattr(self.stats, fn)(*processed)
  535.             else:
  536.                 print >>self.stream, 'No statistics object is loaded.'
  537.             return 0
  538.  
  539.         
  540.         def generic_help(self):
  541.             print >>self.stream, 'Arguments may be:'
  542.             print >>self.stream, '* An integer maximum number of entries to print.'
  543.             print >>self.stream, '* A decimal fractional number between 0 and 1, controlling'
  544.             print >>self.stream, '  what fraction of selected entries to print.'
  545.             print >>self.stream, '* A regular expression; only entries with function names'
  546.             print >>self.stream, '  that match it are printed.'
  547.  
  548.         
  549.         def do_add(self, line):
  550.             if self.stats:
  551.                 self.stats.add(line)
  552.             else:
  553.                 print >>self.stream, 'No statistics object is loaded.'
  554.             return 0
  555.  
  556.         
  557.         def help_add(self):
  558.             print >>self.stream, 'Add profile info from given file to current statistics object.'
  559.  
  560.         
  561.         def do_callees(self, line):
  562.             return self.generic('print_callees', line)
  563.  
  564.         
  565.         def help_callees(self):
  566.             print >>self.stream, 'Print callees statistics from the current stat object.'
  567.             self.generic_help()
  568.  
  569.         
  570.         def do_callers(self, line):
  571.             return self.generic('print_callers', line)
  572.  
  573.         
  574.         def help_callers(self):
  575.             print >>self.stream, 'Print callers statistics from the current stat object.'
  576.             self.generic_help()
  577.  
  578.         
  579.         def do_EOF(self, line):
  580.             print >>self.stream, ''
  581.             return 1
  582.  
  583.         
  584.         def help_EOF(self):
  585.             print >>self.stream, 'Leave the profile brower.'
  586.  
  587.         
  588.         def do_quit(self, line):
  589.             return 1
  590.  
  591.         
  592.         def help_quit(self):
  593.             print >>self.stream, 'Leave the profile brower.'
  594.  
  595.         
  596.         def do_read(self, line):
  597.             if line:
  598.                 
  599.                 try:
  600.                     self.stats = Stats(line)
  601.                 except IOError:
  602.                     args = None
  603.                     print >>self.stream, args[1]
  604.                     return None
  605.                     except Exception:
  606.                         err = None
  607.                         print >>self.stream, err.__class__.__name__ + ':', err
  608.                         return None
  609.                     else:
  610.                         self.prompt = line + '% '
  611.                 except:
  612.                     if len(self.prompt) > 2:
  613.                         line = self.prompt[:-2]
  614.                         self.do_read(line)
  615.                     else:
  616.                         print >>self.stream, 'No statistics object is current -- cannot reload.'
  617.  
  618.             return 0
  619.  
  620.         
  621.         def help_read(self):
  622.             print >>self.stream, 'Read in profile data from a specified file.'
  623.             print >>self.stream, 'Without argument, reload the current file.'
  624.  
  625.         
  626.         def do_reverse(self, line):
  627.             if self.stats:
  628.                 self.stats.reverse_order()
  629.             else:
  630.                 print >>self.stream, 'No statistics object is loaded.'
  631.             return 0
  632.  
  633.         
  634.         def help_reverse(self):
  635.             print >>self.stream, 'Reverse the sort order of the profiling report.'
  636.  
  637.         
  638.         def do_sort(self, line):
  639.             if not self.stats:
  640.                 print >>self.stream, 'No statistics object is loaded.'
  641.                 return None
  642.             abbrevs = None.stats.get_sort_arg_defs()
  643.             if line and (all,)((lambda .0: pass)(line.split())):
  644.                 self.stats.sort_stats(*line.split())
  645.             else:
  646.                 print >>self.stream, 'Valid sort keys (unique prefixes are accepted):'
  647.                 for key, value in Stats.sort_arg_dict_default.iteritems():
  648.                     print >>self.stream, '%s -- %s' % (key, value[1])
  649.                 
  650.             return 0
  651.  
  652.         
  653.         def help_sort(self):
  654.             print >>self.stream, 'Sort profile data according to specified keys.'
  655.             print >>self.stream, "(Typing `sort' without arguments lists valid keys.)"
  656.  
  657.         
  658.         def complete_sort(self, text, *args):
  659.             return [ a for a in Stats.sort_arg_dict_default if a.startswith(text) ]
  660.  
  661.         
  662.         def do_stats(self, line):
  663.             return self.generic('print_stats', line)
  664.  
  665.         
  666.         def help_stats(self):
  667.             print >>self.stream, 'Print statistics from the current stat object.'
  668.             self.generic_help()
  669.  
  670.         
  671.         def do_strip(self, line):
  672.             if self.stats:
  673.                 self.stats.strip_dirs()
  674.             else:
  675.                 print >>self.stream, 'No statistics object is loaded.'
  676.  
  677.         
  678.         def help_strip(self):
  679.             print >>self.stream, 'Strip leading path information from filenames in the report.'
  680.  
  681.         
  682.         def help_help(self):
  683.             print >>self.stream, 'Show help for a given command.'
  684.  
  685.         
  686.         def postcmd(self, stop, line):
  687.             if stop:
  688.                 return stop
  689.  
  690.  
  691.     import sys
  692.     if len(sys.argv) > 1:
  693.         initprofile = sys.argv[1]
  694.     else:
  695.         initprofile = None
  696.     
  697.     try:
  698.         browser = ProfileBrowser(initprofile)
  699.         print >>browser.stream, 'Welcome to the profile statistics browser.'
  700.         browser.cmdloop()
  701.         print >>browser.stream, 'Goodbye.'
  702.     except KeyboardInterrupt:
  703.         pass
  704.  
  705.