Ответ 1
Python не отслеживает, какой исходный код соответствует любому скомпилированному байт-коду. Возможно, он даже не прочитал этот исходный код, пока ему не понадобится распечатать трассировку, например, если модуль загружен из файла .pyc
.
Когда Python должен печатать трассировку, он пытается найти исходный код, соответствующий всем используемым фреймам стека. Имя файла и номер строки, который вы видите в трассировке стека, все Python должен продолжаться. Если он использовал модуль traceback
, путь кода прошел бы через раздел в linecache
, который исключает имена файлов, начинающиеся и заканчивающиеся на <
и >
, но по умолчанию sys.excepthook
не проходит этот путь.
default sys.excepthook
проходит через собственный вызов PyErr_Display
, который в конечном итоге заканчивается использованием _Py_DisplaySourceLine
для отображения отдельных строк источника. _Py_DisplaySourceLine
безоговорочно пытается найти файл в текущем рабочем каталоге (по какой-то причине - ошибочная оптимизация?), затем вызывает _Py_FindSourceFile
для поиска sys.path
для файла, соответствующего этому имени, если в рабочем каталоге его нет. Обычно он не находит файл <stdin>
или <string>
, и он просто пропускает исходный код печати, когда он не может найти файл, но если он находит его, он печатает из этого файла.
Первоначально я думал, что вы можете предотвратить это, запустив Python с -I
flag, поставив его в изолированном режиме. Одним из эффектов изолированного режима является удаление каталога script из sys.path
. Эксперимент доказал, что это не меняло вещи, а именно, когда я понял, что _Py_DisplaySourceLine
пытается запустить рабочий каталог независимо от того, что.
Было бы довольно просто исправить это, исключив <>
имена файлов в пути собственного кода, например linecache
. Также необходимо изменить код, который безошибочно ищет текущий каталог для файла.