Подсветка трассировки стека Python - PullRequest
22 голосов
/ 19 февраля 2010

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

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

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

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

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

  1. Я не вижу выходных данных до завершения тестирования носа. То есть Я не вижу прогресса.
  2. Я должен писать 2> & 1 снова и снова.

UPD 2:

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

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

Ответы [ 8 ]

21 голосов
/ 24 февраля 2010

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

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

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

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

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

Подсветка трассировки консоли Pygments http://www.tux21b.org/public/pygments-pytb.png

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

6 голосов
/ 19 февраля 2010

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

На основании предложения Дейва Кирби для vim, это выглядит примерно так:

less -p regex file_name

Или

some_command | less -p regex
1 голос
/ 22 июля 2017

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

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

pip install colored-traceback

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

if DEBUG:
    import colored_traceback
    colored_traceback.add_hook()

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

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
1 голос
/ 19 февраля 2010

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

0 голосов
/ 07 февраля 2019

Вот пример использования ipython:

import sys
from IPython.core.ultratb import ColorTB
print(''.join(ColorTB().structured_traceback(*sys.exc_info())))
0 голосов
/ 15 марта 2012

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

0 голосов
/ 19 февраля 2010

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

nosetests | vim -

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

:set hlsearch

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

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

Вуаля - все строки с вашим путем будут выделены.

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

/.*/path/to/my/code.*\n.*
0 голосов
/ 19 февраля 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...