[Python-Dev] about line numbers

Vladimir Marangozov Vladimir.Marangozov@inrialpes.fr
Thu, 19 Aug 1999 20:09:26 +0100 (NFT)


[Tim, in an earlier msg]
> 
> Would be more valuable to rethink the debugger's breakpoint approach so that
> SET_LINENO is never needed (line-triggered callbacks are expensive because
> called so frequently, turning each dynamic SET_LINENO into a full-blown
> Python call;

Ok. In the meantime I think that folding the redundant SET_LINENO doesn't
hurt. I ended up with a patchlet that seems to have no side effects, that
updates the lnotab as it should and that even makes pdb a bit more clever,
IMHO.

Consider an extreme case for the function f (listed below). Currently,
we get the following:

-------------------------------------------
>>> from test import f
>>> import dis, pdb
>>> dis.dis(f)
          0 SET_LINENO          1

          3 SET_LINENO          2

          6 SET_LINENO          3

          9 SET_LINENO          4

         12 SET_LINENO          5
         15 LOAD_CONST          1 (1)
         18 STORE_FAST          0 (a)

         21 SET_LINENO          6

         24 SET_LINENO          7

         27 SET_LINENO          8
         30 LOAD_CONST          2 (None)
         33 RETURN_VALUE   
>>> pdb.runcall(f)
> test.py(1)f()
-> def f():
(Pdb) list 1, 20
  1  -> def f():
  2             """Comment about f"""
  3             """Another one"""
  4             """A third one"""
  5             a = 1
  6             """Forth"""
  7             "and pdb can set a breakpoint on this one (simple quotes)"
  8             """but it's intelligent about triple quotes..."""
[EOF]
(Pdb) step
> test.py(2)f()
-> """Comment about f"""
(Pdb) step
> test.py(3)f()
-> """Another one"""
(Pdb) step
> test.py(4)f()
-> """A third one"""
(Pdb) step
> test.py(5)f()
-> a = 1
(Pdb) step
> test.py(6)f()
-> """Forth"""
(Pdb) step
> test.py(7)f()
-> "and pdb can set a breakpoint on this one (simple quotes)"
(Pdb) step
> test.py(8)f()
-> """but it's intelligent about triple quotes..."""
(Pdb) step
--Return--
> test.py(8)f()->None
-> """but it's intelligent about triple quotes..."""
(Pdb) 
>>>
-------------------------------------------

With folded SET_LINENO, we have this:

-------------------------------------------
>>> from test import f
>>> import dis, pdb
>>> dis.dis(f)
          0 SET_LINENO          5
          3 LOAD_CONST          1 (1)
          6 STORE_FAST          0 (a)

          9 SET_LINENO          8
         12 LOAD_CONST          2 (None)
         15 RETURN_VALUE   
>>> pdb.runcall(f)
> test.py(5)f()
-> a = 1
(Pdb) list 1, 20
  1     def f():
  2             """Comment about f"""
  3             """Another one"""
  4             """A third one"""
  5  ->         a = 1
  6             """Forth"""
  7             "and pdb can set a breakpoint on this one (simple quotes)"
  8             """but it's intelligent about triple quotes..."""
[EOF]
(Pdb) break 7 
Breakpoint 1 at test.py:7
(Pdb) break 8
*** Blank or comment
(Pdb) step
> test.py(8)f()
-> """but it's intelligent about triple quotes..."""
(Pdb) step
--Return--
> test.py(8)f()->None
-> """but it's intelligent about triple quotes..."""
(Pdb) 
>>> 
-------------------------------------------

i.e, pdb stops at (points to) the first real instruction and doesn't step
trough the doc strings.

Or is there something I'm missing here?

-- 
       Vladimir MARANGOZOV          | Vladimir.Marangozov@inrialpes.fr
http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252

-------------------------------[ cut here ]---------------------------
*** compile.c-orig	Thu Aug 19 19:27:13 1999
--- compile.c	Thu Aug 19 19:00:31 1999
***************
*** 615,620 ****
--- 615,623 ----
  	int arg;
  {
  	if (op == SET_LINENO) {
+ 		if (!Py_OptimizeFlag && c->c_last_addr == c->c_nexti - 3)
+ 			/* Hack for folding several SET_LINENO in a row. */
+ 			c->c_nexti -= 3;
  		com_set_lineno(c, arg);
  		if (Py_OptimizeFlag)
  			return;