Почему линейный кэш Python влияет на модуль трассировки, а не на обычные трассировки? - PullRequest
0 голосов
/ 24 мая 2018

Рассмотрим следующую программу на Python:

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()

Я динамически определяю функцию, которая вызывает исключение, и добавляю ее в linecache.Вывод кода:

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

Если я получу трассировку от этой функции с помощью модуля traceback, будет показана строка кода из функции (часть 1/0 первой трассировки)).Но если я просто позволю коду вызвать исключение и получить регулярную трассировку от интерпретатора, он не покажет код.

Почему обычная трассировка интерпретатора не использует linecache?Есть ли способ заставить код появляться в регулярных трассировках?

1 Ответ

0 голосов
/ 24 мая 2018

По умолчанию sys.excepthook используется отдельная реализация трассировки печати на уровне C, а не модуль traceback.(Возможно, так оно и работает, даже если система слишком загружена, чтобы использовать traceback.py.) Реализация C не пытается использовать linecache.Вы можете увидеть код, который он использует для извлечения исходных строк, в _Py_DisplaySourceLine.

Если вы хотите, чтобы в трассировках использовалась реализация модуля traceback, вы можете заменить sys.excepthook на traceback.print_exception:

import sys
import traceback
sys.excepthook = traceback.print_exception
...