[Python-checkins] python/dist/src/Lib trace.py,1.18,1.19

montanaro at users.sourceforge.net montanaro at users.sourceforge.net
Wed Apr 7 11:46:08 EDT 2004


Update of /cvsroot/python/python/dist/src/Lib
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26703
Modified Files:
	trace.py 
Log Message:
Added --trackcalls command line arg to display crude caller/callee
relationships at program exit. Output is a bit prettier than that for
--listfuncs but won't parse as easily using downstream postprocessing tools.
Index: trace.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/trace.py,v
retrieving revision 1.18
retrieving revision 1.19
diff -C2 -d -r1.18 -r1.19
*** trace.py	19 Feb 2004 19:16:50 -0000	1.18
--- trace.py	7 Apr 2004 15:46:05 -0000	1.19
***************
*** 33,36 ****
--- 33,37 ----
 trace.py -c -f counts --ignore-dir '$prefix' spam.py eggs
 trace.py -t --ignore-dir '$prefix' spam.py eggs
+ trace.py --track-callers spam.py eggs
 
 Sample use, programmatically
***************
*** 77,80 ****
--- 78,83 ----
 once and write the results to sys.stdout after the
 program exits.
+ -T, --trackcalls Keep track of caller/called pairs and write the
+ results to sys.stdout after the program exits.
 -r, --report Generate a report from a counts file; do not execute
 any code. `--file' must specify the results file to
***************
*** 192,196 ****
 class CoverageResults:
 def __init__(self, counts=None, calledfuncs=None, infile=None,
! outfile=None):
 self.counts = counts
 if self.counts is None:
--- 195,199 ----
 class CoverageResults:
 def __init__(self, counts=None, calledfuncs=None, infile=None,
! callers=None, outfile=None):
 self.counts = counts
 if self.counts is None:
***************
*** 201,204 ****
--- 204,211 ----
 self.calledfuncs = {}
 self.calledfuncs = self.calledfuncs.copy()
+ self.callers = callers
+ if self.callers is None:
+ self.callers = {}
+ self.callers = self.callers.copy()
 self.infile = infile
 self.outfile = outfile
***************
*** 206,211 ****
 # Try to merge existing counts file.
 try:
! counts, calledfuncs = pickle.load(open(self.infile, 'rb'))
! self.update(self.__class__(counts, calledfuncs))
 except (IOError, EOFError, ValueError), err:
 print >> sys.stderr, ("Skipping counts file %r: %s"
--- 213,219 ----
 # Try to merge existing counts file.
 try:
! counts, calledfuncs, callers = \
! pickle.load(open(self.infile, 'rb'))
! self.update(self.__class__(counts, calledfuncs, callers))
 except (IOError, EOFError, ValueError), err:
 print >> sys.stderr, ("Skipping counts file %r: %s"
***************
*** 216,221 ****
--- 224,231 ----
 counts = self.counts
 calledfuncs = self.calledfuncs
+ callers = self.callers
 other_counts = other.counts
 other_calledfuncs = other.calledfuncs
+ other_callers = other.callers
 
 for key in other_counts.keys():
***************
*** 225,235 ****
 calledfuncs[key] = 1
 
 def write_results(self, show_missing=True, summary=False, coverdir=None):
 """
 @param coverdir
 """
! for filename, modulename, funcname in self.calledfuncs.keys():
! print ("filename: %s, modulename: %s, funcname: %s"
! % (filename, modulename, funcname))
 
 # turn the counts data ("(filename, lineno) = count") into something
--- 235,267 ----
 calledfuncs[key] = 1
 
+ for key in other_callers.keys():
+ callers[key] = 1
+ 
 def write_results(self, show_missing=True, summary=False, coverdir=None):
 """
 @param coverdir
 """
! if self.calledfuncs:
! print "functions called:"
! calls = self.calledfuncs.keys()
! calls.sort()
! for filename, modulename, funcname in calls:
! print ("filename: %s, modulename: %s, funcname: %s"
! % (filename, modulename, funcname))
! 
! if self.callers:
! print "calling relationships:"
! calls = self.callers.keys()
! calls.sort()
! lastfile = lastcfile = ""
! for ((pfile, pmod, pfunc), (cfile, cmod, cfunc)) in calls:
! if pfile != lastfile:
! print "***", pfile, "***"
! lastfile = pfile
! lastcfile = ""
! if cfile != pfile and lastcfile != cfile:
! print " -->", cfile
! lastcfile = cfile
! print " %s.%s -> %s.%s" % (pmod, pfunc, cmod, cfunc)
 
 # turn the counts data ("(filename, lineno) = count") into something
***************
*** 287,291 ****
 # try and store counts and module info into self.outfile
 try:
! pickle.dump((self.counts, self.calledfuncs),
 open(self.outfile, 'wb'), 1)
 except IOError, err:
--- 319,323 ----
 # try and store counts and module info into self.outfile
 try:
! pickle.dump((self.counts, self.calledfuncs, self.callers),
 open(self.outfile, 'wb'), 1)
 except IOError, err:
***************
*** 393,398 ****
 
 class Trace:
! def __init__(self, count=1, trace=1, countfuncs=0, ignoremods=(),
! ignoredirs=(), infile=None, outfile=None):
 """
 @param count true iff it should count number of times each
--- 425,430 ----
 
 class Trace:
! def __init__(self, count=1, trace=1, countfuncs=0, countcallers=0,
! ignoremods=(), ignoredirs=(), infile=None, outfile=None):
 """
 @param count true iff it should count number of times each
***************
*** 420,424 ****
 self.trace = trace
 self._calledfuncs = {}
! if countfuncs:
 self.globaltrace = self.globaltrace_countfuncs
 elif trace and count:
--- 452,459 ----
 self.trace = trace
 self._calledfuncs = {}
! self._callers = {}
! if countcallers:
! self.globaltrace = self.globaltrace_trackcallers
! elif countfuncs:
 self.globaltrace = self.globaltrace_countfuncs
 elif trace and count:
***************
*** 472,475 ****
--- 507,537 ----
 return result
 
+ def globaltrace_trackcallers(self, frame, why, arg):
+ """Handler for call events.
+ 
+ Adds information about who called who to the self._callers dict.
+ """
+ if why == 'call':
+ # XXX Should do a better job of identifying methods
+ code = frame.f_code
+ filename = code.co_filename
+ funcname = code.co_name
+ if filename:
+ modulename = modname(filename)
+ else:
+ modulename = None
+ this_func = (filename, modulename, funcname)
+ 
+ frame = frame.f_back
+ code = frame.f_code
+ filename = code.co_filename
+ funcname = code.co_name
+ if filename:
+ modulename = modname(filename)
+ else:
+ modulename = None
+ parent_func = (filename, modulename, funcname)
+ self._callers[(parent_func, this_func)] = 1
+ 
 def globaltrace_countfuncs(self, frame, why, arg):
 """Handler for call events.
***************
*** 545,549 ****
 return CoverageResults(self.counts, infile=self.infile,
 outfile=self.outfile,
! calledfuncs=self._calledfuncs)
 
 def _err_exit(msg):
--- 607,612 ----
 return CoverageResults(self.counts, infile=self.infile,
 outfile=self.outfile,
! calledfuncs=self._calledfuncs,
! callers=self._callers)
 
 def _err_exit(msg):
***************
*** 557,566 ****
 argv = sys.argv
 try:
! opts, prog_argv = getopt.getopt(argv[1:], "tcrRf:d:msC:l",
 ["help", "version", "trace", "count",
 "report", "no-report", "summary",
 "file=", "missing",
 "ignore-module=", "ignore-dir=",
! "coverdir=", "listfuncs",])
 
 except getopt.error, msg:
--- 620,630 ----
 argv = sys.argv
 try:
! opts, prog_argv = getopt.getopt(argv[1:], "tcrRf:d:msC:lT",
 ["help", "version", "trace", "count",
 "report", "no-report", "summary",
 "file=", "missing",
 "ignore-module=", "ignore-dir=",
! "coverdir=", "listfuncs",
! "trackcalls"])
 
 except getopt.error, msg:
***************
*** 581,584 ****
--- 645,649 ----
 summary = 0
 listfuncs = False
+ countcallers = False
 
 for opt, val in opts:
***************
*** 591,594 ****
--- 656,663 ----
 sys.exit(0)
 
+ if opt == "-T" or opt == "--trackcalls":
+ countcallers = True
+ continue
+ 
 if opt == "-l" or opt == "--listfuncs":
 listfuncs = True
***************
*** 651,657 ****
 _err_exit("cannot specify both --listfuncs and (--trace or --count)")
 
! if not count and not trace and not report and not listfuncs:
! _err_exit("must specify one of --trace, --count, --report or "
! "--listfuncs")
 
 if report and no_report:
--- 720,726 ----
 _err_exit("cannot specify both --listfuncs and (--trace or --count)")
 
! if not (count or trace or report or listfuncs or countcallers):
! _err_exit("must specify one of --trace, --count, --report, "
! "--listfuncs, or --trackcalls")
 
 if report and no_report:
***************
*** 674,679 ****
 
 t = Trace(count, trace, countfuncs=listfuncs,
! ignoremods=ignore_modules, ignoredirs=ignore_dirs,
! infile=counts_file, outfile=counts_file)
 try:
 t.run('execfile(%r)' % (progname,))
--- 743,749 ----
 
 t = Trace(count, trace, countfuncs=listfuncs,
! countcallers=countcallers, ignoremods=ignore_modules,
! ignoredirs=ignore_dirs, infile=counts_file,
! outfile=counts_file)
 try:
 t.run('execfile(%r)' % (progname,))


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /