This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Incorrect lineno's in code objects
Type: Stage:
Components: Interpreter Core Versions: Python 2.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: nnorwitz Nosy List: nnorwitz, twouters
Priority: high Keywords:

Created on 2006-06-26 16:01 by twouters, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
lineno.diff nnorwitz, 2006-07-13 05:59
Messages (6)
msg28929 - (view) Author: Thomas Wouters (twouters) * (Python committer) Date: 2006-06-26 16:01
The 2.5 compiler forgets how to count linenumbers in
certain situations:

>>> s255 = "".join(["\n"] * 255 + ["spam"])
>>> s256 = "".join(["\n"] * 256 + ["spam"])

>>> exec s255
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 256, in <module>
NameError: name 'spam' is not defined

>>> exec s256
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'spam' is not defined

Notice the 'line 1' linenumber in the case of 256 blank
lines. The same happens for 'pass' statements or 'if 0'
blocks instead of blank lines. The problem is in the
actual code objects created:

>>> dis.disco(compile(s255, "", "exec"))
256           0 LOAD_NAME                0 (spam)
              3 POP_TOP             
              4 LOAD_CONST               0 (None)
              7 RETURN_VALUE        
>>> dis.disco(compile(s256, "", "exec"))
  1           0 LOAD_NAME                0 (spam)
              3 POP_TOP             
              4 LOAD_CONST               0 (None)
              7 RETURN_VALUE        

msg28930 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2006-07-10 00:04
Logged In: YES 
user_id=33168

Committed revision 50500.
msg28931 - (view) Author: Thomas Wouters (twouters) * (Python committer) Date: 2006-07-12 13:11
Logged In: YES 
user_id=34209

Unfortunately, it isn't quite fixed. It's fixed for code in
the global scope, but not for functions:

>>> s255 = "def foo():\n " + "".join(["\n "] * 254 + ["
spam\n"])
>>> exec s255
>>> dis.dis(foo)
.256           0 LOAD_GLOBAL              0 (spam)
.              3 POP_TOP             
.              4 LOAD_CONST               0 (None)
.              7 RETURN_VALUE        

>>> s256 = "def foo():\n " + "".join(["\n "] * 255 + ["
spam\n"])
>>> exec s256
>>> dis.dis(foo)
.  1           0 LOAD_GLOBAL              0 (spam)
.              3 POP_TOP             
.              4 LOAD_CONST               0 (None)
.              7 RETURN_VALUE        

I haven't tried figuring out for what else it's broken like
this, sorry :)
msg28932 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2006-07-13 05:59
Logged In: YES 
user_id=33168

Try the attached patch on for size.  Let me know if you can
find any other holes.
msg28933 - (view) Author: Thomas Wouters (twouters) * (Python committer) Date: 2006-07-13 09:58
Logged In: YES 
user_id=34209

Yep, the patch seems to work, also for the other case
someone pointed out to me, that was still broken after the
last fix:

>>> exec "import os\ns='''" + "\n"*256 + "'''\n1/0\n"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero

I tried a couple of other ways to get large linenumbers and
complex(er) parsing structures, and they all seem to work right.
msg28934 - (view) Author: Neal Norwitz (nnorwitz) * (Python committer) Date: 2006-07-16 01:51
Logged In: YES 
user_id=33168

Committed revision 50673.

Hopefully I'm really done this time. :-)
History
Date User Action Args
2022-04-11 14:56:18adminsetgithub: 43555
2006-06-26 16:01:55twouterscreate