[Python-Dev] tests for standard library modules (original) (raw)

Vladimir Marangozov Vladimir.Marangozov@inrialpes.fr
Fri, 4 Aug 2000 00:25:38 +0200 (CEST)


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 , 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.PyCodeLine2Addr.funccode # some code object codeutil.PyCodeGetExecLines(co) [20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36] codeutil.PyCodeLine2Addr(co, 29) 173 codeutil.PyCodeAddr2Line(co, 173) 29 codeutil.PyCodeLine2Addr(co, 10) Traceback (innermost last): File "", 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