Save this as average.py and run it:
def average(total: float, count: int) -> float:
return total / count
print(average(12.0, 0))
Python stops and prints a traceback, its report of where the program failed and which calls led there:
Traceback (most recent call last):
File "average.py", line 5, in <module>
print(average(12.0, 0))
~~~~~~~^^^^^^^^^
File "average.py", line 2, in average
return total / count
~~~~~~^~~~~~~
ZeroDivisionError: division by zero
Python 3.15 printed this. Python 3.12 and 3.13 say float division by zero.
Read it from the bottom up
"Most recent call last" means the newest call is at the bottom, next to the error. Start there and work up.
- The last line names the exception and gives a message. An exception is
the object Python raises when something goes wrong, and
ZeroDivisionErroris its class. - The entry above it shows the line that raised it, line 2 in
average. The marks under the line point at the part that failed, the division. - Each entry higher up is a call that led there. It gives the file, the
line number and the function. Python prints the file's full path, which
this page shortens. The name
<module>means the top level of the file, outside any function. Line 5 calledaverage(12.0, 0)and passed the zero. - Decide what the program should do when
countis zero, such as reject the input or skip it. Changing the zero to a one hides the error and returns a wrong average.
Start from your own code
Often the bottom entries are inside a library, with paths into the standard
library or site-packages. The bug is usually in what your code passed in.
Find the lowest entry in a file you wrote, and check the values it passed.
Check your understanding
Your traceback ends inside json/decoder.py with JSONDecodeError: Expecting property name enclosed in double quotes. Where do you look first?
Show answer
Hide answer
Move up to the lowest entry in your own code, the line that called json.loads, and look at the text it passed. The json module is rarely the problem. JSON requires double quotes, so text such as {'a': 1} fails with exactly this message.
Check the name Python suggests
Some errors end with a guess:
NameError: name 'totl' is not defined. Did you mean: 'total'?
Python picks a name with almost the same spelling. Check that it is the one you meant, because two variables can have close names and different values.
A SyntaxError means nothing ran
A SyntaxError means Python could not read the file, so none of it ran.
You get no list of calls, only the line and a ^ where Python noticed the
problem. The message often names the cause, as in '[' was never closed.
When an import fails
Read the module name in the message. If import reporting fails with
No module named 'csv_helper', Python found reporting, and one of its own
imports failed.
If the missing module is a package you installed, you probably installed it
into another Python. Run python -m pip install <name> with the same python command that
runs your program. A bare pip can belong to another Python.
A file next to your script with the name of a standard module, such as
json.py or random.py, hides the real module. Python 3.13 and later add
"consider renaming" to the error. Python 3.12 only says the module has no
such attribute.
When a traceback holds more than one error
Later items in this track teach these. For now, learn to spot them.
- Python can join two tracebacks with "The above exception was the direct cause of the following exception:" or with "During handling of the above exception, another exception occurred:". Either line means one error led to another. The one above is the original failure, and often the one to fix. Keep the Original Error with raise from explains both lines.
- A traceback drawn with
|bars and numbered sections comes from an exception group, one exception that holds several errors. Read each numbered error. Report Several Errors at Once with ExceptionGroup teaches groups.
Lines after the error message are notes, which code adds with add_note():
ValueError: invalid literal for int() with base 10: 'unknown'
reading amount on row 2
So the last line is not always the exception. Look for the line that starts with the class name. Keep the Original Error with raise from shows how to add a note.
Going further
In a terminal, Python 3.13 and later print tracebacks in color. Set
PYTHON_COLORS=0 to turn color off, for example when the color codes
clutter a log file.