⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trace.py

📁 这个是内存数据库中的一个管理工具
💻 PY
📖 第 1 页 / 共 3 页
字号:
                lines_hit[lineno] = self.counts[(filename, lineno)]        # there are many places where this is insufficient, like a blank        # line embedded in a multiline string.        blank = re.compile(r'^\s*(#.*)?$')        # accumulate summary info, if needed        sums = {}        # generate file paths for the coverage files we are going to write...        fnlist = []        tfdir = tempfile.gettempdir()        for key in per_file.keys():            filename = key            # skip some "files" we don't care about...            if filename == "<string>":                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"):                filename = filename[:-1]            if coverdir:                thiscoverdir = coverdir            else:                thiscoverdir = os.path.dirname(os.path.abspath(filename))            # the code from here to "<<<" is the contents of the `fileutil.make_dirs()' function in the Mojo Nation project.  --Zooko 2001-10-14            # http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/mojonation/evil/common/fileutil.py?rev=HEAD&content-type=text/vnd.viewcvs-markup            tx = None            try:                os.makedirs(thiscoverdir)            except OSError, x:                tx = x            if not os.path.isdir(thiscoverdir):                if tx:                    raise tx                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...            # <<<            # build list file name by appending a ".cover" to the module name            # and sticking it into the specified directory            if "." in modulename:                # A module in a package                finalname = modulename.split(".")[-1]                listfilename = os.path.join(thiscoverdir, finalname + ".cover")            else:                listfilename = os.path.join(thiscoverdir, modulename + ".cover")            # Get the original lines from the .py file            try:                lines = open(filename, 'r').readlines()            except IOError, err:                sys.stderr.write("trace: Could not open %s for reading because: %s - skipping\n" % (`filename`, err))                continue            try:                outfile = open(listfilename, 'w')            except IOError, err:                sys.stderr.write(                    '%s: Could not open %s for writing because: %s" \                    "- skipping\n' % ("trace", `listfilename`, err))                continue            # If desired, get a list of the line numbers which represent            # executable content (returned as a dict for better lookup speed)            if show_missing:                executable_linenos = find_executable_linenos(filename)            else:                executable_linenos = {}            n_lines = 0            n_hits = 0            lines_hit = per_file[key]            for i in range(len(lines)):                line = lines[i]                # do the blank/comment match to try to mark more lines                # (help the reader find stuff that hasn't been covered)                if lines_hit.has_key(i+1):                    # count precedes the lines that we captured                    outfile.write('%5d: ' % lines_hit[i+1])                    n_hits = n_hits + 1                    n_lines = n_lines + 1                elif blank.match(line):                    # blank lines and comments are preceded by dots                    outfile.write('    . ')                else:                    # lines preceded by no marks weren't hit                    # Highlight them if so indicated, unless the line contains                    # '#pragma: NO COVER' (it is possible to embed this into                    # the text as a non-comment; no easy fix)                    if executable_linenos.has_key(i+1) and \                       string.find(lines[i],                                   string.join(['#pragma', 'NO COVER'])) == -1:                        outfile.write('>>>>>> ')                    else:                        outfile.write(' '*7)                    n_lines = n_lines + 1                outfile.write(string.expandtabs(lines[i], 8))            outfile.close()            if summary and n_lines:                percent = int(100 * n_hits / n_lines)                sums[modulename] = n_lines, percent, modulename, filename        if summary and sums:            mods = sums.keys()            mods.sort()            print "lines   cov%   module   (path)"            for m in mods:                n_lines, percent, modulename, filename = sums[m]                print "%5d   %3d%%   %s   (%s)" % sums[m]        if self.outfile:            # try and store counts and module info into self.outfile            try:                pickle.dump((self.counts, self.calledfuncs,), open(self.outfile, 'w'), 1)            except IOError, err:                sys.stderr.write("cannot save counts files because %s" % err)# Given a code string, return the SET_LINENO informationdef _find_LINENO_from_string(co_code):    """return all of the SET_LINENO information from a code string"""    import dis    linenos = {}    # This code was filched from the `dis' module then modified    n = len(co_code)    i = 0    prev_op = None    prev_lineno = 0    while i < n:        c = co_code[i]        op = ord(c)        if op == dis.SET_LINENO:            if prev_op == op:                # two SET_LINENO in a row, so the previous didn't                # indicate anything.  This occurs with triple                # quoted strings (?).  Remove the old one.                del linenos[prev_lineno]            prev_lineno = ord(co_code[i+1]) + ord(co_code[i+2])*256            linenos[prev_lineno] = 1        if op >= dis.HAVE_ARGUMENT:            i = i + 3        else:            i = i + 1        prev_op = op    return linenosdef _find_LINENO(code):    """return all of the SET_LINENO information from a code object"""    import types    # get all of the lineno information from the code of this scope level    linenos = _find_LINENO_from_string(code.co_code)    # and check the constants for references to other code objects    for c in code.co_consts:        if type(c) == types.CodeType:            # find another code object, so recurse into it            linenos.update(_find_LINENO(c))    return linenosdef find_executable_linenos(filename):    """return a dict of the line numbers from executable statements in a file    Works by finding all of the code-like objects in the module then searching    the byte code for 'SET_LINENO' terms (so this won't work one -O files).    """    import parser    assert filename.endswith('.py')    prog = open(filename).read()    ast = parser.suite(prog)    code = parser.compileast(ast, filename)    # The only way I know to find line numbers is to look for the    # SET_LINENO instructions.  Isn't there some way to get it from    # the AST?    return _find_LINENO(code)### XXX because os.path.commonprefix seems broken by my way of thinking...def commonprefix(dirs):    "Given a list of pathnames, returns the longest common leading component"    if not dirs: return ''    n = copy.copy(dirs)    for i in range(len(n)):        n[i] = n[i].split(os.sep)    prefix = n[0]    for item in n:        for i in range(len(prefix)):            if prefix[:i+1] <> item[:i+1]:                prefix = prefix[:i]                if i == 0: return ''                break    return os.sep.join(prefix)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 line is executed        @param trace true iff it should print out each line that is being counted        @param countfuncs true iff it should just output a list of (filename, modulename, funcname,) for functions that were called at least once;  This overrides `count' and `trace'        @param ignoremods a list of the names of modules to ignore        @param ignoredirs a list of the names of directories to ignore all of the (recursive) contents of        @param infile file from which to read stored counts to be added into the results        @param outfile file in which to write the results        """        self.pid = os.getpid()        self.infile = infile        self.outfile = outfile        self.ignore = Ignore(ignoremods, ignoredirs)        self.counts = {}   # keys are (filename, linenumber)        self.blabbed = {} # for debugging        self.pathtobasename = {} # for memoizing os.path.basename        self.donothing = 0        self.trace = trace        self._calledfuncs = {}        if countfuncs:            self.globaltrace = self.globaltrace_countfuncs        elif trace and count:            self.globaltrace = self.globaltrace_lt            self.localtrace = self.localtrace_trace_and_count        elif trace:            self.globaltrace = self.globaltrace_lt            self.localtrace = self.localtrace_trace        elif count:            self.globaltrace = self.globaltrace_lt            self.localtrace = self.localtrace_count        else:            # Ahem -- do nothing?  Okay.            self.donothing = 1    def run(self, cmd):        import __main__        dict = __main__.__dict__        if not self.donothing:            sys.settrace(self.globaltrace)        try:            exec cmd in dict, dict        finally:            if not self.donothing:                sys.settrace(None)    def runctx(self, cmd, globals=None, locals=None):        if globals is None: globals = {}        if locals is None: locals = {}        if not self.donothing:            sys.settrace(self.globaltrace)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -