Get Only the Last Items in a Traceback

Peter Otten __peter__ at web.de
Wed Sep 12 11:35:53 EDT 2007


Am Wed, 12 Sep 2007 15:09:02 +0000 schrieb gregpinero 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



More information about the Python-list mailing list