Jeremy Hylton wrote: > > Skip's trace.py code coverage tool is now available in Tools/script. > You can use it to examine how much of a particular module is covered > by existing tests. Hmm. Glancing quickly at trace.py, I see that half of it is guessing line numbers. The same SET_LINENO problem again. This is unfortunate. But fortunately <wink>, here's another piece of code, modeled after its C counterpart, that comes to Skip's rescue and that works with -O. Example: >>> import codeutil >>> co = codeutil.PyCode_Line2Addr.func_code # some code object >>> codeutil.PyCode_GetExecLines(co) [20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36] >>> codeutil.PyCode_Line2Addr(co, 29) 173 >>> codeutil.PyCode_Addr2Line(co, 173) 29 >>> codeutil.PyCode_Line2Addr(co, 10) Traceback (innermost last): File "<stdin>", line 1, in ? File "codeutil.py", line 26, in PyCode_Line2Addr raise IndexError, "line must be in range [%d,%d]" % (line, lastlineno) IndexError: line must be in range [20,36] etc... -- Vladimir MARANGOZOV | Vladimir.Marangozov@inrialpes.fr http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252 ------------------------------[ codeutil.py ]------------------------- import types def PyCode_Addr2Line(co, addrq): assert type(co) == types.CodeType, \ "1st arg must be a code object, %s given" % type(co).__name__ if addrq < 0 or addrq > len(co.co_code): raise IndexError, "address must be in range [0,%d]" % len(co.co_code) addr = 0 line = co.co_firstlineno lnotab = co.co_lnotab for i in range(0, len(lnotab), 2): addr_incr = ord(lnotab[i]) line_incr = ord(lnotab[i+1]) addr = addr + addr_incr if (addr > addrq): break line = line + line_incr return line def PyCode_Line2Addr(co, lineq): assert type(co) == types.CodeType, \ "1st arg must be a code object, %s given" % type(co).__name__ line = co.co_firstlineno lastlineno = PyCode_Addr2Line(co, len(co.co_code)) if lineq < line or lineq > lastlineno: raise IndexError, "line must be in range [%d,%d]" % (line, lastlineno) addr = 0 lnotab = co.co_lnotab for i in range(0, len(lnotab), 2): if line >= lineq: break addr_incr = ord(lnotab[i]) line_incr = ord(lnotab[i+1]) addr = addr + addr_incr line = line + line_incr return addr def PyCode_GetExecLines(co): assert type(co) == types.CodeType, \ "arg must be a code object, %s given" % type(co).__name__ lastlineno = PyCode_Addr2Line(co, len(co.co_code)) lines = range(co.co_firstlineno, lastlineno + 1) # remove void lines (w/o opcodes): comments, blank/escaped lines i = len(lines) - 1 while i >= 0: if lines[i] != PyCode_Addr2Line(co, PyCode_Line2Addr(co, lines[i])): lines.pop(i) i = i - 1 return lines
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4