Index: Tools/scripts/trace.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/trace.py,v retrieving revision 1.6 diff -u -d -r1.6 trace.py --- Tools/scripts/trace.py 28 Nov 2001 19:41:45 -0000 1.6 +++ Tools/scripts/trace.py 11 Apr 2002 16:29:06 -0000 @@ -1,5 +1,7 @@ #!/usr/bin/env python +__cvsid = '$Id$' + # portions copyright 2001, Autonomous Zones Industries, Inc., all rights... # err... reserved and offered to the public under the terms of the # Python 2.2 license. @@ -69,6 +71,8 @@ """ program/module to trace Python program or function execution +See usage string below for usage details. + Sample use, command line: trace.py -c -f counts --ignore-dir '$prefix' spam.py eggs trace.py -t --ignore-dir '$prefix' spam.py eggs @@ -98,6 +102,9 @@ def usage(outfile): outfile.write("""Usage: %s [OPTIONS] [ARGS] +Note that neither --trace nor --count work if the Python interpreter is in -O +(optimized) mode. + Meta-options: --help Display this help then exit. --version Output version information then exit. @@ -108,6 +115,9 @@ and write the counts to .cover for each module executed, in the module's directory. See also `--coverdir', `--file', `--no-report' below. +-l, --listfuncs Keep track of which functions are executed at least + once and write the results to sys.stdout after the the + program exits. -r, --report Generate a report from a counts file; do not execute any code. `--file' must specify the results file to read, which must have been created in a previous run @@ -201,10 +211,7 @@ # try and merge existing counts file try: thingie = pickle.load(open(self.infile, 'r')) - if type(thingie) is types.DictType: - # backwards compatibility for old trace.py after Zooko touched it but before calledfuncs --Zooko 2001年10月24日 - self.update(self.__class__(thingie)) - elif type(thingie) is types.TupleType and len(thingie) == 2: + if type(thingie) is types.TupleType and len(thingie) == 2: (counts, calledfuncs,) = thingie self.update(self.__class__(counts, calledfuncs)) except (IOError, EOFError,): @@ -220,9 +227,8 @@ other_counts = other.counts other_calledfuncs = other.calledfuncs - for key in other_counts.keys(): - if key != 'calledfuncs': # backwards compatibility for abortive attempt to stuff calledfuncs into self.counts, by Zooko --Zooko 2001年10月24日 - counts[key] = counts.get(key, 0) + other_counts[key] + for k, v in other_counts.items(): + counts[k] = counts.get(k, 0) + v for key in other_calledfuncs.keys(): calledfuncs[key] = 1 @@ -231,6 +237,8 @@ """ @param coverdir """ + # print "self.calledfuncs: %s, self.counts: %s" % (self.calledfuncs, self.counts,) + for (filename, modulename, funcname,) in self.calledfuncs.keys(): print "filename: %s, modulename: %s, funcname: %s" % (filename, modulename, funcname,) @@ -239,10 +247,9 @@ # accessible on a per-file basis per_file = {} for thingie in self.counts.keys(): - if thingie != "calledfuncs": # backwards compatibility for abortive attempt to stuff calledfuncs into self.counts, by Zooko --Zooko 2001年10月24日 - (filename, lineno,) = thingie - lines_hit = per_file[filename] = per_file.get(filename, {}) - lines_hit[lineno] = self.counts[(filename, lineno)] + (filename, lineno,) = thingie + lines_hit = per_file[filename] = per_file.get(filename, {}) + lines_hit[lineno] = self.counts[(filename, lineno)] # there are many places where this is insufficient, like a blank # line embedded in a multiline string. @@ -253,17 +260,14 @@ # generate file paths for the coverage files we are going to write... fnlist = [] - tfdir = tempfile.gettempdir() + # print "per_file.keys(): %s" % per_file.keys() + for key in per_file.keys(): filename = key # skip some "files" we don't care about... if filename == "": continue - # are these caused by code compiled using exec or something? - if filename.startswith(tfdir): - continue - modulename = inspect.getmodulename(filename) if filename.endswith(".pyc") or filename.endswith(".pyo"): @@ -285,6 +289,7 @@ if not os.path.isdir(thiscoverdir): if tx: raise tx + # print "raise exceptions.IOError, \"unknown error prevented creation of directory: %%s\" % %s" % thiscoverdir raise exceptions.IOError, "unknown error prevented creation of directory: %s" % thiscoverdir # careful not to construct an IOError with a 2-tuple, as that has a special meaning... # <<< @@ -297,6 +302,8 @@ else: listfilename = os.path.join(thiscoverdir, modulename + ".cover") + # print "listfilename: %s" % listfilename + # Get the original lines from the .py file try: lines = open(filename, 'r').readlines() @@ -534,6 +541,7 @@ """ Handles `call' events (why == 'call') and if the code block being entered is to be ignored then it returns `None', else it returns `self.localtrace'. """ + # print "%s.globaltrace_lt(%s, %s, %s)" % (self, frame, why, arg,) if why == 'call': (filename, lineno, funcname, context, lineindex,) = inspect.getframeinfo(frame, 0) # if DEBUG_MODE and not filename: @@ -594,16 +602,19 @@ return self.localtrace def localtrace_count(self, frame, why, arg): + # print "%s.localtrace_count(%s, %s, %s)" % (self, frame, why, arg,) if why == 'line': # XXX shouldn't do the count increment when arg is exception? But be careful to return self.localtrace when arg is exception! ? --Zooko 2001-10-14 # record the file name and line number of every trace # XXX I wish inspect offered me an optimized `getfilename(frame)' to use in place of the presumably heavier `getframeinfo()'. --Zooko 2001-10-14 (filename, lineno, funcname, context, lineindex,) = inspect.getframeinfo(frame) key = (filename, lineno,) + # print "self.counts[%s] = [self.counts.get(key, 0)==%s] + 1" % (key, self.counts.get(key, 0),) self.counts[key] = self.counts.get(key, 0) + 1 return self.localtrace def results(self): + # print "return CoverageResults(%s, infile=%s, outfile=%s, calledfuncs=%s)" % (self.counts, self.infile, self.outfile, self._calledfuncs,) return CoverageResults(self.counts, infile=self.infile, outfile=self.outfile, calledfuncs=self._calledfuncs) def _err_exit(msg): @@ -721,6 +732,15 @@ if no_report and len(prog_argv) == 0: _err_exit("missing name of file to run") + # Hopefully a future version of the Python interpreter will provide a `sys.optimized' constant or function. + if count or trace: + if hasattr(sys, 'optimized'): + if callable(sys.optimized): + if sys.optimized(): + _err_exit("can't use --trace or --count with optimized mode of Python interpreter") + elif sys.optimized: + _err_exit("can't use --trace or --count with optimized mode of Python interpreter") + # everything is ready if report: results = CoverageResults(infile=counts_file, outfile=counts_file) @@ -731,6 +751,7 @@ if eval(sys.version[:3])>1.3: sys.path[0] = os.path.split(progname)[0] # ??? + # print "t = Trace(%s, %s, countfuncs=%s, ignoremods=%s, ignoredirs=%s, infile=%s, outfile=%s)" % (count, trace, listfuncs, ignore_modules, ignore_dirs, counts_file, counts_file,) t = Trace(count, trace, countfuncs=listfuncs, ignoremods=ignore_modules, ignoredirs=ignore_dirs, infile=counts_file, outfile=counts_file) try: t.run('execfile(' + `progname` + ')') @@ -742,6 +763,7 @@ results = t.results() if not no_report: + # print "results.write_results(%s, summary=%s, coverdir=%s)" % (missing, summary, coverdir,) results.write_results(missing, summary=summary, coverdir=coverdir) if __name__=='__main__':

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