Missing 'line' event when writing to frame.f_lineno in trace function
CTS
csamaras72 at gmail.com
Mon May 9 15:13:31 EDT 2011
Hello all,
I've been playing with sys.settrace() in an attempt to better
understand how trace functions (and debugging) work. I'm running
Python3.2 on Windows, which I installed by running the installer
package (i.e. I did not compile from source code).
Here's my code, some of which I borrowed from Pdb/Bdb. The trace
function basically prints out the event type, the filename, and the
line number, and asks the user what to do next. If "jump <line>" is
entered, <line> is written to frame.f_lineno before moving on.
Otherwise, we just move on to the next trace event.
# ---------- BEGIN tracing code -------------------
import sys
import __main__
import re
class Tracer:
def __init__( self, filename ):
__main__.__dict__.clear()
__main__.__dict__.update( {
"__name__": "__main__",
"__file__": filename,
"__builtins__": __builtins__, } )
with open( filename, "rb" ) as file:
code = compile( file.read(), filename, 'exec')
sys.settrace( self.trace )
exec( code, __main__.__dict__ )
def trace( self, frame, event, arg ):
filename = frame.f_code.co_filename
line = frame.f_lineno
prompt = event + " -> " + filename + "(" + str( line ) + "):"
action = input( prompt )
tokens = re.split( " +", action )
if tokens[ 0 ] == "jump":
frame.f_lineno = int( tokens[ 1 ] )
return self.trace
def run( filename ):
Tracer( filename )
# ---------- END end tracing code -------------
I start tracing a script's execution by typing the following at the
interactive prompt:
>>> import tracer
>>> tracer.run( "insert file name here" )
Given the following code,
# ----- BEGIN traced script ------
print( "Line 1" )
print( "Line 2" )
print( "Line 3" )
print( "Line 4" )
# ----- END traced script-------
... I get the following output if I just step though from beginning to
end:
# BEGIN output (no writes to frame.f_lineno)
C:\python_tests>python
Python 3.2 (r32:88445, Feb 20 2011, 21:29:02) [MSC v.1
32
Type "help", "copyright", "credits" or "license" for m
>>> import tracer
>>> tracer.run('just_prints.py')
call -> just_prints.py(1):
line -> just_prints.py(1):
call -> c:\python32\lib\encodings\cp437.py(18):
line -> c:\python32\lib\encodings\cp437.py(19):
return -> c:\python32\lib\encodings\cp437.py(19):
Line 1call -> c:\python32\lib\encodings\cp437.py(18):
line -> c:\python32\lib\encodings\cp437.py(19):
return -> c:\python32\lib\encodings\cp437.py(19):
line -> just_prints.py(2):
call -> c:\python32\lib\encodings\cp437.py(18):
line -> c:\python32\lib\encodings\cp437.py(19):
return -> c:\python32\lib\encodings\cp437.py(19):
Line 2call -> c:\python32\lib\encodings\cp437.py(18):
line -> c:\python32\lib\encodings\cp437.py(19):
return -> c:\python32\lib\encodings\cp437.py(19):
line -> just_prints.py(3):
call -> c:\python32\lib\encodings\cp437.py(18):
line -> c:\python32\lib\encodings\cp437.py(19):
return -> c:\python32\lib\encodings\cp437.py(19):
Line 3call -> c:\python32\lib\encodings\cp437.py(18):
line -> c:\python32\lib\encodings\cp437.py(19):
return -> c:\python32\lib\encodings\cp437.py(19):
line -> just_prints.py(4):
call -> c:\python32\lib\encodings\cp437.py(18):
line -> c:\python32\lib\encodings\cp437.py(19):
return -> c:\python32\lib\encodings\cp437.py(19):
Line 4call -> c:\python32\lib\encodings\cp437.py(18):
line -> c:\python32\lib\encodings\cp437.py(19):
return -> c:\python32\lib\encodings\cp437.py(19):
return -> just_prints.py(6):
>>>
# END output (no writes to frame.f_lineno)
So, as expected, I get "line" events for each of my script's lines,
and it appears that the print() built-in calls some helper functions
in lib\encodings\cp437.py, which is fine and explainable.
Now, if I try to jump to any line during the trace (in the following
output, after I'm done with line 3, I try to jump back to line 1 by
writing "1" to frame.f_lineno), I don't get the "line" event; instead
I go directly to the first "call" event of file cp437.py:
# BEGIN output (with a write to frame.f_lineno)
C:\python_tests>python
Python 3.2 (r32:88445, Feb 20 2011, 21:29:02) [MSC v.1500 32 bit (
32
Type "help", "copyright", "credits" or "license" for more informat
>>> import tracer
>>> tracer.run( 'just_prints.py')
call -> just_prints.py(1):
line -> just_prints.py(1):
call -> c:\python32\lib\encodings\cp437.py(18):
line -> c:\python32\lib\encodings\cp437.py(19):
return -> c:\python32\lib\encodings\cp437.py(19):
Line 1call -> c:\python32\lib\encodings\cp437.py(18):
line -> c:\python32\lib\encodings\cp437.py(19):
return -> c:\python32\lib\encodings\cp437.py(19):
line -> just_prints.py(2):
call -> c:\python32\lib\encodings\cp437.py(18):
line -> c:\python32\lib\encodings\cp437.py(19):
return -> c:\python32\lib\encodings\cp437.py(19):
Line 2call -> c:\python32\lib\encodings\cp437.py(18):
line -> c:\python32\lib\encodings\cp437.py(19):
return -> c:\python32\lib\encodings\cp437.py(19):
line -> just_prints.py(3):
call -> c:\python32\lib\encodings\cp437.py(18):
line -> c:\python32\lib\encodings\cp437.py(19):
return -> c:\python32\lib\encodings\cp437.py(19):
Line 3call -> c:\python32\lib\encodings\cp437.py(18):
line -> c:\python32\lib\encodings\cp437.py(19):
return -> c:\python32\lib\encodings\cp437.py(19):
line -> just_prints.py(4):jump 1 <=======
write to frame.f_lineno
call -> c:\python32\lib\encodings\cp437.py(18): <======= No "line"
event !!!!
line -> c:\python32\lib\encodings\cp437.py(19):
return -> c:\python32\lib\encodings\cp437.py(19):
Line 1call -> c:\python32\lib\encodings\cp437.py(18):
line -> c:\python32\lib\encodings\cp437.py(19):
return -> c:\python32\lib\encodings\cp437.py(19):
line -> just_prints.py(2):
# <snip>
# END output (with a write to frame.f_lineno)
The above behavior occurs both when I jump back, as well as forward in
a script. My questions to the group:
1) I was expecting a "line" event for line 1 of my traced script right
after I wrote "1" to frame.f_lineno, shouldn't that event have been
passed to my trace function?
2) Is there a way to get the missing "line" event by any means other
than by writing to frame.f_lineno?
My apologies for the lengthy message.
Thanks in advance for your insights,
-CTS
More information about the Python-list
mailing list