Tracing fIle path and line number

前端 未结 1 851
逝去的感伤
逝去的感伤 2021-01-14 08:17

I\'m using python\'s trace module to trace some code. When I trace code this way, I can get one of the following two results:

Call:

相关标签:
1条回答
  • 2021-01-14 09:16

    With a little monkey-patching, this is actually quite easy. Digging around in the source code of the trace module it seems that callbacks are used to report on each execution step. The basic functionality of Trace.run, greatly simplified, is:

    sys.settrace(globaltrace)   # Set the trace callback function
    exec function               # Execute the function, invoking the callback as necessary
    sys.settrace(None)          # Reset the trace
    

    globaltrace is defined in Trace.__init__ depending on the arguments passed. Specifically, with the arguments in your first example, Trace.globaltrace_lt is used as the global callback, which calls Trace.localtrace_trace for each line of execution. Changing it is simply a case of modifying Trace.localtrace, so to get the result you want:

    import trace
    import sys
    import time
    import linecache
    
    class Trace(trace.Trace):
        def localtrace_trace(self, frame, why, arg):
            if why == "line":
                # record the file name and line number of every trace
                filename = frame.f_code.co_filename
                lineno = frame.f_lineno
    
                if self.start_time:
                    print '%.2f' % (time.time() - self.start_time),
                print "%s (%d): %s" % (filename, lineno,
                                      linecache.getline(filename, lineno)),
            return self.localtrace
    
    
    tracer = Trace(count=False, trace=True, ignoredirs=[sys.prefix, sys.exec_prefix])
    r = tracer.run('run()')
    

    There is a difference between the two examples you give; if the first the output is printed during the Trace.run call, in the second it is printed during write_results. The code I've given above follows the pattern of the former, so tracer.results().write_results() is not necessary. However, if you want to manipulate this output instead it can be achieved by patching the trace.CoverageResults.write_results method in a similar manner.

    0 讨论(0)
提交回复
热议问题