Changeset 388 for python/vendor/current/Lib/pstats.py
- Timestamp:
- Mar 19, 2014, 11:11:30 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
python/vendor/current/Lib/pstats.py
r2 r388 1 1 """Class for printing reports on profiled python code.""" 2 2 3 # Class for printing reports on profiled python code. rev 1.0 4/1/94 4 # 3 # Written by James Roskind 5 4 # Based on prior profile module by Sjoerd Mullender... 6 5 # which was hacked somewhat by: Guido van Rossum 6 7 # Copyright Disney Enterprises, Inc. All Rights Reserved. 8 # Licensed to PSF under a Contributor Agreement 7 9 # 8 # see profile.doc and profile.py for more info. 9 10 # Copyright 1994, by InfoSeek Corporation, all rights reserved. 11 # Written by James Roskind 10 # Licensed under the Apache License, Version 2.0 (the "License"); 11 # you may not use this file except in compliance with the License. 12 # You may obtain a copy of the License at 12 13 # 13 # Permission to use, copy, modify, and distribute this Python software 14 # and its associated documentation for any purpose (subject to the 15 # restriction in the following sentence) without fee is hereby granted, 16 # provided that the above copyright notice appears in all copies, and 17 # that both that copyright notice and this permission notice appear in 18 # supporting documentation, and that the name of InfoSeek not be used in 19 # advertising or publicity pertaining to distribution of the software 20 # without specific, written prior permission. This permission is 21 # explicitly restricted to the copying and modification of the software 22 # to remain in Python, compiled Python, or other languages (such as C) 23 # wherein the modified or derived code is exclusively imported into a 24 # Python module. 14 # http://www.apache.org/licenses/LICENSE-2.0 25 15 # 26 # INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 27 # SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 28 # FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY 29 # SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 30 # RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF 31 # CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 32 # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 # Unless required by applicable law or agreed to in writing, software 17 # distributed under the License is distributed on an "AS IS" BASIS, 18 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 19 # either express or implied. See the License for the specific language 20 # governing permissions and limitations under the License. 33 21 34 22 … … 38 26 import marshal 39 27 import re 28 from functools import cmp_to_key 40 29 41 30 __all__ = ["Stats"] … … 66 55 sort_stats() and get_sort_arg_defs(self) for more examples. 67 56 68 All methods return self, 57 All methods return self, so you can string together commands like: 69 58 Stats('foo', 'goo').strip_dirs().sort_stats('calls').\ 70 59 print_stats(5).print_callers(5) … … 132 121 arg.stats = {} 133 122 if not self.stats: 134 raise TypeError , "Cannot create or construct a %r object from '%r''" % (135 self.__class__, arg)123 raise TypeError("Cannot create or construct a %r object from %r" 124 % (self.__class__, arg)) 136 125 return 137 126 … … 184 173 sort_arg_dict_default = { 185 174 "calls" : (((1,-1), ), "call count"), 175 "ncalls" : (((1,-1), ), "call count"), 176 "cumtime" : (((3,-1), ), "cumulative time"), 186 177 "cumulative": (((3,-1), ), "cumulative time"), 187 178 "file" : (((4, 1), ), "file name"), 179 "filename" : (((4, 1), ), "file name"), 188 180 "line" : (((5, 1), ), "line number"), 189 181 "module" : (((4, 1), ), "file name"), 190 182 "name" : (((6, 1), ), "function name"), 191 183 "nfl" : (((6, 1),(4, 1),(5, 1),), "name/file/line"), 192 "pcalls" : (((0,-1), ), " call count"),184 "pcalls" : (((0,-1), ), "primitive call count"), 193 185 "stdname" : (((7, 1), ), "standard name"), 194 186 "time" : (((2,-1), ), "internal time"), 187 "tottime" : (((2,-1), ), "internal time"), 195 188 } 196 189 … … 218 211 self.fcn_list = 0 219 212 return self 220 if len(field) == 1 and type(field[0]) == type(1):213 if len(field) == 1 and isinstance(field[0], (int, long)): 221 214 # Be compatible with old profiler 222 215 field = [ {-1: "stdname", 223 0:"calls",224 1:"time",225 2: "cumulative" } [ field[0]] ]216 0: "calls", 217 1: "time", 218 2: "cumulative"}[field[0]] ] 226 219 227 220 sort_arg_defs = self.get_sort_arg_defs() … … 239 232 (func_std_string(func), func)) 240 233 241 stats_list.sort(key= CmpToKey(TupleComp(sort_tuple).compare))234 stats_list.sort(key=cmp_to_key(TupleComp(sort_tuple).compare)) 242 235 243 236 self.fcn_list = fcn_list = [] … … 300 293 def eval_print_amount(self, sel, list, msg): 301 294 new_list = list 302 if type(sel) == type(""): 295 if isinstance(sel, basestring): 296 try: 297 rex = re.compile(sel) 298 except re.error: 299 msg += " <Invalid regular expression %r>\n" % sel 300 return new_list, msg 303 301 new_list = [] 304 302 for func in list: 305 if re .search(sel,func_std_string(func)):303 if rex.search(func_std_string(func)): 306 304 new_list.append(func) 307 305 else: 308 306 count = len(list) 309 if type(sel) == type(1.0) and 0.0 <= sel < 1.0:307 if isinstance(sel, float) and 0.0 <= sel < 1.0: 310 308 count = int(count * sel + .5) 311 309 new_list = list[:count] 312 elif type(sel) == type(1) and 0 <= sel < count:310 elif isinstance(sel, (int, long)) and 0 <= sel < count: 313 311 count = sel 314 312 new_list = list[:count] 315 313 if len(list) != len(new_list): 316 msg = msg +" List reduced from %r to %r due to restriction <%r>\n" % (317 314 msg += " List reduced from %r to %r due to restriction <%r>\n" % ( 315 len(list), len(new_list), sel) 318 316 319 317 return new_list, msg … … 322 320 width = self.max_name_len 323 321 if self.fcn_list: 324 list = self.fcn_list[:]322 stat_list = self.fcn_list[:] 325 323 msg = " Ordered by: " + self.sort_type + '\n' 326 324 else: 327 list = self.stats.keys()325 stat_list = self.stats.keys() 328 326 msg = " Random listing order was used\n" 329 327 330 328 for selection in sel_list: 331 list, msg = self.eval_print_amount(selection,list, msg)332 333 count = len( list)334 335 if not list:336 return 0, list329 stat_list, msg = self.eval_print_amount(selection, stat_list, msg) 330 331 count = len(stat_list) 332 333 if not stat_list: 334 return 0, stat_list 337 335 print >> self.stream, msg 338 336 if count < len(self.stats): 339 337 width = 0 340 for func in list:338 for func in stat_list: 341 339 if len(func_std_string(func)) > width: 342 340 width = len(func_std_string(func)) 343 return width+2, list341 return width+2, stat_list 344 342 345 343 def print_stats(self, *amount): … … 354 352 if self.total_calls != self.prim_calls: 355 353 print >> self.stream, "(%d primitive calls)" % self.prim_calls, 356 print >> self.stream, "in %.3f CPUseconds" % self.total_tt354 print >> self.stream, "in %.3f seconds" % self.total_tt 357 355 print >> self.stream 358 356 width, list = self.get_print_list(amount) … … 443 441 print >> self.stream, ' '*8, 444 442 else: 445 print >> self.stream, f8( tt/nc),443 print >> self.stream, f8(float(tt)/nc), 446 444 print >> self.stream, f8(ct), 447 445 if cc == 0: 448 446 print >> self.stream, ' '*8, 449 447 else: 450 print >> self.stream, f8( ct/cc),448 print >> self.stream, f8(float(ct)/cc), 451 449 print >> self.stream, func_std_string(func) 452 450 … … 471 469 return direction 472 470 return 0 473 474 def CmpToKey(mycmp):475 """Convert a cmp= function into a key= function"""476 class K(object):477 def __init__(self, obj):478 self.obj = obj479 def __lt__(self, other):480 return mycmp(self.obj, other.obj) == -1481 return K482 483 471 484 472 #************************************************************************** … … 523 511 for func, caller in source.iteritems(): 524 512 if func in new_callers: 525 new_callers[func] = tuple([i[0] + i[1] for i in 526 zip(caller, new_callers[func])]) 513 if isinstance(caller, tuple): 514 # format used by cProfile 515 new_callers[func] = tuple([i[0] + i[1] for i in 516 zip(caller, new_callers[func])]) 517 else: 518 # format used by profile 519 new_callers[func] += caller 527 520 else: 528 521 new_callers[func] = caller … … 558 551 cmd.Cmd.__init__(self) 559 552 self.prompt = "% " 553 self.stats = None 554 self.stream = sys.stdout 560 555 if profile is not None: 561 self.stats = Stats(profile) 562 self.stream = self.stats.stream 563 else: 564 self.stats = None 565 self.stream = sys.stdout 556 self.do_read(profile) 566 557 567 558 def generic(self, fn, line): … … 598 589 599 590 def do_add(self, line): 600 self.stats.add(line) 591 if self.stats: 592 self.stats.add(line) 593 else: 594 print >> self.stream, "No statistics object is loaded." 601 595 return 0 602 596 def help_add(self): … … 633 627 print >> self.stream, args[1] 634 628 return 629 except Exception as err: 630 print >> self.stream, err.__class__.__name__ + ':', err 631 return 635 632 self.prompt = line + "% " 636 633 elif len(self.prompt) > 2: 637 line = self.prompt[-2:] 634 line = self.prompt[:-2] 635 self.do_read(line) 638 636 else: 639 637 print >> self.stream, "No statistics object is current -- cannot reload." … … 641 639 def help_read(self): 642 640 print >> self.stream, "Read in profile data from a specified file." 641 print >> self.stream, "Without argument, reload the current file." 643 642 644 643 def do_reverse(self, line): 645 self.stats.reverse_order() 644 if self.stats: 645 self.stats.reverse_order() 646 else: 647 print >> self.stream, "No statistics object is loaded." 646 648 return 0 647 649 def help_reverse(self): … … 649 651 650 652 def do_sort(self, line): 653 if not self.stats: 654 print >> self.stream, "No statistics object is loaded." 655 return 651 656 abbrevs = self.stats.get_sort_arg_defs() 652 if line and not filter(lambda x,a=abbrevs: x not in a,line.split()):657 if line and all((x in abbrevs) for x in line.split()): 653 658 self.stats.sort_stats(*line.split()) 654 659 else: … … 670 675 671 676 def do_strip(self, line): 672 self.stats.strip_dirs() 673 return 0 677 if self.stats: 678 self.stats.strip_dirs() 679 else: 680 print >> self.stream, "No statistics object is loaded." 674 681 def help_strip(self): 675 682 print >> self.stream, "Strip leading path information from filenames in the report." 683 684 def help_help(self): 685 print >> self.stream, "Show help for a given command." 676 686 677 687 def postcmd(self, stop, line):
Note:
See TracChangeset
for help on using the changeset viewer.