traceback — Печать или получение обратной трассировки стека


Данный модуль предоставляет стандартный интерфейс для извлечения, форматирования и печати трассировки стека Python программ. Он точно имитирует поведение интерпретатора Python, когда печатает трассировку стека. Это полезно, когда вы хотите распечатать трассировку стека под управлением программы, например, в «оболочке» вокруг интерпретатора.

Модуль использует объекты трассировки — это тип объекта, который хранится в переменной sys.last_traceback и возвращается как третий элемент из sys.exc_info().

Модуль определяет следующие функции:

traceback.print_tb(tb, limit=None, file=None)

Распечатывает до limit записей трассировки стека из объекта трассировки tb (начиная с фрейма вызывающего объекта), если limit положительный. В противном случае выводит последние записи abs(limit). Если limit пропущен или None, печатаются все записи. Если file пропущен или None, вывод идет на sys.stderr; в противном случае это должен быть открытый файл или файлоподобный объект для получения вывода.

Изменено в версии 3.5: Добавлена отрицательная поддержка limit.

traceback.print_exception(etype, value, tb, limit=None, file=None, chain=True)

Распечатывает информацию об исключении и записи трассировки стека от объекта трассировки tb до file. Отличается от print_tb() следующим образом:

  • если tb не является None, печатает заголовок Traceback (most recent call last):
  • печатает исключение etype и value после трассировки стека
  • если type(value) имеет значение SyntaxError, а value имеет соответствующий формат, печатает строку, в которой произошла синтаксическая ошибка, с символом вставки, указывающим приблизительное положение ошибки.

Необязательный аргумент limit имеет то же значение, что и print_tb(). Если chain имеет значение истина (по умолчанию), то цепочечные исключения (атрибуты __cause__ или __context__ исключения) также будут напечатаны, как это делает сам интерпретатор при печати необработанного исключения.

Изменено в версии 3.5: Аргумент etype игнорируется и выводится из типа value.

traceback.print_exc(limit=None, file=None, chain=True)

Сокращение от print_exception(*sys.exc_info(), limit, file, chain).

traceback.print_last(limit=None, file=None, chain=True)

Сокращение от print_exception(sys.last_type, sys.last_value, sys.last_traceback, limit, file, chain). Как правило, будет работать только после того, как исключение достигнет интерактивной подсказки (см. sys.last_type).

traceback.print_stack(f=None, limit=None, file=None)

Распечатывает до limit записей трассировки стека (начиная с точки вызова), если limit положительный. В противном случае выводит последние записи abs(limit). Если limit пропущен или None, печатаются все записи. Необязательный аргумент f может использоваться для указания запуска альтернативного фрейма стека. Необязательный аргумент file имеет то же значение, что и для print_tb().

Изменено в версии 3.5: Добавлена отрицательная поддержка limit.

traceback.extract_tb(tb, limit=None)

Возвращает объект StackSummary, представляющий список «предварительно обработанных» записей трассировки стека, извлеченных из объекта трассировки tb. Это полезно для альтернативного форматирования трассировки стека. Необязательный аргумент limit имеет то же значение, что и print_tb(). «Предварительно обработанная» запись трассировки стека — это объект FrameSummary, содержащий атрибуты filename, lineno, name и line, представляющие информацию, которая обычно печатается для трассировки стека. line — это строка с удалёнными начальными и конечными пробелами; если источник недоступен, это None.

traceback.extract_stack(f=None, limit=None)

Извлекает необработанную трассировку из текущего фрейма стека. Возвращаемое значение имеет тот же формат, что и для extract_tb(). Необязательные аргументы f и limit имеют то же значение, что и для print_stack().

traceback.format_list(extracted_list)

Получив список кортежей или объектов FrameSummary, возвращенных extract_tb() или extract_stack(), возвращает список строк, готовых к печати. Каждая строка в результирующем списке соответствует элементу с тем же индексом в списке аргументов. Каждая строка заканчивается новой строкой; строки также могут содержать внутренние символы новой строки для тех элементов, строка исходного текста которых не содержит None.

traceback.format_exception_only(etype, value)

Отформатировать часть исключения трассировки. Аргументы — это тип и значение исключения, такие как sys.last_type и sys.last_value. Возвращаемое значение представляет собой список строк, каждая из которых заканчивается новой строкой. Обычно список содержит одну строку; однако для исключений SyntaxError он содержит несколько строк, которые (при печати) отображают подробную информацию о том, где произошла синтаксическая ошибка. Сообщение указывает на произошедшее исключение; всегда является последней строкой в списке.

traceback.format_exception(etype, value, tb, limit=None, chain=True)

Отформатировать трассировку стека и информацию об исключении. Аргументы имеют то же значение, что и соответствующие аргументы print_exception(). Возвращаемое значение представляет собой список строк, каждая из которых заканчивается символом новой строки, а некоторые содержат внутренние символы новой строки. Когда данные строки объединяются и печатаются, печатается точно такой же текст, как и print_exception().

Изменено в версии 3.5: Аргумент etype игнорируется и выводится из типа value.

traceback.format_exc(limit=None, chain=True)

