Get Only the Last Items in a Traceback

gregpinero at gmail.com gregpinero at gmail.com
Tue Nov 6 23:53:31 EST 2007


On Sep 12, 10:35 am, Peter Otten <__pete... at web.de> wrote:
> Am Wed, 12 Sep 2007 15:09:02 +0000 schrieb gregpin... at gmail.com:
>
> > On Sep 12, 5:17 am, Peter Otten <__pete... at web.de> wrote:
>
> >> Your assessment is wrong. You only get the extra lines in the traceback if
> >> you don't immediately wrap the exec statement in a try ... except block:
> >> $ cat snip_traceback3.py
> >> import sys
> >> import traceback
>
> >> def alpha():
> >>     beta()
>
> >> def beta():
> >>     gamma()
>
> >> def gamma():
> >>     try:
> >>         exec s in {}
> >>     except Exception, e:
> >>         etype, value, tb = sys.exc_info()
> >>         traceback.print_exception(etype, value, tb.tb_next)
>
> >> s = """
> >> def delta():
> >>     epsilon()
>
> >> def epsilon():
> >>     1/0
> >> delta()
> >> """
>
> >> if __name__ == "__main__":
> >>     alpha()
>
> >> $ python snip_traceback3.py
> >> Traceback (most recent call last):
> >>   File "<string>", line 7, in <module>
> >>   File "<string>", line 3, in delta
> >>   File "<string>", line 6, in epsilon
> >> ZeroDivisionError: integer division or modulo by zero
>
> >> Heureka.
> > Thanks for the help, Peter.  That's exactly what I need.
>
> Indeed. But not exactly what you want, it seems.
>
> > Now could I
> > use your tb.tb_next trick a couple times and thus avoid moving the try/
> > except?
>
> Of course you can cut off the traceback at arbitrary positions. Here's an
> example that uses the filename:
>
> import traceback
> import sys
>
> def tb_filename(tb):
>     return tb.tb_frame.f_code.co_filename
>
> def tb_iter(tb):
>     while tb is not None:
>         yield tb
>         tb = tb.tb_next
>
> def alpha():
>     try:
>         beta()
>     except Exception, e:
>         etype, value, tb = sys.exc_info()
>         filename = tb_filename(tb)
>         for tb in tb_iter(tb):
>             if tb_filename(tb) != filename:
>                 break
>         traceback.print_exception(etype, value, tb)
>
> def beta():
>     gamma()
>
> def gamma():
>     exec s in {}
>
> s = """
> def delta():
>     epsilon()
>
> def epsilon():
>     1/0
> delta()
> """
>
> if __name__ == "__main__":
>     alpha()
>
> Did I mention it already? It's better to move the try ... except.
>
> Peter

This works great except for syntax errors.  Any idea why your solution
doesn't catch those?

Here's the output it gives me, followed by the code I'm using (running
in Python 2.5):

Traceback (most recent call last):
  File "traceback_test.py", line 27, in gamma
    exec s in {}
  File "<string>", line 6
     print hi'
             ^
 SyntaxError: EOL while scanning single-quoted string


file traceback_test.py contents:
import traceback
import sys

def tb_filename(tb):
    return tb.tb_frame.f_code.co_filename

def tb_iter(tb):
    while tb is not None:
        yield tb
        tb = tb.tb_next

def alpha():
    try:
        beta()
    except Exception, e:
        etype, value, tb = sys.exc_info()
        filename = tb_filename(tb)
        for tb in tb_iter(tb):
            if tb_filename(tb) != filename:
                break
        traceback.print_exception(etype, value, tb)

def beta():
    gamma()

def gamma():
    exec s in {}

s = """
def delta():
    epsilon()

def epsilon():
    print hi'
delta()
"""

if __name__ == "__main__":
    alpha()

-Greg




More information about the Python-list mailing list