The traceback of error generated by python interpreter can be sometimes long and not that useful. We might need to modify stack traces according to our need in some situations where we need more control over the amount of traceback getting printed. We might even need more control over the format of the trace getting printed. Python provides a module named traceback
which has a list of method which let us extract error traces, format it and print it according to our need. This can help with formatting and limiting error trace getting generated. As a part of this tutorial, we'll be explaining how we can use a different method of traceback module for different purposes. We'll explain the usage of the method with simple examples.
There is three kinds of methods available with the traceback module.
extract_*
methods. These methods can be useful if we want to print an error stack on some GUI.We'll now explain the usage of these methods with simple examples one by one.
As a part of our first example, we'll explain how we can print the stack trace of error using print_tb() method.
Below we have artificially tried to generate an error by giving randint() method of random module negative integer numbers. We have the first printed traceback generated by the python interpreter. Then we have caught exceptions using try-except block. We have then retrieved traceback from the error object using traceback attribute of the error object and have given it to print_tb() method which prints a stack trace.
Please make a note that print_tb() only prints stack trace and does not print actual exception type.
import random
out = random.randint(-5,-10)
import traceback
import random
try:
out = random.randint(-5,-10)
except Exception as e:
traceback.print_tb(e.__traceback__)
Below we have again executed code same as the previous cell but this time we have set the limit parameter to 1 hence it only prints the first trace frame.
import traceback
import random
try:
out = random.randint(-5,-10)
except Exception as e:
traceback.print_tb(e.__traceback__, limit=1)
As a part of this example, we have explained how we can direct the trace generated to a file. We have directed the error trace generated by the code to a file named traceback_ex1.out.
import traceback
import random
try:
out = random.randint(-5,-10)
except Exception as e:
traceback.print_tb(e.__traceback__, file=open("traceback_ex1.out", "w"))
!cat traceback_ex1.out
As a part of this example, we have introduced two other methods print_exception() and print_exc().
Please make a note that parameter limit, file, and chain are present in multiple methods of traceback module and it has the same meaning in all of them.
In this example, we have called method named exc_info() of sys module that returns tuple (exception type, exception value, exception traceback). This tuple has information about a recent exception that was caught by try-except block. We have then given this tuple to print_exception() method to print an error stack trace. We have directed stack trace to standard output in all of our examples.
Please make a note that when we used print_exception() method, it printed information about exceptions as well which was not getting printed with print_tb() method.
import traceback
import random
import sys
try:
out = random.randint(-5,-10)
except:
exc_type, exc_value, exc_traceback = sys.exc_info()
print("==================Traceback 1 =========================")
traceback.print_tb(exc_traceback, file=sys.stdout)
print("\n==================Traceback 2 ===================")
traceback.print_exception(exc_type, exc_value, exc_traceback, file=sys.stdout)
print("\n==================Traceback 3 ===================")
traceback.print_exc(file=sys.stdout)
As a part of our fourth example, we have demonstrated how we can catch the exception and print stack trace using print_exception() method. We have not retrieved exception information using sys.exc_info() this time. We have artificially generated divide by zero error in this example.
import traceback
import random
try:
out = 10/0
except Exception as e:
traceback.print_exception(type(e), e, e.__traceback__, file=sys.stdout)
We'll use our fifth example to demonstrate the usage of print_last() method.
We have first artificially generated error and then printed the error stack by calling print_last() method.
out = 10/0
traceback.print_last()
As a part of our sixth example, we'll demonstrate usage of extract_tb(), format_list() and print_list() methods.
Below we have first extracted the error stack using extract_tb() method and then printed it in different formats. We have also explained how we can use format_list() and print_list() methods. The StackSummary instance also has format() method which works exactly like format_list() method.
import traceback
import random
import sys
try:
out = random.randint(-5,-10)
except:
exc_type, exc_value, exc_traceback = sys.exc_info()
traces = traceback.extract_tb(exc_traceback)
print("Type of Traceback : ", type(traces))
print("Type of Individual Traces : ", type(traces[0]))
print(" \n========== Trace Format 1 ===============\n")
print("%50s | %10s | %5s | %10s" %("File Name", "Method Name", "Line Number", "Line"))
print("-"*100)
for frame_summary in traces:
print("%50s | %11s | %11d | %10s"%(frame_summary.filename, frame_summary.name, frame_summary.lineno, frame_summary.line))
print("-"*100)
print(" \n========== Trace Format 2 ===============\n")
for trace_line in traces.format():
print(trace_line)
print(" \n========== Trace Format 3 ===============\n")
for trace_line in traceback.format_list(traces):
print(trace_line)
print(" \n========== Trace Format 4 ===============\n")
traceback.print_list(traces, file=sys.stdout)
As a part of our seventh example, we'll explain usage of methods format_tb(), format_exception() and format_exc().
Below we have explained how we can use these methods with a simple example.
import traceback
import random
import sys
try:
out = random.randint(-5,-10)
except:
exc_type, exc_value, exc_traceback = sys.exc_info()
print("==================Traceback 1 =========================")
for trace in traceback.format_tb(exc_traceback):
print(trace)
print("\n==================Traceback 2 ===================")
for trace in traceback.format_exception(exc_type, exc_value, exc_traceback):
print(trace)
print("\n==================Traceback 3 ===================")
print(traceback.format_exc())
As a part of our eighth example, we'll demonstrate the usage of format_exception_only() method.
Below we have explained the usage of it with simple example.
import traceback
import random
try:
out = 10/0
except Exception as e:
for exception_line in traceback.format_exception_only(type(e), e):
print(exception_line)
As a part of our ninth example, we'll demonstrate the usage of walk_tb() and StackSummary.extract() methods.
The StackSummary class has another method named from_list(frame_summary_list) which takes as an input list of FrameSummary instances and generates StackSummary instance from it. It can also take a list of tuples (filename, line no, name, line) as input to generate the StackSummary instance.
Below we have explained how we can generate StackSummary instance from the frame generator generated by walk_tb() method. We have then formatted stack trace as well using the StackSummary instance.
import traceback
import random
import sys
try:
out = random.randint(-5,-10)
except Exception as e:
tbk = e.__traceback__
print("\n==================Traceback 1 ===================\n")
for frame in traceback.walk_tb(tbk):
print(frame)
print("\n==================Traceback 2 ===================\n")
stack_summary = traceback.StackSummary.extract(traceback.walk_tb(tbk))
print("%50s | %10s | %5s | %10s" %("File Name", "Method Name", "Line Number", "Line"))
print("-"*100)
for frame_summary in stack_summary:
print("%50s | %11s | %11d | %10s"%(frame_summary.filename, frame_summary.name, frame_summary.lineno, frame_summary.line))
print("-"*100)
As a part of our tenth example, we have demonstrated the usage of print_stack() method.
Below we have explained how we can use print_stack() method.
import traceback
import random
import sys
try:
out = random.randint(-5,-10)
except Exception as e:
tbk = e.__traceback__
while tbk:
print("Line No : ", tbk.tb_lineno)
#print("Frame : ", tbk.tb_frame)
print("========== Trace ==========")
traceback.print_stack(tbk.tb_frame, limit=1, file=sys.stdout)
print()
tbk = tbk.tb_next
As a part of our eleventh example, we have demonstrated the usage of format_stack() method.
Below we have explained the usage of format_stack() with a simple example that has code almost the same as print_stack() with minor changes.
import traceback
import random
import sys
try:
out = random.randint(-5,-10)
except Exception as e:
tbk = e.__traceback__
while tbk:
print("Line No : ", tbk.tb_lineno)
#print("Frame : ", tbk.tb_frame)
print("========== Trace ==========")
print(traceback.format_stack(tbk.tb_frame, limit=1)[0])
print()
tbk = tbk.tb_next
As a part of our twelfth example, we have demonstrated the usage of extract_stack() method.
We have explained the usage of extract_stack() with a simple example below. We can even generate StackSummary instance from the output of extract_stack() method.
import traceback
import random
import sys
try:
out = random.randint(-5,-10)
except Exception as e:
tbk = e.__traceback__
print("%50s | %10s | %5s | %10s" %("File Name", "Method Name", "Line Number", "Line"))
print("-"*100)
while tbk:
trace = list(traceback.extract_stack(tbk.tb_frame, limit=1))[0]
print("%50s | %11s | %11d | %10s"%(trace.filename, trace.name, trace.lineno, trace.line))
print("-"*100)
tbk = tbk.tb_next
As a part of our thirteenth and last example, we'll demonstrate the usage of walk_stack() method.
Below we have explained the usage of the method with simple example. We have first generated StackSummary instance from the output of walk_stack() method. We have then formatted the stack trace.
import traceback
import random
import sys
try:
out = random.randint(-5,-10)
except Exception as e:
tbk = e.__traceback__
print("%50s | %10s | %5s | %10s" %("File Name", "Method Name", "Line Number", "Line"))
print("-"*100)
while tbk:
stack_summary = traceback.StackSummary.extract(traceback.walk_stack(tbk.tb_frame))
for frame_summary in stack_summary[:1]:
print("%50s | %11s | %11d | %10s"%(frame_summary.filename, frame_summary.name, frame_summary.lineno, frame_summary.line))
print("-"*100)
tbk = tbk.tb_next
This ends our small tutorial explaining the usage of the traceback module. Please feel free to let us know your views in the comments section.
If you are more comfortable learning through video tutorials then we would recommend that you subscribe to our YouTube channel.
When going through coding examples, it's quite common to have doubts and errors.
If you have doubts about some code examples or are stuck somewhere when trying our code, send us an email at coderzcolumn07@gmail.com. We'll help you or point you in the direction where you can find a solution to your problem.
You can even send us a mail if you are trying something new and need guidance regarding coding. We'll try to respond as soon as possible.
If you want to