Похожа на print_exc(limit), но возвращает строку вместо печати в файл.

traceback.format_tb(tb, limit=None)

Сокращение для format_list(extract_tb(tb, limit)).

traceback.format_stack(f=None, limit=None)

Сокращение для format_list(extract_stack(f, limit)).

traceback.clear_frames(tb)

Очищает локальные переменные всех фреймов стека в трассировке tb, вызывая метод clear() каждого объекта фрейма.

Добавлено в версии 3.4.

traceback.walk_stack(f)

Обходит стек, следующий за f.f_back от данного фрейма, получая фрейм и номер строки для каждого фрейма. Если f равен None, используется текущий стек. Данный помощник используется с StackSummary.extract().

Добавлено в версии 3.5.

traceback.walk_tb(tb)

Обходит обратную трассировку по tb_next, получая фрейм и номер строки для каждого фрейма. Данный помощник используется с StackSummary.extract().

Добавлено в версии 3.5.

Модуль также определяет следующие классы:

Объекты TracebackException

Добавлено в версии 3.5.

Объекты TracebackException создаются из реальных исключений для сбора данных для последующей печати в облегчённом виде.

class traceback.TracebackException(exc_type, exc_value, exc_traceback, *, limit=None, lookup_lines=True, capture_locals=False)

Захватывает исключение для последующего рендеринга. limit, lookup_lines и capture_locals соответствуют классу StackSummary.

Обратите внимание, что при захвате локальных они также отображаются в трассировке.

__cause__

TracebackException оригинального __cause__.

__context__

TracebackException оригинального __context__.

__suppress_context__

Значение __suppress_context__ из исходного исключения.

stack

StackSummary, представляющий трассировку.

exc_type

Класс исходной трассировки.

filename

Для синтаксических ошибок — имя файла, в котором произошла ошибка.

lineno

Для синтаксических ошибок — номер строки, в которой произошла ошибка.

text

Для синтаксических ошибок — текст, в котором произошла ошибка.

offset

Для синтаксических ошибок — смещение в тексте, где произошла ошибка.

msg

Для синтаксических ошибок — сообщение об ошибке компилятора.

classmethod from_exception(exc, *, limit=None, lookup_lines=True, capture_locals=False)

Захват исключения для последующего рендеринга. limit, lookup_lines и capture_locals соответствуют классу StackSummary.

Обратите внимание, что при захвате локальных они также отображаются в трассировке.

format(*, chain=True)

Отформатировать исключение.

Если chain не является True, __cause__ и __context__ не будут отформатированы.

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

Сообщение, указывающее, какое исключение произошло, всегда является последней строкой в выходных данных.

format_exception_only()

Отформатировать часть исключения в трассировке.

Возвращаемое значение представляет собой генератор строк, каждая из которых заканчивается новой строкой.

Обычно генератор вызывает одну строку; однако для исключений SyntaxError выдаётся несколько строк, которые (при печати) отображают подробную информацию о том, где произошла синтаксическая ошибка.

Сообщение, указывающее, какое исключение произошло, всегда является последней строкой в выходных данных.

Объекты StackSummary

Добавлено в версии 3.5.

Объекты StackSummary представляют стек вызовов, готовый к форматированию.

class traceback.StackSummary
classmethod extract(frame_gen, *, limit=None, lookup_lines=True, capture_locals=False)

Создаёт объект StackSummary из генератора фреймов (например, возвращаемый walk_stack() или walk_tb()).

Если указан limit, из frame_gen берётся только это количество фреймов. Если lookup_lines равен False, возвращенные объекты FrameSummary ещё не считывают свои строки, что удешевляет стоимость создания StackSummary (что может быть ценным, если он может фактически не форматироваться). Если capture_locals равен True, локальные переменные в каждом FrameSummary фиксируются как представления объектов.

classmethod from_list(a_list)

Создаёт объект StackSummary из предоставленного списка объектов FrameSummary или списка кортежей в старом стиле. Каждый кортеж должен состоять из 4-х элементов с именем файла, номером строки, именем и строкой.

format()

Возвращает список строк, готовых к печати. Каждая строка в результирующем списке соответствует одному кадру из стека. Каждая строка заканчивается новой строкой; строки также могут содержать внутренние символы новой строки для элементов со строками исходного текста.

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

Изменено в версии 3.6: Длинные последовательности повторяющихся фреймов теперь сокращаются.

Объекты FrameSummary

Добавлено в версии 3.5.

Объекты FrameSummary представляют один фрейм в трассировке.

class traceback.FrameSummary(filename, lineno, name, lookup_line=True, locals=None, line=None)

Представляет один фрейм в трассировке или стеке, который форматируется или печатается. При желании он может иметь включённую в него строковую версию локальных переменных фреймов. Если lookup_lineFalse, исходный код не просматривается до тех пор, пока FrameSummary не получит доступ к атрибуту line (что также происходит при приведении его к кортежу). line может быть предоставлен напрямую и вообще предотвратит поиск строк. locals — это необязательный словарь локальных переменных, и если он указан, представления переменных сохраняются в сводке для последующего отображения.

Примеры трассировки

