В python вы можете скомпилировать () строку, которая будет выполняться быстрее с exec (). Но как только я его использую, мы теряем информацию, когда в exec происходит исключение.
Например, вот фрагмент кода, который вызывает неизвестный метод (для демонстрационных целей):
code = 'my_unknown_method()'
bytecode = compile(code, '<string>', 'exec')
А позже я вызываю exec для этого байт-кода:
exec bytecode
Показанная трассировка:
Traceback (most recent call last):
File "test.py", line 3, in <module>
exec bytecode
File "<string>", line 1, in <module>
NameError: name 'my_unknown_method' is not defined
Кадр "exec ()" теперь неясен. Я хотел бы иметь лучшее исключение, например:
Traceback (most recent call last):
File "test.py", line 3, in <module>
exec "my_unknown_method()"
File "<string>", line 1, in <module>
NameError: name 'my_unknown_method' is not defined
Есть мысли?
Примечания:
- Я не хочу использовать второй аргумент компиляции (имя файла)
- Я протестировал игру с проверкой и изменением f_code на кадре, но это атрибут только для чтения.
РЕДАКТИРОВАТЬ: после того, как я посмотрел больше на sys.excepthook, я увидел, что в исходном коде python / traceback.c, когда python хочет показать содержимое строки, они являются fopen () непосредственно в файле, если найдены. Нет доступного крючка для отображения нашего собственного контента. Единственным способом было бы создать реальное поддельное имя файла на диске? Кто-нибудь?
EDIT2: я проверил некоторый код отладки jinja2, и они тоже переписывают traceback, но не для содержимого. Нужен ли мне кастом, кроме крючка? Я обеспокоен тем, что, поскольку он не находится в самой трассировке, если пользователь / модуль / что-либо еще делает исключение, трассировка не будет содержать ценной информации.