Python Errors
This page contains a listing of common errors students find in their code. Feel free to use this list as a reference, consulting it when you have trouble understanding what an error means.
Note that when something goes wrong while the Python interpreter runs your program, the interpreter will stop and will produce a stack trace (also known as a traceback) that lists all functions that were running when the error occurred.1
For example, say that the expression a + 1
is executed before a
has
been given a value.
Traceback (most recent call last): File "demo.py", line 1, in <module> NameError: name 'a' is not defined
The last line gives us the type of the error (in this case, NameError
),
along with a description. On the second line, the stack trace lists the file
and line number the interpreter was running when it encountered the error.
Usually the error and description are enough to deduce what went wrong with
your program, but sometimes the description is confusing. If you’re not
sure what an error means, consult the following list.
SyntaxError
The most common type of error, a syntax error occurs when the interpreter
is reading the Python file to determine if it is valid Python code and
encounters something it doesn’t “understand”. The interpreter will check things
like indentation, use of parentheses and square brackets, proper forms
of if
, elif
, and else
blocks, and so on.
For example, here’s a simple file that has a syntax error. In this case, the
programmer has forgotten to add a closing square bracket to the definition of
the list lst
:
lst = [1, 2, 3 a = 2
When this is run by the Python interpreter, we get the following error message:
File "issue.py", line 2 a = 2 ^ SyntaxError: invalid syntax
After Python is done with the first line, it expects to keep reading elements
of lst
(i.e., it expects to see a ,
and then another number). However,
it sees that there is a variable assignment happening on the next line, and it
stops with a syntax error.
It’s important to realize that, due to the way Python reads through the file, the interpreter reports that the syntax error is on line 2. However, line 2 is correct, and the error is being caused by a missing square bracket on the previous line!
See the Python documentation for more details.
IndentationError
Python uses indentation to determine which lines of code belong to other
lines. For example, since it is possible to have many different function
definitions in a Python file, the lines of code that belong to one function
must be indented below the line containing def
and the function’s name:
def my_function(): print('note that these lines') print('are indented four spaces') print('from the def line')
In the example above (and in general), we can refer to the lines that
have been indented under the def
line to be children of the def
line. Similarly, the def
line is considered to be the parent of
the lines indented underneath it. Here’s an illustrated example, which
shows the parent/child relationships of each line:
All of the lines indented under the def
line are children of the def
line, with the exception of the lines indented deeper.
The print("I can't believe it!")
call is a child of the if
line.
The print('Me, too!')
line is a child of the else
line.
unindent does not match any outer indentation level
Before Python runs any code in your program, it will first determine the
correct parent and children of each line. Python produces
an IndentationError
whenever it comes across a line for which it
cannot determine the right parent to assign. For example:
def bad_indentation(num): if num < 10: a = 10 b = 5
This code causes Python to output the following:
File "<stdin>", line 4 b = 5 ^ IndentationError: unindent does not match any outer indentation level
Since the line containing b = 5
only has six spaces before it, Python
couldn’t determine whether that line’s parent was the if
line or
the def
line.
To fix this, either push the b = 5
line to the right two spaces (to place
it under the if
line) if you want it to run only when the condition is
true, or pull the line to the left two spaces (to place it outside
the if
entirely) to make it run whether the condition is true or not.
expected an indented block
Lines that begin with def
or if
(for example) must have at least
one child. This means that a function must have at least one line of code.
It also means that a conditional must have at least one line of code to
run if the condition is true. Take, for example, the following incorrect
function:
def missing_block(num): if num > 10: elif num % 2 == 1: print("number can't be odd!")
Python produces the following output when the file containing this incorrect function is read:
File "example.py", line 4 elif num % 2 == 1: ^ IndentationError: expected an indented block
After Python reads the if
line, it expects to see at least one child
line following it. However, since the next non-empty line it reads
is the elif
line, and that line’s parent is the def
line,
the if
line has no children, and Python reports that it expected some
indented lines.
To fix this, either place at least one line of code as the if
‘s child,
or remove the if
entirely. The same applies for any other type of
line that must have at least one child (e.g., a def
or for
).
This error can also come up if the programmer forgets to indent a docstring. Docstrings must be in line with the rest of the code in a function. To fix this issue, indent the docstring.
unexpected indent
Python will also produce an IndentationError
when it reads a line
that is indented as if the line had some parent line, but Python couldn’t
find any lines above to be its parent. A common special case of this
indentation issue occurs when a line is indented by one or more
spaces more than the previous line, and the previous line isn’t
a def
, if
, elif
, else
, for
, or while
line (the kinds of
lines that need children).
This often occurs by accident, if the programmer puts one too many spaces before a line. It can also happen when a docstring is placed on a different indentation level than the code inside of a function — to fix this, make sure the docstring is in line with the rest of the function’s code.
NameError
This error occurs when a name (a variable or function name) is used that Python does not know about. It can occur if a programmer changes a variable’s name but forgets to update the name everywhere in the Python file.
It can also occur in IDLE when a programmer is writing a Python file containing functions, and the programmer tries to access the functions from the shell without first pressing F5 or choosing “Run Module” from the Run menu.
It can also occur as the result of inconsistent indentation. For example:
def length(x): if x == '': return 0 else: return 1 + length(x[1:]) def caps(s): if s == '': return '' elif s[0] in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ': return 1 + caps(s[1:]) else: return caps(s[1:])
You might expect that the function caps()
could be accessed from the shell.
However, the shell doesn’t know any function with the name caps()
, because
it’s defined inside the length()
function. To fix this, the entire
definition of the caps()
function should be shifted left by four spaces.
It’s worth noting that it is sometimes useful to define functions inside of
functions, especially if the outer function needs to return a function.
However, in the example above, we want length()
and caps()
to be two,
unrelated functions.
description |
meaning |
---|---|
|
on this line, the variable name |
See the Python documentation for more details.
TypeError
This error occurs when a function or operator cannot be applied to the given values, due to the fact that the value’s type is inappropriate. This can happen when two incompatible types are used together, for example:
>>> "a" + 2 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Can't convert 'int' object to str implicitly
The TypeError
is generated because addition (+
) does not work between
an integer and a string. However, note the description: it suggests a
way to fix this error.
>>> "a" + str(2) 'a2'
This might not have been what the programmer intended, which is why Python
stopped with a TypeError
in the first place.
TypeError
can come up in a variety of places, but it usually appears when
a programmer’s assumption about the type of a value is incorrect (e.g.,
trying to manipulate an integer as if it were a list). The best way to
diagnose these problems is to use Python’s built-in type()
function to
determine the type of the problematic variable’s value.
description |
meaning |
---|---|
|
square brackets ( |
|
similar to above; |
|
the |
|
this “unsupported operand type” error
is very common, and is comes from the
use of the |
|
exactly the same error as above, except the list is on the left and the integer is on the right; see the special note about this below |
|
in a list comprehension, a non-sequence
was used after the |
|
same as above, only where the value
after the |
|
the |
|
a relational operator like |
See the Python documentation for more details.
Issues when using the +
operator
A common mistake made by beginning programmers is to use the +
operator
between values of incompatible types. For example, this straightforward
use of +
is just fine:
>>> 4 + 5 9
Let’s step through Python’s interpretation of this line. It first reads
through the entire line and notices a use of +
. It then considers the
type of 4
, which is int
, and the type of 5
, which is int
. Since
both numbers are the same type, and +
is supported between int
s,
Python uses integer addition and comes up with 9
.
However, take the following piece of code as an example:
>>> 0 + [1, 2, 3]
Python reads through the entire line and notices a use of +
. It will
consider the type of the left operand, 0
and conclude that it is an
int
. It then considers the type of the right operand, which is
list
. Python then produces an error, because it does not know how to
add int
and list
. To be clear, Python will produce the following
TypeError
:
Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unsupported operand type(s) for +: 'int' and 'list'
A slightly different error can be produced if the list is on the left and the non-list is on the right:
>>> [0] + 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can only concatenate list (not "int") to list
In general, Python only knows how to use +
between two operands
of the same type.2 So, how do we fix this? We should “wrap” the
single int
with square brackets to put it inside of a new list.
Then Python will be able to use +
between two operands of the same
type (list
!). Remember that, in this case, +
between two lists
will perform list concatenation: it will connect the two lists
together:
>>> [0] + [1, 2, 3] [0, 1, 2, 3]
Unexpected uses of None
(NoneType
)
Another common mistake occurs when programmers use the return value of a function they expect to return a string or integer value (for example), but Python outputs an error like the following:
Traceback (most recent call last): File "test.py", line 3, in outer_function return x + 1 TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
Often, the source of this problem is a function that returns None
,
when some non-None
value was expected. A function will return None
when...
- Python executes a
return
line that doesn’t specify a value or variable’s value to return (i.e., justreturn
by itself). In this case, the function will returnNone
. - Python reaches the end of a function that does not have a
return
statement. In this case the function automatically returnsNone
.
For example, take this function that, when given a number, returns ten times the number if the number is less than 10:
def mult_less_than_ten(n): if n < 10: return n * 10
The problem with this function is that it may not always return an integer
value. If we pass in a number greater than or equal to 10, Python reaches
the end of this function and automatically returns None
.
Aside
This kind of function is called a partial function. In other programming languages (Java, for example), partial functions are not allowed. In those languages, your code won’t even run if a function might not return anything!
Python will not alert you to the fact that the function may not always return an integer; it usually becomes a problem when some other code makes use of this function.
def get_and_add_five(): num = int(input('Enter an integer: ')) num2 = mult_less_than_ten(num) return num2 + 5
What happens if the user enters a number greater than ten?
The mult_less_than_ten()
function will return None
.
Then None
comes back to the get_and_add_five()
function and is
stored in num2
. Python produces the error when it attempts to
add None
to 5.
IndexError
This error occurs when an index into a list or string is out of range.
For example, attempting my_list[2]
when the list my_list
has zero,
one, or two elements will produce an IndexError
. This will also
occur in the same way with strings.
Note that empty lists (i.e., []
) and empty strings (i.e., ''
or ""
)
do not have an element or character at position 0. Attempting to index
0 with empty lists or strings will result in an IndexError
. To determine
if a variable contains the empty string or the empty list, try a direct
comparison to ''
or []
(i.e., s == ''
or lst == []
). You could also
use the len()
function, which returns 0 for empty sequences.
Note also that, when slicing a list or a string, IndexError
will
not be produced if any indices in the slice are out of bounds. See the
transcript below for examples of this:
>>> my_list = [1, 2] >>> my_list[:100] [1, 2] >>> my_list[100:] [] >>> my_list[100:200] []
description |
meaning |
---|---|
|
square brackets ( |
|
exactly the same problem as above, in the case of accessing an element of a list |
See the Python documentation for more details.
RuntimeError
This error can be triggered by many problems, but it is most notably produced when a stack overflow occurs. Take the following simple example of a recursive function that will never terminate:
def forever(): forever()
This function will fill up the Python interpreter’s stack until it runs
out of memory space for another call to forever()
. This can be seen
by the traceback that Python prints (note that there were many, many more
occurences of File "test.py", line 2, in forever
that were not
reproduced here, to save space):
... File "test.py", line 2, in forever forever() File "test.py", line 2, in forever forever() File "test.py", line 2, in forever forever() File "test.py", line 2, in forever forever() File "test.py", line 2, in forever forever() RuntimeError: maximum recursion depth exceeded
In addition, the description here is helpful. If a programmer encounters
RuntimeError
with the description maximum recursion depth exceeded
,
the recursive function is probably missing a base case. However, it can
still occur with a properly written recursive function, if that function
is given a very large input.
description |
meaning |
---|---|
|
the number of function calls made in a row is too high; this could be infinite recursion or a sign that the input data is too large; this usually means that the base case is not triggering or the recursive case does not break the problem down into a smaller problem |
See the Python documentation for more details.
ImportError
This error occurs when an import
statement is used, but Python cannot find
the Python module to import.
A common use of import
statements is to gain access to a function that
comes with Python, but isn’t available for use by default. For example, the
functions that produce random values or make random choices from lists
come from the random
module. To use them, you must put the following line
at the top of your file:
import random
After this line, you may use any function in the random
module
(e.g., choice()
) by putting random.
in front of the function’s name
(i.e., random.choice(...)
).
An ImportError
occurs when Python cannot find the module you want to
import. If you are trying to import a module that comes with Python
(e.g., random
, turtle
, or functools
), you may have misspelled the
module’s name.
If you are trying to import a module from a file that you wrote, or from files we supplied you, you must ensure that the files you are trying to import are in the same folder as the file that is doing the import.
See the Python documentation for more details.
AttributeError
This error occurs when you try to access an attribute of an object, but one of these two conditions hold:
-
The object does not have the specified attribute. This can happen if the object itself was never given the attribute (i.e., if the programmer forgot to initialize it in the
__init__()
function). If the object is a list, or some other object that did not come from a class you wrote, the attribute’s name is most likely misspelled.- If you aren’t sure whether you misspelled an attribute on a
built-in object type (e.g., a list), try calling the
help()
function on the variable referring to the object from the Python Shell. Thishelp()
function will list all of the object’s attributes. You can also review the relevant lecture notes or try a Google search for the attribute. - If the object was created from a class you wrote, find the
class definition and review the class’
__init__()
function. You should find the attribute’s correct name there. Or, you may find that you forgot to initialize the attribute.
- If you aren’t sure whether you misspelled an attribute on a
built-in object type (e.g., a list), try calling the
-
The object’s type is not what you expect. This often happens when you assume a variable contains a useful object (e.g., a list), but it actually contains
None
. (In that case, you’ll seeAttributeError: 'NoneType' object has no attribute '...'
.) Try to step back through your program to determine where the variable was set. Somewhere, the variable is being set toNone
. For more help withNone
, seeTypeError
.
Keep in mind that attributes can be both variables and methods.
In other words, you can get an AttributeError
when you try to
access a field of an object (i.e., a variable) that doesn’t exist,
or when you try to call a nonexistent method.
See the Python documentation for more details.
ZeroDivisionError
As it sounds, this error is produced when a division by zero occurs in your code. To avoid this error, you should make sure you have nonzero divisors before performing a division.
See the Python documentation for more details.
UnicodeDecodeError
This error occurs when Python is reading from a file that contains special characters. Special characters are letters or symbols that fall outside the common English alphabet and are not standard punctuation and numbers. For example, a lower case A with an acute accent (á) is a special character. Special characters also include “curly” single and double quotation marks and the ellipsis character (…).
A simple way to fix this error is to remove the special characters from
the file your program is reading. You can also add the encoding
parameter
with a value of 'utf-8'
to the open()
call you used to open the file.
For example, you could
use handle = open('filename.txt', 'r', encoding='utf-8')
. This causes
Python to recognize more kinds of characters when reading the file.
description |
meaning |
---|---|
|
the file your Python program is reading contains a special character, but Python cannot read the character |
Written by: Alexander Breen (CS111, Fall 2014, Spring 2015, Fall 2015, Spring 2016)
-
In this course, we will study the runtime stack in detail as part of the unit on machine organization. ↩
-
You might protest this if you’ve ever done
1.5 + 2
at the Python shell. Ultimately, however, Python is doing floating-point addition here. Python knows that it can convert2
to2.0
and then do1.5 + 2.0
to produce a floating-point result. ↩