What Are Some Common Tracebacks in Python?
00:00 Knowing how to read a Python traceback when your program raises an exception can be very helpful when you’re programming, but knowing some of the more common tracebacks can also speed up the process.
00:10 In this lesson, you’ll learn about some common exceptions that you might come across, the reasons they get raised and what they mean, and the information that you can find in their tracebacks.
00:19
Let’s start with the AttributeError
. This is raised when you try to access an attribute on an object that doesn’t have the attribute defined.
00:26
The Python documentation defines this exception as being “raised when an attribute reference or assignment fails.” Let’s step through an example of the AttributeError
being raised.
00:37
Create an integer object called an_int
and give it the value of 1
. Then, try and access an attribute of the object that doesn’t exist.
00:46
The error message line for an AttributeError
tells you that this specific object type int
(integer) in this case, doesn’t have the attribute accessed, .an_attribute
in this case.
00:56
Seeing the AttributeError
in the error message line can help you quickly identify which attribute you attempted to access and where to go to fix it.
01:05 Most of the time, getting this exception indicates that you’re probably working with an object that isn’t the type that you were expecting. Let’s take another example.
01:14
We have an object called a_list
that contains the numbers 1
and 2
. You might be expecting this to be of type list
, which has a method called .append()
.
01:24
So if you try and call the .append()
method and add 3
to the list, you receive an AttributeError
exception that tells you you probably aren’t dealing with the type of object you’re expecting.
01:35
If you query the type of a_list
you can see it’s actually a tuple, not a list, as denoted by the round brackets. Often, this happens when you’re expecting an object to be returned from a function or method call to be of a specific type, and you end up with an object of type None
. In this case, the error message line will read 'NoneType' object has no attribute 'append'
.
01:57
The ImportError
is raised when something goes wrong with an import
statement. You’ll get this exception, or its subclass of ModuleNotFoundError
, if the module you’re trying to import can’t be found, or if you try to import something from a module that doesn’t exist in the module. The Python documentation defines this exception as being “raised when an import statement has troubles trying to load a module.
02:19
Also raised when the ‘from list’ in from ... import
has a name that cannot be found.”
02:25
Let’s look at an example of the ImportError
and the ModuleNotFoundError
being raised. Here, you can see that attempting to import a module that doesn’t exist, asdf
, results in the ModuleNotFoundError
.
02:37
If you attempt to import something that doesn’t exist, let’s say asdf
again, from a module that does exist—let’s use our greetings example, again—this results in an ImportError
. The error message lines at the bottom of the tracebacks tell you which thing couldn’t be imported, which again is asdf
.
02:54
The IndexError
is raised when you attempt to retrieve an index from a sequence, like a list or tuple, and the index isn’t found in the sequence.
03:03
The Python documentation states that this exception is “raised when a sequence subscript is out of range.” Let’s look at an example that raises an IndexError
. First, create a list with a couple of items in it.
03:15
Then, try and access an index in the list that doesn’t exist, like index 3
. The error message line for an IndexError
doesn’t give you great information.
03:23
You can see that you have a sequence reference that is out of range
and what the type of the sequence is, a list
in this case.
03:30
That information, combined with the rest of the traceback, is usually enough to help you quickly identify how to fix the issue. Next up, we have the KeyError
. Similar to the IndexError
, The KeyError
is raised when you attempt to access a key that isn’t in the mapping, usually a dictionary. Think of this as the IndexError
, but for dictionaries.
03:48
The Python documentation states that this exception is “raised when a mapping (dictionary) key is not found in the set of existing keys.” So, let’s look at an example of the KeyError
being raised. Firstly, create a new dictionary with two key-value pairs, 'a'
being 1
and 'c'
being 3
.
04:08
Then, try to access a key that doesn’t exist— for example, 'b'
. The error message line for the KeyError
gives you the key that could not be found. This isn’t much to go on, again, but if you combine it with the rest of the traceback, it’s usually enough to fix the issue. For an in-depth look at KeyError
, take a look at the Python KeyError
Exceptions and How to Handle Them course here on Real Python. Moving on to the NameError
.
04:33
This is raised when you have referenced a variable, module, class, function, or some other name that hasn’t been defined in your code. The Python documentation states that this exception is “raised when a local or global name is not found.” Let’s test this out. First, define a function called greet()
that takes in a parameter person
.
04:54
But in the function itself, we’ll misspell that parameter as persn
.
04:59
Then, call the function and pass it the value of 'World'
. The error message line in the NameError
traceback gives you the name that is missing. So in this example, it’s a misspelled variable or parameter to the function that was passed in. A NameError
would also be raised if it’s the parameter that you misspelled.
05:16
Let’s try this by defining our greet()
function again and misspelling the parameter. Then, try to call the function again. Here, it might seem as though you’ve done nothing wrong.
05:27
The last line that was executed and referenced in the traceback looks good. If you find yourself in this situation, then the thing to do is look through your code for where the person
variable is used and defined. Here, you can quickly see that the parameter name was misspelled.
05:43
The SyntaxError
is raised when you have incorrect Python syntax in your code. According to the Python documentation, this exception is “raised when the parser encounters a syntax error.”
05:55
We can demonstrate this by creating a function called greet()
, but missing off the colon that should be at the end of the function definition line. In the Python REPL, this SyntaxError
is raised right away after hitting Enter. The error message of the SyntaxError
only tells you that there was a problem with the syntax of your code. Looking into the lines above gives you the line with the problem, and usually a caret (^
) pointing to the problem spot. Here, as we know, the colon is missing from the function’s def
statement. Also, with SyntaxError
tracebacks, the regular first-line traceback—the one that states the most recent last call—is missing.
06:30
This is because the SyntaxError
is raised when Python attempts to parse your code and the lines aren’t actually being executed.
06:38
The TypeError
is raised when your code attempts to do something with an object that can’t do that thing, such as trying to add a string to an integer or calling the len()
(length) function on an object where its length isn’t defined. The Python documentation states that this exception is “raised when an operation or function is applied to an object of inappropriate type.” Let’s step through some more examples of the TypeError
.
07:01 Firstly, try and add a string to an integer.
07:05
This results in a TypeError
that does a pretty good job of informing you what’s wrong. Next, try to add an integer to a string.
07:14
This results in another TypeError
. However, it’s subtly different from the last one, as you can see from the error message line. For the last one, try to call the len()
function on an integer.
07:25 The error message line tells you that you can’t do that with an integer.
07:29
Next up, we have the ValueError
. This is raised when the value of the object is incorrect. You can think of this as similar to an IndexError
that’s raised because the value of an index isn’t in the range of the sequence, only the ValueError
is for a more generic case.
07:44
The Python documentation says that this exception is “raised when an operation or function receives an argument that has the right type but an inappropriate value, and the situation is not described by a more precise exception such as IndexError
.” A good way to demonstrate this one is by unpacking iterables into variables. Firstly, let’s try and unpack a
, b
, and c
variables into 1
and 2
.
08:10
So, here you’re trying to unpack too many variables. The error message line even tells you that you were expecting to unpack three values, but got two. And the opposite is true when you try to unpack too many values and there aren’t enough variables to unpack them into. So, you can see that the ValueError
error message line in both of these examples tells you exactly what the problem is with the values. So now you know about some of the more common tracebacks in Python and how you can work out where to look in your code to fix them. Coming up, you’ll learn how to hide unexpected tracebacks, and log them for later review.
Become a Member to join the conversation.
rolandgarceau on June 14, 2020
Make the links clickable