Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the Python linecache affect the traceback module but not regular tracebacks?

Consider the following Python program:

code = """
def test():
    1/0
"""

filename = "<test>"

c = compile(code, filename, 'exec')
exec(c)

import linecache

linecache.cache[filename] = (len(code), None, code.splitlines(keepends=True), filename)

import traceback

print("Traceback from the traceback module:")
print()
try:
    test()
except:
    traceback.print_exc()

print()
print("Regular traceback:")
print()

test()

I am dynamically defining a function that raises an exception and adding it to the linecache. The output of the code is

Traceback from the traceback module:

Traceback (most recent call last):
  File "test.py", line 20, in <module>
    test()
  File "<test>", line 3, in test
    1/0
ZeroDivisionError: division by zero

Regular traceback:

Traceback (most recent call last):
  File "test.py", line 28, in <module>
    test()
  File "<test>", line 3, in test
ZeroDivisionError: division by zero

If I then get a traceback from that function using the traceback module, the line of code from the function is shown (the 1/0 part of the first traceback). But if I just let the code raise an exception and get the regular traceback from the interpreter, it doesn't show the code.

Why doesn't the regular interpreter traceback use the linecache? Is there a way to make the code appear in regular tracebacks?

like image 660
asmeurer Avatar asked May 24 '18 18:05

asmeurer


People also ask

What are common traceback errors?

Some of the common traceback errors are:NameError. IndexError. KeyError. TypeError.

What are three elements that you might find in a traceback?

The class of the original traceback. For syntax errors - the file name where the error occurred. For syntax errors - the line number where the error occurred. For syntax errors - the text where the error occurred.

What is traceback module in Python?

Traceback is a python module that provides a standard interface to extract, format and print stack traces of a python program. When it prints the stack trace it exactly mimics the behaviour of a python interpreter. Useful when you want to print the stack trace at any step.


1 Answers

The default sys.excepthook uses a separate, C-level implementation of traceback printing, not the traceback module. (Perhaps this is so it still works even if the system is too borked to use traceback.py.) The C implementation doesn't try to use linecache. You can see the code it uses to retrieve source lines in _Py_DisplaySourceLine.

If you want tracebacks to use the traceback module's implementation, you could replace sys.excepthook with traceback.print_exception:

import sys
import traceback
sys.excepthook = traceback.print_exception
like image 175
user2357112 supports Monica Avatar answered Sep 23 '22 08:09

user2357112 supports Monica