views:

824

answers:

2

When A Python exception is thrown by code that spans multiple lines, e.g.:

   myfoos = [foo("bar",
                "baz",
                "quux",
                 i) for i in range(10)]

Python will report the line number of the last line, and will show the code fragment from that line:

Traceback (most recent call last):
  File "test.py", line 4, in <module>
    i) for i in range(10)]
NameError: name 'foo' is not defined

Is there any way to determine what the first line is? Is there any way to catch the exception and manipulate the traceback object to be able to report something like this instead:

Traceback (most recent call last):
 File "test.py", lines 1-4 in <module>
   myfoos = [foo("bar",
                "baz",
                "quux",
                 i) for i in range(10)]
 NameError: name 'foo' is not defined
A: 

In a try/except block you can except NameError and try setting NameError.lineno, though I'm not exactly sure if or how this works, but it's the best I've found thusfar.

try:
    somecode
except NameError
    NameError.lineno = [1,4]

You'll have to figure out where the statement begins and ends yourself somehow as well as which statement is raising the error.

Hope this helps

dragonjujo
The part I'm asking about is figuring out when the statement begins and ends.
lorin
+2  A: 

Finding the beginning of the line will be really hard. You'll have to either parse the Python or maybe dig into the compiled byte code. There are modules in the standard library for parsing Python, but I can tell you from experience that interpreting their output is a black art. And I'm not sure the compiled byte code has the answer either...

Ned Batchelder