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

1

6

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?

Instruction answered 24/5, 2018 at 18:10 Comment(0)
E
7

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
Else answered 24/5, 2018 at 18:24 Comment(1)
If I read that C source correctly, it just opens the file and reads it each time (no line caching). So I guess your solution is the only reasonable fix.Instruction

© 2022 - 2024 — McMap. All rights reserved.