473,382 Members | 1,594 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

Get Only the Last Items in a Traceback

I'm running code via the "exec in context" statement within a much
larger program. What I would like to do is capture any possible
errors and show a pretty traceback just like the Python interactive
interpreter does, but only show the part of the traceback relating to
the code sent to exec.

For example here is the code I'm using:

try:
exec code
except Exception,Err:
traceback.print_exc()

Which gives me something like this when it catches an exception:

Traceback (most recent call last):
File "/....py", line 843, in run
semi_safe_exec.safe_eval(code.replace('\r',''),con text,5)
File ".....py", line 400, in safe_eval
exec_timed(code, context, timeout_secs)
File ".....py", line 353, in exec_timed
exec code in context
File "<string>", line 7, in ?
File "<string>", line 5, in func2
File "<string>", line 2, in func1
ZeroDivisionError: integer division or modulo by zero

What I want to print instead is just something like:

Traceback (most recent call last):
File "<string>", line 7, in ?
File "<string>", line 5, in func2
File "<string>", line 2, in func1
ZeroDivisionError: integer division or modulo by zero

Thanks in advance for the help.

-Greg

P.S. if it matters, for this example, code in exec code is:

def func1():
print 7/0

def func2():
func1()

func2()

Sep 12 '07 #1
8 1970
Am Wed, 12 Sep 2007 02:09:28 +0000 schrieb gr********@gmail.com:
I'm running code via the "exec in context" statement within a much
larger program. What I would like to do is capture any possible
errors and show a pretty traceback just like the Python interactive
interpreter does, but only show the part of the traceback relating to
the code sent to exec.

For example here is the code I'm using:

try:
exec code
except Exception,Err:
traceback.print_exc()

Which gives me something like this when it catches an exception:

Traceback (most recent call last):
File "/....py", line 843, in run
semi_safe_exec.safe_eval(code.replace('\r',''),con text,5)
File ".....py", line 400, in safe_eval
exec_timed(code, context, timeout_secs)
File ".....py", line 353, in exec_timed
exec code in context
File "<string>", line 7, in ?
File "<string>", line 5, in func2
File "<string>", line 2, in func1
ZeroDivisionError: integer division or modulo by zero

What I want to print instead is just something like:

Traceback (most recent call last):
File "<string>", line 7, in ?
File "<string>", line 5, in func2
File "<string>", line 2, in func1
ZeroDivisionError: integer division or modulo by zero

Thanks in advance for the help.

-Greg

P.S. if it matters, for this example, code in exec code is:

def func1():
print 7/0

def func2():
func1()

func2()
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_traceback1.py
import traceback

def alpha():
try:
beta()
except Exception, e:
traceback.print_exc()

def beta():
gamma()

def gamma():
exec s in {}

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

def epsilon():
1/0
delta()
"""

if __name__ == "__main__":
alpha()

$ python snip_traceback1.py
Traceback (most recent call last):
File "snip_traceback1.py", line 5, in alpha
beta()
File "snip_traceback1.py", line 10, in beta
gamma()
File "snip_traceback1.py", line 13, in gamma
exec s in {}
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

So the first step is to move the try ... except closer to the exec:

$ cat snip_traceback2.py
import traceback

def alpha():
beta()

def beta():
gamma()

def gamma():
try:
exec s in {}
except Exception, e:
traceback.print_exc()

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

def epsilon():
1/0
delta()
"""

if __name__ == "__main__":
alpha()

$ python snip_traceback2.py
Traceback (most recent call last):
File "snip_traceback2.py", line 11, in gamma
exec s in {}
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

You are almost there. Now let's strip off the outermost traceback:

$ 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.

Peter
Sep 12 '07 #2
gr********@gmail.com wrote:
I'm running code via the "exec in context" statement within a much
larger program. What I would like to do is capture any possible
errors and show a pretty traceback just like the Python interactive
interpreter does, but only show the part of the traceback relating to
the code sent to exec.

For example here is the code I'm using:

try:
exec code
except Exception,Err:
traceback.print_exc()
Guess what's argument limit is for. Excerpt from the Python docs:

-------------------------------- snip --------------------------------
print_exc( [limit[, file]])
This is a shorthand for print_exception(sys.exc_type, sys.exc_value,
sys.exc_traceback, limit, file). (In fact, it uses sys.exc_info() to
retrieve the same information in a thread-safe way instead of using the
deprecated variables.)
-------------------------------- snip --------------------------------

Ciao, Michael.
Sep 12 '07 #3
Am Wed, 12 Sep 2007 11:21:48 +0200 schrieb Michael Ströder:
gr********@gmail.com wrote:
>I'm running code via the "exec in context" statement within a much
larger program. What I would like to do is capture any possible
errors and show a pretty traceback just like the Python interactive
interpreter does, but only show the part of the traceback relating to
the code sent to exec.

For example here is the code I'm using:

try:
exec code
except Exception,Err:
traceback.print_exc()

