The Python Traceback

The Python Traceback#

How often has your Python code “broken,” spitting out a long error message that you then completely ignore while going back to your code to make changes in a vain attempt to solve the problem as quickly as possible? Or perhaps you executed a piece of code and, upon seeing the error, turn to a friend or teacher, providing such “useful” information as: “help, my code doesn’t work!”

The error message you recieve from Python is providing useful information to identify the problem source, and after reading this page you should be able to utilize this to solve them more efficiently. Even if you can’t use the information to solve your problem directly, it is important to be able to communicate effectively about the problem when asking for help. For example, there is a big difference between asking someone for help by saying “my code is broken,” versus “I have an index error and I can’t figure out why it’s happening.”

Click –> Live Code on the top right corner of this screen and then execute the cells as you go through the page. In each case, see if you can fix the code (re-run the cell until the error is gone), as well as try to replicate the error with your own example.

The work on this page is derived from work that is Copyright © The Carpentries under CC BY 4.0. Specifically, material from this page was used.

Python Traceback#

The traceback is simply a listing and description of the sequence of function calls leading to an error; specifically, it will help identify exceptions that have been raised during code execution. Let’s take a look at one!

def favorite_ice_cream():
    ice_creams = [
        'chocolate',
        'vanilla',
        'strawberry'
    ]
    print(ice_creams[3])

favorite_ice_cream()
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[1], line 9
      2     ice_creams = [
      3         'chocolate',
      4         'vanilla',
      5         'strawberry'
      6     ]
      7     print(ice_creams[3])
----> 9 favorite_ice_cream()

Cell In[1], line 7, in favorite_ice_cream()
      1 def favorite_ice_cream():
      2     ice_creams = [
      3         'chocolate',
      4         'vanilla',
      5         'strawberry'
      6     ]
----> 7     print(ice_creams[3])

IndexError: list index out of range

This particular traceback has two levels. You can determine the number of levels by looking for the number of arrows on the left hand side. In this case:

  1. The first shows code from the cell above, with an arrow pointing to Line 11 (which is favorite_ice_cream()).

  2. The second shows some code in the function favorite_ice_cream, with an arrow pointing to Line 9 (which is print(ice_creams[3])).

The last level is the actual place where the error occurred. The other level(s) show what function the program executed to get to the next level down. So, in this case, the program first performed a function call to the function favorite_ice_cream. Inside this function, the program encountered an error on Line 6, when it tried to run the code print(ice_creams[3]).

Note

Sometimes, you might see a traceback that is very long – sometimes they might even be 20 levels deep! This can make it seem like something horrible happened, but the length of the error message does not reflect severity, rather, it indicates that your program called many functions before it encountered the error. Most of the time, the actual place where the error occurred is at the bottom-most level, so you can skip down the traceback to the bottom.

So what error did the program actually encounter? In the last line of the traceback, Python helpfully tells us the category or type of error (in this case, it is an IndexError) and a more detailed error message (in this case, it says “list index out of range”).

If you encounter an error and don’t know what it means, it is still important to read the traceback closely. That way, if you fix the error, but encounter a new one, you can tell that the error changed. Additionally, sometimes knowing where the error occurred is enough to fix it, even if you don’t entirely understand the message.

If you do encounter an error you don’t recognize, try looking at the official documentation on errors. However, note that you may not always be able to find the error there, as it is possible to create custom errors. In that case, hopefully the custom error message is informative enough to help you figure out what went wrong.

In general, we recommend you think through the following questions whenever reading a traceback:

Reading the Traceback (Error Messages)

Use the traceback to answer the following questions:

  1. How many levels does the traceback have?

  2. What is the function name where the error occurred?

  3. On which line number in this function did the error occur?

  4. What is the type of error?

  5. What is the error message?

Exercise#

After reading and executing the Python code and the resulting traceback, answer the following questions

  1. How many levels does the traceback have?

  2. What is the function name where the error occurred?

  3. On which line number in this function did the error occur?

  4. What is the type of error?

  5. What is the error message?

def print_message(day):
    messages = [
        'Hello, world!',
        'Today is Tuesday!',
        'It is the middle of the week.',
        'Today is Donnerstag in German!',
        'Last day of the week!',
        'Hooray for the weekend!',
        'Aw, the weekend is almost over.'
    ]
    print(messages[day])

def print_sunday_message():
    print_message(7)

print_sunday_message()
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[2], line 16
     13 def print_sunday_message():
     14     print_message(7)
---> 16 print_sunday_message()

Cell In[2], line 14, in print_sunday_message()
     13 def print_sunday_message():
---> 14     print_message(7)

Cell In[2], line 11, in print_message(day)
      1 def print_message(day):
      2     messages = [
      3         'Hello, world!',
      4         'Today is Tuesday!',
   (...)
      9         'Aw, the weekend is almost over.'
     10     ]
---> 11     print(messages[day])

IndexError: list index out of range

Complicated Tracebacks#

The examples above generate relatively simple tracebacks; however, when you are working on your own computer the “real” tracebacks may seem more complicated. Often this is simply because of the way Python files are stored in your computer. Although this online textbook is not the same as the Python distribution you have on your computer, we can get a sense of the problem by executing the cell below:

import numpy as np
x = np.array([5, 6, 7, 8])
np.this_method_does_not_exist_in_numpy
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[3], line 3
      1 import numpy as np
      2 x = np.array([5, 6, 7, 8])
----> 3 np.this_method_does_not_exist_in_numpy

File c:\Users\tomvanwoudenbe\Anaconda3\lib\site-packages\numpy\__init__.py:333, in __getattr__(attr)
    330     "Removed in NumPy 1.25.0"
    331     raise RuntimeError("Tester was removed in NumPy 1.25.")
--> 333 raise AttributeError("module {!r} has no attribute "
    334                      "{!r}".format(__name__, attr))

AttributeError: module 'numpy' has no attribute 'this_method_does_not_exist_in_numpy'

Can you answer the list of 5 questions for this traceback?

In addition, the location of the file where the exception was raised is given; it is quite long and (perhaps) unclear. This is simply the location where the Python file (numpy/__init__.py) responsible for code execution are stored in your internet browser (/lib/python/...). Note that __init__.py is used in every Python Package. Tou can see references to the method within numpy responsible for finding the numpy methods or attributes: __getattr__(attr). Finally, we can actually see how the exception is raised (we will learn about this later!): raise AttributeError....

Hopefully this explanation makes it easier for you to identify and solve exceptions when working with Python!