Подтвердить что ты не робот

Выделение трассировки стека python

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

Итак, я понял, что хочу что-то, что будет раскрашивать трассировки стека и выделять строки, которые являются моими. Сравните оригинал с выделен.

Я мог бы написать python script, который мог бы использовать этот способ:

nosetests | colorize_stack_trace.py

Но я считаю, что есть более быстрый и элегантный способ сделать это с помощью набора инструментов Linux. Любые идеи?

UPD:

Используя суперкарт, предложенный Деннисом Уильямсоном, промежуточный результат следующий за функцией bash:

pyst() {
    rc=/tmp/spcrc;
    echo '#################### ### # # # ########################################' > $rc;
    echo '                     blk   0 r ^(.*)$' >> $rc;
    echo '                     mag b 0 r ^\s*File "'`pwd`'/(.*)"' >> $rc;
    spc -c $rc;
}

Теперь я могу сделать:

nosetests 2>&1 | pyst

Не слишком элегантный, но работает в некоторой степени. Остались две проблемы:

  • Я не вижу никакого вывода перед завершением носетей. То есть Я не вижу прогресса.
  • Мне нужно снова и снова писать 2 > & 1.

UPD 2:

Задавая этот вопрос, я имел в виду главным образом nosetests. И я просто нашел отличное решение: rednose плагин для носа. Он выделяет пути, которые являются локальными, и делает еще много удобных возможностей для чтения.

Возвращаясь к исходному вопросу: проблемы, которые я заметил с помощью supercat, не относятся к нему полностью, но его проблема в потоковой передаче, промывке, пересылке, перенаправлении Unix. Так как в качестве ответа на заданный вопрос я принимаю ответ, который предлагает supercat.

4b9b3361

Ответ 1

Посмотрите Supercat (spc). Он выполняет подсветку ANSI и HTML и может быть настроен для вашего конкретного вывода. Он поставляется с некоторыми файлами конфигурации для файлов исходного кода в C и Python, например, файлы журналов, Changelogs, diff и другие.

На основе предложения Дейва Кирби для vim это делает нечто похожее:

less -p regex file_name

или

some_command | less -p regex

Ответ 2

На самом деле, есть отличная библиотека подсветки синтаксиса Python, которая называется Pygments, которая также может подсвечивать обратные вызовы.

Итак, все, что вам нужно сделать, это:

$ easy_install pygments # downloads and installs pygments
$ cat traceback.txt | pygmentize -l pytb

"pytb" - это ярлык для PythonTracebackLexer. Также есть специальный лексер для Python 3 Tracebacks, который называется "py3tb".

Вы можете форматировать вывод в различных форматах (включая html, latex, svg, несколько форматов изображений и т.д.). Но есть также средство форматирования терминала (и если вам интересно... конечно, есть разные цветовые темы!).

Вы можете использовать -f html, чтобы выбрать другой форматер (в этом случае, форматер HTML).

Ответ 3

Для этого есть хороший модуль:

Вам просто нужно скачать и установить его через pip:

pip install colored-traceback

Импортируйте его в файл верхнего уровня вашего проекта, например:

if DEBUG:
    import colored_traceback
    colored_traceback.add_hook()

И вы получите такую ​​трассировку для каждого файла underling (цвета меняются):

Traceback (most recent call last):
  File "./workflowy.py", line 525, in <module>
    main()
  File "./workflowy.py", line 37, in main
    projects = cli.load_json(args, input_is_pipe)
  File "./workflowy.py", line 153, in load_json
    return json.load(sys.stdin)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 290, in load
    **kw)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 365, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 383, in raw_decode
    raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded

Ответ 4

Возможно, вы могли бы использовать модуль cgitb (короткий официальный документ здесь) в качестве отправной точки (он создает приятные HTML-трассировки). Это должно быть относительно просто сделать необходимые вам изменения (например, добавить цветовой тег в соответствии с файловым путем). Но, конечно, это возможно только в том случае, если вы хотите использовать браузер для просмотра трасс.

Ответ 5

В качестве отправной точки для раскраски (и в противном случае форматирования) текста вы, вероятно, захотите посмотреть curses library. Также смотрите этот практический способ, который выглядит полезным.

Что касается переопределения встроенной обработки ошибок Python для всех программ... Я никогда не пробовал, но я бы подумал, что это потребует некоторых довольно низких изменений. Вы всегда можете обернуть свой код огромным блоком try/except, но я предполагаю, что вы не хотите этого делать. Я одобряю более унифицированный подход к написанию небольшого script, который делает одно и делает это хорошо: он принимает вход и, если это трассировка стека, раскрашивает его. В противном случае передайте текст без изменений. Использование трубы, как вы сказали, может быть лучшим способом. (В этом случае для pipe stderr вы хотите сделать что-то вроде этого, которое объединяет stderr с stdout перед конвейером: cmd1 2>&1 | cmd2)

Ответ 6

Также вы можете открыть файл трассировки с помощью vim, используя команду :cfile. Затем вы можете открыть выделенный ant интерактивный список файлов в трассировке с помощью команды :copen и перейти между этими файлами с помощью набора связанных команд vim.

Ответ 7

Вот один из них, использующий ipython:

import sys
from IPython.core.ultratb import ColorTB
print(''.join(ColorTB().structured_traceback(*sys.exc_info())))

Ответ 8

Загрузите текст в vim:

nosetests | vim -

Установите vim, чтобы выделить все строки, соответствующие поиску

:set hlsearch

Искать строки с "вашим" путем

/.*/path/to/my/code.*

Voila - все линии с вашим путем будут выделены.

Если вы хотите также выделить следующую строку, вы также можете сделать это:

/.*/path/to/my/code.*\n.*