Guess what's argument limit is for. Excerpt from the Python docs:
Unfortunately traceback.print_exc(limit=N) trims the wrong end of the
traceback:
>>def alpha(): beta()
....
>>def beta(): gamma()
....
>>def gamma(): 1/0
....
>>try:
.... alpha()
.... except:
.... traceback.print_exc()
....
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "<stdin>", line 1, in alpha
File "<stdin>", line 1, in beta
File "<stdin>", line 1, in gamma
ZeroDivisionError: integer division or modulo by zero
>>try:
.... alpha()
.... except:
.... traceback.print_exc(limit=1)
....
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ZeroDivisionError: integer division or modulo by zero
>>>
Peter
Sep 12 '07 #4
On Sep 12, 5:17 am, Peter Otten <__pete...@web.dewrote:
>
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_traceback1.py
import traceback

def alpha():
try:
beta()
except Exception, e:
traceback.print_exc()

def beta():
gamma()

def gamma():
exec s in {}

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

def epsilon():
1/0
delta()
"""

if __name__ == "__main__":
alpha()

$ python snip_traceback1.py
Traceback (most recent call last):
File "snip_traceback1.py", line 5, in alpha
beta()
File "snip_traceback1.py", line 10, in beta
gamma()
File "snip_traceback1.py", line 13, in gamma
exec s in {}
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

So the first step is to move the try ... except closer to the exec:

$ cat snip_traceback2.py
import traceback

def alpha():
beta()

def beta():
gamma()

def gamma():
try:
exec s in {}
except Exception, e:
traceback.print_exc()

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

def epsilon():
1/0
delta()
"""

if __name__ == "__main__":
alpha()

$ python snip_traceback2.py
Traceback (most recent call last):
File "snip_traceback2.py", line 11, in gamma
exec s in {}
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

You are almost there. Now let's strip off the outermost traceback:

$ 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.

Peter
Thanks for the help, Peter. That's exactly what I need. Now could I
use your tb.tb_next trick a couple times and thus avoid moving the try/
except?

-Greg

Sep 12 '07 #5
Am Wed, 12 Sep 2007 15:09:02 +0000 schrieb gr********@gmail.com:
On Sep 12, 5:17 am, Peter Otten <__pete...@web.dewrote:
>>
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
Sep 12 '07 #6
On Sep 12, 11:35 am, Peter Otten <__pete...@web.dewrote:
Am Wed, 12 Sep 2007 15:09:02 +0000 schrieb gregpin...@gmail.com:
On Sep 12, 5:17 am, Peter Otten <__pete...@web.dewrote:
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 approach is ideal. Indirect, but ideal :-) I'll apply it
tonight.

It's complicated but suffice it to say it would be difficult to move
the try/except. Thanks for the help. Way to know about tracebacks,
very impressive!

-Greg

Sep 12 '07 #7
On Sep 12, 10:35 am, Peter Otten <__pete...@web.dewrote:
Am Wed, 12 Sep 2007 15:09:02 +0000 schrieb gregpin...@gmail.com:
On Sep 12, 5:17 am, Peter Otten <__pete...@web.dewrote:
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

Nov 7 '07 #8
En Wed, 07 Nov 2007 01:53:31 -0300, gr********@gmail.com
<gr********@gmail.comescribió:
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
Which would be your expected output?
Syntax errors happen when the code is *compiled*, before it gets executed.
You may catch syntax errors before even trying to execute the code, if you
do it in two steps:

try:
ccode = compile(s, filename, 'exec')
except SyntaxError:
...show the error appropiately...
...abort execution...
try:
exec ccode in {}
except Exception, e:
...handle exception...
--
Gabriel Genellina

Nov 10 '07 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Doug Farrell | last post by:
Hi everyone, I'm trying to build a program to interface to a SOAP/XML interface provided by one of our vendors. This interface is built with MS SOAP Toolkit 3.0, so I'm guessig they are running...
0
by: Christian Tismer | last post by:
Dear Python community, since I didn't get *any* reply to this request, either the request was bad or there is really nobody using f_tstate in a way that makes it urgent to keep. I will wait a...
11
by: Vani Murarka | last post by:
Hi Everyone, Does .NET offer any collection class which will give me objects last *accessed* such that I may build a least-recently-used cache that kills off objects that haven't been used for...
32
by: James Curran | last post by:
I'd like to make the following proposal for a new feature for the C# language. I have no connection with the C# team at Microsoft. I'm posting it here to gather input to refine it, in an "open...
3
by: Guoqi Zheng | last post by:
Sir, According to our design, very often, I need to have a different html code for the last row of our repeater control. I can not put those code difference into footer because those code has to...
5
by: Nathan Sokalski | last post by:
I have a control that I want displayed in all items except the last one. I figured the best way to do this was to determine whether the current item was the last from within the ItemDataBound event...
1
by: Kimmo Laine | last post by:
Hi! I need to resize the last column in my listview control so that there won´t be horizontal scrollbar. Lets first create lv and add some items: listView1.View = View.Details;
23
by: Florian Lindner | last post by:
Hello, can I determine somehow if the iteration on a list of values is the last iteration? Example: for i in : if last_iteration: print i*i else:
3
by: Koen Vossen | last post by:
A project I'm currently working on uses Turbogears as a framework. I'd like to interact with it using the tg-admin shell. We also use gettext's _() function for internationalization. Now, this...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.