How Do You Read a Python Traceback?
00:00 The Python traceback contains a lot of helpful information when you’re trying to determine the reason for an exception being raised in your code. In this lesson, you’ll walk through different tracebacks in order to understand the different bits of information contained in a traceback.
00:14 There are several sections to every Python traceback that are important. In Python, it’s best to read the traceback from the bottom up. The last line of the traceback is the error message line.
00:24 It contains the exception name that was raised. After the exception name is the error message. This message usually contains helpful information for understanding the reason for the exception being raised. Further up the traceback are the various function calls moving from bottom to top, most recent to least recent.
00:41 These calls are represented by two-line entries for each call. The first line of each call contains information like the filename, line number, and module name, all specifying where the code can be found.
00:53 The second line for these calls contains the actual code that was executed. It’s worth noting here that if you’re used to seeing stack traces in other programming languages, then you’ll notice a major difference in the way that a Python traceback looks in comparison.
01:06 Most other languages print the exception at the top and then go from top to bottom, most recent call to least recent. Just to reiterate, a Python traceback should be read from bottom to top.
01:17 This is very helpful since the traceback is printed out and your terminal—or wherever you’re reading the traceback—usually ends up at the bottom of the output, giving you the perfect place to start reading the traceback.
01:27
There are a few differences between traceback output when you’re executing your code in the command line and running the code in the REPL. Let’s execute the same code in our REPL and have a look at the traceback output. Notice that in place of filenames, you get "<stdin>"
(standard in).
01:42 This makes sense since you type the code in through the standard input. Also, the executed lines of code are not displayed in the traceback. Going through some specific traceback output will help you better understand and see what information the traceback will give you.
01:57
You’ll use this code in the next few examples to illustrate the information a Python traceback gives you. Here, the who_to_greet()
function takes a value person
and either returns it or prompts for a value to return instead.
02:09
Then, greet()
takes a name to be greeted, someone
, and an optional greeting
value, and calls print()
. who_to_greet()
is also called with the someone
value passed in.
02:19
Finally, greet_many()
will iterate over the list of people and call greet()
. If there’s an exception raised by calling greet()
, then a simple backup greeting is printed.
02:29 This code doesn’t have any bugs that would result in an exception being raised as long as the right input is provided.
02:36
If you add a call to greet()
to the bottom of greetings.py
and specify a keyword argument that it isn’t expecting—for example, 'Chad'
and greeting
spelled greting
—and then run the script,
02:51
you’ll get this traceback. Once again, with a Python traceback, it’s best to work backward, moving up the output. Starting at the final line of the traceback, you can see that the exception was a TypeError
. The messages that follow the exception type, everything after the colon, give you some great information.
03:09
It tells you that greet()
was called with a keyword argument that it didn’t expect. The unknown argument name is also given to you. Moving up, you can see the line that resulted in the exception. In this case, it’s the greet()
call that you added to the bottom of greetings.py
.
03:24 The next line up gives you the path to the file where the code exists and the line number of that file where the code can be found, and which module it’s in.
03:32
In this case, because your code isn’t using any other Python modules, you just see <module>
here, meaning that this is the file that’s being executed. With a different file and different input, you can see the traceback really pointing you in the right direction to find the issue. If you’re following along, remove the buggy greet()
call from the bottom of greetings.py
and add this file to your directory. Here, you’ve set up another Python file that’s importing your previous module, greetings.py
, and using greet()
from it.
04:02
Here’s what happens if you now run example2.py
. The exception raised in this case is a TypeError
again, but this time the message is a little less helpful.
04:11
It tells you that somewhere in the code it was expecting to work with a string, but an integer was given. Moving up, you can see the line of code that was executed, then the file and line number of the code. This time, however, instead of <module>
, you get the name of the function that was being executed, greet()
.
04:27
Moving up to the next executed line of code, you can see your problematic greet()
call passing in an integer. Sometimes after an exception is raised, another bit of code catches the exception and also results in an exception.
04:40
In these situations, Python will output all exception tracebacks in the order in which they were received, once again ending in the most recently raised exception’s traceback. Since this can be a little confusing, let’s look at an example. Add a call to greet_many()
to the bottom of greetings.py
.
05:00 This should result in printing greetings to all three people. However, if you run this code, you’ll see an example of the multiple tracebacks being output.
05:09
Notice the line starting with During handling
in this output. In between all tracebacks, you’ll see this line. Its message is very clear: while your code was trying to handle the previous exception, another exception was raised. Note that Python’s feature of displaying the previous exceptions’ tracebacks were added in Python 3. In Python 2, you’ll only get the last exception’s traceback. You have seen this exception before, when you called greet()
with an integer.
05:37
Since you added a 1
to the list of people to greet, you can expect the same result. However, the function greet_many()
wraps the greet()
call in a try
and except
block. Just in case greet()
results in an exception being raised, greet_many()
wants to print a default greeting.
05:53
So when greet()
results in the TypeError
because of the bad integer input, greet_many()
handles that exception and attempts to print a simple greeting. Here, the code ends up resulting in another, similar, exception.
06:05 It’s still attempting to add a string and an integer. Seeing all of the traceback output can help you see what might be the real cause of an exception. Sometimes when you see the final exception raised, and its resulting traceback, you still can’t see what’s wrong. In those cases, moving up to previous exceptions usually gives you a better idea of the root cause.
06:26 So now you know how to read a Python traceback when your program raises an exception. Next up, you’ll learn about some of the more common tracebacks that you’ll see in Python.
Become a Member to join the conversation.