В данном простом примере реализован базовый цикл чтения-вычисления-печати, аналогичный (но менее полезный) стандартному циклу интерактивного интерпретатора Python. Для более полной реализации цикла интерпретатора обратитесь к модулю code.

import sys, traceback

def run_user_code(envdir):
    source = input(">>> ")
    try:
        exec(source, envdir)
    except Exception:
        print("Исключение в пользовательском коде:")
        print("-"*60)
        traceback.print_exc(file=sys.stdout)
        print("-"*60)

envdir = {}
while True:
    run_user_code(envdir)

В следующем примере демонстрируются различные способы печати и форматирования исключения и обратной трассировки:

import sys, traceback

def lumberjack():
    bright_side_of_death()

def bright_side_of_death():
    return tuple()[0]

try:
    lumberjack()
except IndexError:
    exc_type, exc_value, exc_traceback = sys.exc_info()
    print("*** print_tb:")
    traceback.print_tb(exc_traceback, limit=1, file=sys.stdout)
    print("*** print_exception:")
    # exc_type below is ignored on 3.5 and later
    traceback.print_exception(exc_type, exc_value, exc_traceback,
                              limit=2, file=sys.stdout)
    print("*** print_exc:")
    traceback.print_exc(limit=2, file=sys.stdout)
    print("*** format_exc, first and last line:")
    formatted_lines = traceback.format_exc().splitlines()
    print(formatted_lines[0])
    print(formatted_lines[-1])
    print("*** format_exception:")
    # exc_type below is ignored on 3.5 and later
    print(repr(traceback.format_exception(exc_type, exc_value,
                                          exc_traceback)))
    print("*** extract_tb:")
    print(repr(traceback.extract_tb(exc_traceback)))
    print("*** format_tb:")
    print(repr(traceback.format_tb(exc_traceback)))
    print("*** tb_lineno:", exc_traceback.tb_lineno)

Вывод для примера будет выглядеть примерно так:

*** print_tb:
  File "<doctest...>", line 10, in <module>
    lumberjack()
*** print_exception:
Traceback (most recent call last):
  File "<doctest...>", line 10, in <module>
    lumberjack()
  File "<doctest...>", line 4, in lumberjack
    bright_side_of_death()
IndexError: tuple index out of range
*** print_exc:
Traceback (most recent call last):
  File "<doctest...>", line 10, in <module>
    lumberjack()
  File "<doctest...>", line 4, in lumberjack
    bright_side_of_death()
IndexError: tuple index out of range
*** format_exc, first and last line:
Traceback (most recent call last):
IndexError: tuple index out of range
*** format_exception:
['Traceback (most recent call last):\n',
 '  File "<doctest...>", line 10, in <module>\n    lumberjack()\n',
 '  File "<doctest...>", line 4, in lumberjack\n    bright_side_of_death()\n',
 '  File "<doctest...>", line 7, in bright_side_of_death\n    return tuple()[0]\n',
 'IndexError: tuple index out of range\n']
*** extract_tb:
[<FrameSummary file <doctest...>, line 10 in <module>>,
 <FrameSummary file <doctest...>, line 4 in lumberjack>,
 <FrameSummary file <doctest...>, line 7 in bright_side_of_death>]
*** format_tb:
['  File "<doctest...>", line 10, in <module>\n    lumberjack()\n',
 '  File "<doctest...>", line 4, in lumberjack\n    bright_side_of_death()\n',
 '  File "<doctest...>", line 7, in bright_side_of_death\n    return tuple()[0]\n']
*** tb_lineno: 10

В следующем примере показаны различные способы печати и форматирования стека:

>>> import traceback
>>> def another_function():
...     lumberstack()
...
>>> def lumberstack():
...     traceback.print_stack()
...     print(repr(traceback.extract_stack()))
...     print(repr(traceback.format_stack()))
...
>>> another_function()
  File "<doctest>", line 10, in <module>
    another_function()
  File "<doctest>", line 3, in another_function
    lumberstack()
  File "<doctest>", line 6, in lumberstack
    traceback.print_stack()
[('<doctest>', 10, '<module>', 'another_function()'),
 ('<doctest>', 3, 'another_function', 'lumberstack()'),
 ('<doctest>', 7, 'lumberstack', 'print(repr(traceback.extract_stack()))')]
['  File "<doctest>", line 10, in <module>\n    another_function()\n',
 '  File "<doctest>", line 3, in another_function\n    lumberstack()\n',
 '  File "<doctest>", line 8, in lumberstack\n    print(repr(traceback.format_stack()))\n']

Данный последний пример демонстрирует последние несколько функций форматирования:

>>> import traceback
>>> traceback.format_list([('spam.py', 3, '<module>', 'spam.eggs()'),
...                        ('eggs.py', 42, 'eggs', 'return "bacon"')])
['  File "spam.py", line 3, in <module>\n    spam.eggs()\n',
 '  File "eggs.py", line 42, in eggs\n    return "bacon"\n']
>>> an_error = IndexError('tuple index out of range')
>>> traceback.format_exception_only(type(an_error), an_error)
['IndexError: tuple index out of range\n']