7.6. Exception Traceback

  • Traceback will help you track down the bug

>>> raise RuntimeError
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError
>>> raise RuntimeError('Huston we have a problem')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: Huston we have a problem

7.6.1. Python 3.11

  • Since Python 3.11

  • PEP 657 -- Include Fine Grained Error Locations in Tracebacks

Traceback (most recent call last):
  File "calculation.py", line 54, in <module>
    result = (x / y / z) * (a / b / c)
              ~~~~~~^~~
ZeroDivisionError: division by zero
Traceback (most recent call last):
  File "distance.py", line 11, in <module>
    print(manhattan_distance(p1, p2))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "distance.py", line 6, in manhattan_distance
    return abs(point_1.x - point_2.x) + abs(point_1.y - point_2.y)
                           ^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'x'
Traceback (most recent call last):
  File "query.py", line 37, in <module>
    magic_arithmetic('foo')
  File "query.py", line 18, in magic_arithmetic
    return add_counts(x) / 25
           ^^^^^^^^^^^^^
  File "query.py", line 24, in add_counts
    return 25 + query_user(user1) + query_user(user2)
                ^^^^^^^^^^^^^^^^^
  File "query.py", line 32, in query_user
    return 1 + query_count(db, response['a']['b']['c']['user'], retry=True)
                               ~~~~~~~~~~~~~~~~~~^^^^^
TypeError: 'NoneType' object is not subscriptable

7.6.2. Traceback Analysis

  • Stacktrace is 8 levels deep, it's not Java's 200 ;)

  • Start analysing traceback from bottom-up

../../_images/exception-traceback-java.png

Figure 7.2. Stacktrace is 8 levels deep, it's not Java's 200 ;) 1

>>> def apollo13():
...     raise RuntimeError('Oxygen tank explosion')
>>>
>>>
>>> apollo13()
Traceback (most recent call last):
  File "<input>", line 5, in <module>
  File "<input>", line 2, in apollo13
RuntimeError: Oxygen tank explosion
>>> def apollo13():
...     raise RuntimeError('Oxygen tank explosion')
>>>
>>>
>>> apollo13()
Traceback (most recent call last):
  File "/home/watney/myscript.py", line 5, in <module>
    apollo13()
  File "/home/watney/myscript.py", line 2, in apollo13
    raise RuntimeError('Oxygen tank explosion')
RuntimeError: Oxygen tank explosion
>>> def apollo13():
...     raise RuntimeError('Oxygen tank explosion')
>>>
>>>
>>> apollo13()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/Applications/PyCharm 2021.1 EAP.app/Contents/helpers/pydev/_pydev_bundle/pydev_umd.py", line 197, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "/Applications/PyCharm 2021.1 EAP.app/Contents/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "/home/watney/myscript.py", line 4, in <module>
    apollo13()
  File "/home/watney/myscript.py", line 2, in apollo13
    raise RuntimeError('Oxygen tank explosion')
RuntimeError: Oxygen tank explosion

7.6.3. Change Verbosity Level

  • Change level with sys.tracebacklimit

  • From time to time you can have problems somewhere in the middle, but it's rare

  • Last lines are the most important, in most cases error is there

>>> import sys
>>> sys.tracebacklimit = 2
>>>
>>>
>>> def apollo13():
...     raise RuntimeError('Oxygen tank explosion')
>>>
>>>
>>> apollo13()
Traceback (most recent call last):
  File "/home/watney/myscript.py", line 4, in <module>
    apollo13()
  File "/home/watney/myscript.py", line 2, in apollo13
    raise RuntimeError('Oxygen tank explosion')
RuntimeError: Oxygen tank explosion

7.6.4. References

1

https://mattwarren.org/images/2016/12/Huge%20Java%20Stack%20Trace.png