>I've been using pyunit for a while in jython and would like to
>have code coverage reports from some of the tests.
>I started from Skip Montanaro's code coverage module
>(http://musi-cal.mojam.com/~skip/python/trace.py) and found out
>that the biggest hurdle probably is obtaining line numbers that have code
>assigned to them. He uses the CPython parser to get actual lines
>from the SETLINENO instructions in CPython byte code.
>That won't work for jython, so I started piecing together a java class
>file disassembler in jython to find out how it's done in jython class files.
>I got to the point of disassembling individual
>instructions more or less correctly, and then I found out
>that setline() is called only at the beginning of each function,
>which is a showstopper in this case.
For dynamicly compiled python code, a call to PyFrame.setline(int) is
generated for each statement (including expr_stmt). Maybe the call to
setline is missing for some statement types, but it can't be that many.
>There is also a line number table, but I wouldn't know how
>to interpret this while the JVM is executing.
The line number table maps java bytecode PC addresses to source line
numbers, but as you say, it is useless while running since we don't have
access to the java bytecode PC.
But if all you need to know is whether a line have some executable
python code, then the line number table in the $py.class file can answer
that with the same certainty as the setline() method calls can.
Each time a call to PyFrame.setline() is generated, we also add a line
number entry to the line number table. See the Code.setline() for
>- Is there an option for jythonc to have setline() called for each line
> of jython code? I checked the sources a bit and even found the
> point at which the setline call is emitted for a jython function,
> but I got no further than that.
For jythonc? No.
>- Is line tracing implemented in jython? Function tracing works fine
> in the profiler, but line tracing is a bit more involved, and I did
> not check whether this can actually be done in jython.
Line tracing is implemented in dynamic compilation. Unless you have
discovered a bug of course. This works for me:
def tracer(frame, why, arg):
print why, frame.f_lineno, arg
for i in range(10):
a = "abc"
a = "Done"