Reading a Traceback
Concepts covered: Functions
When a line raises an error that nothing handles, Python stops and prints a traceback: a report of where the program was when it failed. A new programmer sees a wall of text. The wall has 4 parts, and only 2 of them matter on a first read: the last line and the line above it.
price = 100
total = price * 1.08
print(totl)| Traceback line | What it tells you |
|---|---|
| Traceback (most recent call last): | A report follows; the frames are ordered so the one that failed comes last |
| File "main.py", line 3, in <module> | The file and the line number; <module> means top level, outside any def |
| print(totl) | The source text of that line, copied so the problem can be spotted without opening the file |
| NameError: name 'totl' is not defined | The error's name, a colon, then its message: what went wrong in Python's words |
Read it bottom up. The last line names the kind of failure and says which name was missing. The line above shows the code, where the misspelling is visible. Only then is the line number needed, to go and fix it. The first line is a fixed header and carries nothing specific to this failure.
The error name picks the category
The error's name sorts the failure into a category, and each category points at a different kind of fix. The message after the colon narrows it to the specific name, type or value involved.
| Error name | Python is saying | The usual cause |
|---|---|---|
| NameError | this name has never been assigned | a typo, a use above the assignment, or a missing import |
| TypeError | this operation does not work on these types | a str where a number was needed, often from input() |
| ValueError | the type is right and the content is wrong | int("ten") or int("3.5") |
| ZeroDivisionError | the right side of / was 0 | a count or a total that turned out empty |
| ModuleNotFoundError | no module with this name was found | a misspelled import, or a file in the wrong folder |
| IndentationError | the block structure cannot be parsed | a missing or an extra level of indentation |
More than one frame
When the failing line sits inside a def block, the traceback shows 2 frames: the call that started things, then the line inside the function that raised. Most recent call last means the frame at the bottom is the one that was running when the error happened.
def average(total, count):
return total / count
print(average(10, 0))| Traceback line | Frame |
|---|---|
| Traceback (most recent call last): | header |
| File "main.py", line 4, in <module> | frame 1: the call |
| print(average(10, 0)) | frame 1 source |
| File "main.py", line 2, in average | frame 2: inside average |
| return total / count | frame 2 source |
| ZeroDivisionError: division by zero | the error |
The bottom frame says line 2 divided by zero. The frame above explains why count was 0: line 4 passed it in. The fix belongs at line 4, or at whatever produced the 0, rather than at line 2, which did exactly what it was written to do. A traceback marks where the error surfaced; the cause can be any line that ran earlier.
What does the last line of this program's traceback say, and which line holds the mistake? Names assigned at the top of the file are visible inside the def.
rate = "0.08"
price = 200
def with_tax(amount):
return amount * (1 + rate)
print(with_tax(price))- NameError: name 'rate' is not defined, raised at line 5, because rate was assigned outside the def
- TypeError: unsupported operand type(s) for +: 'int' and 'str', raised at line 5; the mistake is on line 1, where rate is a string
- TypeError raised at line 7, because with_tax was called with an int instead of a float
- ValueError raised at line 1, because "0.08" cannot be stored in a variable
Errors with no traceback header
A SyntaxError or IndentationError appears before the program runs a single line, because Python reads the whole file first and couldn't parse it. The report skips the Traceback header, shows the file and line, the offending source, a caret under the point where parsing gave up, and the error name. There's no frame to list, since nothing was executing. A traceback with the header always means the file parsed and some line actually ran.
Practice
About this lesson
This section is part of the Python Foundations: Intermediate lesson on DataDriven, the home of data engineering. Lessons cover SQL, Python, Spark, data modeling and pipeline architecture, and each section pairs its explanation with worked examples and practice you run as you go.