Модуль "трассировка" модуля Python: отсутствует путь к файлу

Я отслеживаю скрипт python следующим образом:

python -m trace --ignore-dir=$HOME/lib64:$HOME/lib:/usr -t bin/myscript.py

Некоторые строки выглядят так:

 --- modulename: __init__, funcname: getEffectiveLevel
__init__.py(1325):         logger = self
__init__.py(1326):         while logger:
__init__.py(1327):             if logger.level:
__init__.py(1329):             logger = logger.parent
__init__.py(1326):         while logger:
__init__.py(1327):             if logger.level:
__init__.py(1328):                 return logger.level

К сожалению, я не знаю, откуда этот код.

Есть ли способ увидеть имя файла (включая путь) getEffectiveLevel()?

Конечно, я мог бы выполнить поиск по всему установленному питонному коду для метода с этим именем, но я хотел бы сразу увидеть путь к файлу.

В этом контексте используется Python 2.7.

Я не привязан к стандартной трассировке библиотеки. Я мог бы использовать другую библиотеку, если она предоставляет необходимую функцию.

Ответ 1

если цель заключается в поиске полного пути, то проверьте проект hunter, он даже поддерживает отслеживание в стиле запроса.

# a modified example from docs
# do check the documentation it is easy to start with
from hunter import trace, Q, Debugger
from pdb import Pdb

trace(
    # drop into a Pdb session on''myscript.mainMethod()'' call
    Q(module="myscript", function="getEffectiveLevel", kind="call", action=Debugger(klass=Pdb)))

import myscript
myscript.mainMethod()

Ответ 2

К сожалению, для включения этого параметра нет опции флаг/командной строки. Поэтому немедленный (и, вероятно, правильный) ответ: Нет.

Если вы в порядке со вставками со встроенными библиотеками, вы можете легко сделать это, изменив строку, которая гласит:

print (" --- modulename: %s, funcname: %s" 
       % (modulename, code.co_name))

с:

print ("filename: %s, modulename: %s, funcname: %s"
       % (filename, modulename, code.co_name))

в файле trace.py вашей установки Python. Вы можете найти путь к этому файлу с помощью:

>>> import trace
>>> trace.__file__

Но я действительно не хочу предлагать, чтобы изменить библиотеки таким образом, я бы рекомендовал. Прежде чем вы это сделаете (если вы решите, что действительно хотите это сделать), создайте резервную копию файла и, если возможно, замените его еще раз после завершения.

Лучший способ (хотя и все еще запутанный) - скопировать вышеупомянутый файл trace.py (например, в текущий рабочий каталог) и изменить скопированный файл. Затем вы можете запустить модифицированную версию:

python path_to_modified_trace_file your_options_for_trace

Без опции -m и с измененным путем, но в остальном идентичны вашему оригиналу.

Ответ 3

Вы можете создать файл trace2.py с содержимым ниже

from trace import Trace, main

original_globaltrace_lt = Trace.globaltrace_lt

def patch_Trace_globaltrace_lt(self, frame, why, arg):
    value = original_globaltrace_lt(self, frame, why, arg)
    if value:
        filename = frame.f_globals.get('__file__', "")
        print("The code is in file - %s" % (filename))
    return value

Trace.globaltrace_lt = patch_Trace_globaltrace_lt

if __name__ == "__main__":
    main()

и затем запустите его, как показано ниже.

python -m trace2 --ignore-dir=$HOME/lib64:$HOME/lib:/usr -t bin/myscript.py

Результат является подробным, но вы можете изменить функцию patch_Trace_globaltrace_lt в соответствии с вашими потребностями