This is my patch
[ 587993 ] SET_LINENO killer
Remove SET_LINENO. Tracing is now supported by inspecting co_lnotab.
Many sundry changes to document and adapt to this change.
diff --git a/Lib/dis.py b/Lib/dis.py
index 2674094..a1cc215 100644
--- a/Lib/dis.py
+++ b/Lib/dis.py
@@ -55,6 +55,20 @@
def disassemble(co, lasti=-1):
"""Disassemble a code object."""
code = co.co_code
+
+ byte_increments = [ord(c) for c in co.co_lnotab[0::2]]
+ line_increments = [ord(c) for c in co.co_lnotab[1::2]]
+ table_length = len(byte_increments) # == len(line_increments)
+
+ lineno = co.co_firstlineno
+ table_index = 0
+ while (table_index < table_length
+ and byte_increments[table_index] == 0):
+ lineno += line_increments[table_index]
+ table_index += 1
+ addr = 0
+ line_incr = 0
+
labels = findlabels(code)
n = len(code)
i = 0
@@ -63,7 +77,23 @@
while i < n:
c = code[i]
op = ord(c)
- if op == SET_LINENO and i > 0: print # Extra blank line
+
+ if i >= addr:
+ lineno += line_incr
+ while table_index < table_length:
+ addr += byte_increments[table_index]
+ line_incr = line_increments[table_index]
+ table_index += 1
+ if line_incr:
+ break
+ else:
+ addr = sys.maxint
+ if i > 0:
+ print
+ print "%3d"%lineno,
+ else:
+ print ' ',
+
if i == lasti: print '-->',
else: print ' ',
if i in labels: print '>>',
@@ -224,6 +254,7 @@
def_op('INPLACE_OR', 79)
def_op('BREAK_LOOP', 80)
+def_op('RETURN_NONE', 81)
def_op('LOAD_LOCALS', 82)
def_op('RETURN_VALUE', 83)
def_op('IMPORT_STAR', 84)
@@ -277,9 +308,6 @@
def_op('DELETE_FAST', 126) # Local variable number
haslocal.append(126)
-def_op('SET_LINENO', 127) # Current line number
-SET_LINENO = 127
-
def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
def_op('CALL_FUNCTION', 131) # #args + (#kwargs << 8)
def_op('MAKE_FUNCTION', 132) # Number of args with default values
diff --git a/Lib/inspect.py b/Lib/inspect.py
index be2da41..96677b7 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -711,7 +711,7 @@
raise TypeError, 'arg is not a frame or traceback object'
filename = getsourcefile(frame) or getfile(frame)
- lineno = getlineno(frame)
+ lineno = frame.f_lineno
if context > 0:
start = lineno - 1 - context//2
try:
@@ -730,18 +730,8 @@
def getlineno(frame):
"""Get the line number from a frame object, allowing for optimization."""
- # Written by Marc-André Lemburg; revised by Jim Hugunin and Fredrik Lundh.
- lineno = frame.f_lineno
- code = frame.f_code
- if hasattr(code, 'co_lnotab'):
- table = code.co_lnotab
- lineno = code.co_firstlineno
- addr = 0
- for i in range(0, len(table), 2):
- addr = addr + ord(table[i])
- if addr > frame.f_lasti: break
- lineno = lineno + ord(table[i+1])
- return lineno
+ # FrameType.f_lineno is now a descriptor that grovels co_lnotab
+ return frame.f_lineno
def getouterframes(frame, context=1):
"""Get a list of records for a frame and all higher (calling) frames.
diff --git a/Lib/pdb.py b/Lib/pdb.py
index 3786ed9..c6164ad 100755
--- a/Lib/pdb.py
+++ b/Lib/pdb.py
@@ -105,7 +105,13 @@
if len(line) > 0 and line[0] != '#':
self.onecmd(line)
- # Override Bdb methods (except user_call, for now)
+ # Override Bdb methods
+
+ def user_call(self, frame, argument_list):
+ """This method is called when there is the remote possibility
+ that we ever need to stop in this function."""
+ print '--Call--'
+ self.interaction(frame, None)
def user_line(self, frame):
"""This function is called when we stop or break at this line."""
diff --git a/Lib/test/test_hotshot.py b/Lib/test/test_hotshot.py
index dad2bd4..d410099 100644
--- a/Lib/test/test_hotshot.py
+++ b/Lib/test/test_hotshot.py
@@ -91,10 +91,8 @@
f_lineno = f.func_code.co_firstlineno
g_lineno = g.func_code.co_firstlineno
events = [(ENTER, ("test_hotshot", g_lineno, "g")),
- (LINE, ("test_hotshot", g_lineno, "g")),
(LINE, ("test_hotshot", g_lineno+1, "g")),
(ENTER, ("test_hotshot", f_lineno, "f")),
- (LINE, ("test_hotshot", f_lineno, "f")),
(LINE, ("test_hotshot", f_lineno+1, "f")),
(LINE, ("test_hotshot", f_lineno+2, "f")),
(EXIT, ("test_hotshot", f_lineno, "f")),
diff --git a/Lib/traceback.py b/Lib/traceback.py
index c22f576..4910a37 100644
--- a/Lib/traceback.py
+++ b/Lib/traceback.py
@@ -59,7 +59,7 @@
n = 0
while tb is not None and (limit is None or n < limit):
f = tb.tb_frame
- lineno = tb_lineno(tb)
+ lineno = tb.tb_lineno
co = f.f_code
filename = co.co_filename
name = co.co_name
@@ -92,7 +92,7 @@
n = 0
while tb is not None and (limit is None or n < limit):
f = tb.tb_frame
- lineno = tb_lineno(tb)
+ lineno = tb.tb_lineno
co = f.f_code
filename = co.co_filename
name = co.co_name
@@ -263,7 +263,7 @@
list = []
n = 0
while f is not None and (limit is None or n < limit):
- lineno = f.f_lineno # XXX Too bad if -O is used
+ lineno = f.f_lineno
co = f.f_code
filename = co.co_filename
name = co.co_name
@@ -279,23 +279,6 @@
def tb_lineno(tb):
"""Calculate correct line number of traceback given in tb.
- Even works with -O on.
+ Obsolete in 2.3.
"""
- # Coded by Marc-Andre Lemburg from the example of PyCode_Addr2Line()
- # in compile.c.
- # Revised version by Jim Hugunin to work with JPython too.
-
- c = tb.tb_frame.f_code
- if not hasattr(c, 'co_lnotab'):
- return tb.tb_lineno
-
- tab = c.co_lnotab
- line = c.co_firstlineno
- stopat = tb.tb_lasti
- addr = 0
- for i in range(0, len(tab), 2):
- addr = addr + ord(tab[i])
- if addr > stopat:
- break
- line = line + ord(tab[i+1])
- return line
+ return tb.tb_lineno