# `traceback` — 스택 트레이스백 인쇄와 조회

소스 코드: Lib/traceback.py

이 모듈은 파이썬 프로그램의 스택 트레이스를 추출, 포맷 및 인쇄하는 표준 인터페이스를 제공합니다. 스택 트레이스를 인쇄할 때 파이썬 인터프리터의 동작을 정확하게 모방합니다. 이것은 가령 인터프리터를 둘러싸는 “래퍼”처럼 프로그램 제어 하에서 스택 트레이스를 인쇄하려고 할 때 유용합니다.

이 모듈은 트레이스백 객체를 사용합니다 — 이는 `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가 적절한 형식을 가지면, 에러의 대략적인 위치를 나타내는 캐럿(caret)과 함께 문법 에러가 발생한 줄을 인쇄합니다.

  선택적 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)

  트레이스백 객체 tb에서 추출된 “전 처리된” 스택 트레이스 항목의 리스트를 나타내는 `StackSummary` 객체를 반환합니다. 스택 트레이스의 대체 포매팅으로 유용합니다. 선택적 limit 인자는 `print_tb()`와 같은 의미입니다. “전 처리된” 스택 트레이스 항목은 일반적으로 스택 트레이스를 위해 인쇄되는 정보를 나타내는 어트리뷰트 `filename`, `lineno`, `name` 및 `line`을 포함하는 `FrameSummary` 객체입니다. `line`은 선행과 후행 공백이 제거된 문자열입니다; 소스를 사용할 수 없으면 `None`입니다.

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

  현재 스택 프레임에서 날 트레이스백을 추출합니다. 반환 값은 `extract_tb()`와 같은 형식입니다. 선택적 f와 limit 인자는 `print_stack()`과 같은 의미입니다.

`traceback.``format_list`(extracted_list)

  `extract_tb()`나 `extract_stack()`이 반환한 튜플이나 `FrameSummary` 객체의 리스트가 제공되면, 인쇄할 준비가 된 문자열의 리스트를 반환합니다. 결과 리스트의 각 문자열은 인자 리스트에서 같은 인덱스를 가진 항목에 해당합니다. 각 문자열은 줄 바꿈으로 끝납니다; 소스 텍스트 줄이 `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)

  각 프레임 객체의 `clear()` 메서드를 호출하여 트레이스백 tb에 있는 모든 스택 프레임의 지역 변수를 지웁니다.

  버전 3.4에 추가.

`traceback.``walk_stack`(f)

  주어진 프레임에서 `f.f_back`을 따라 스택을 걸어가며 각 프레임의 프레임과 줄 번호를 산출(yield)합니다. f가 `None`이면, 현재 스택이 사용됩니다. 이 도우미는 `StackSummary.extract()`와 함께 사용됩니다.

  버전 3.5에 추가.

`traceback.``walk_tb`(tb)

  `tb_next`를 따라 트레이스백을 걸으면서 각 프레임의 프레임과 줄 번호를 산출(yield)합니다. 이 도우미는 `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` 클래스와 같습니다.

  locals가 포착되면, 트레이스백에도 표시됨에 유의하십시오.

  `__cause__`

    원래 `__cause__`의 `TracebackException`.

  `__context__`

    원래 `__context__`의 `TracebackException`.

  `__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` 클래스와 같습니다.

    locals가 포착되면, 트레이스백에도 표시됨에 유의하십시오.

  `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)

    (`walk_stack()`이나 `walk_tb()`에서 반환된 것과 같은) 프레임 제너레이터로 `StackSummary` 객체를 생성합니다.

    limit가 제공되면, frame_gen에서 이 수 만큼의 프레임만 취합니다. lookup_lines가 `False`이면, 반환된 `FrameSummary` 객체는 아직 해당 줄을 읽지 않아서 `StackSummary`를 만드는 비용을 줄입니다 (실제로 포맷되지 않을 수 있다면 유용 할 수 있습니다). capture_locals가 `True`이면, 각 `FrameSummary`의 지역 변수는 객체 표현(representation)으로 포착됩니다.

  classmethod `from_list`(a_list)

    제공된 `FrameSummary` 객체의 리스트나 이전 스타일의 튜플 리스트로 `StackSummary` 객체를 생성합니다. 각 튜플은 파일명(filename), 줄 번호(lineno), 이름(name), 줄(line)을 요소로 하는 4-튜플이어야 합니다.

  `format`()

    인쇄 준비가 된 문자열의 리스트를 반환합니다. 결과 리스트의 각 문자열은 스택의 단일 프레임에 해당합니다. 각 문자열은 줄 바꿈으로 끝납니다; 소스 텍스트 줄이 있는 항목의 경우, 문자열에 내부 줄 바꿈도 포함될 수 있습니다.

    같은 프레임과 줄의 긴 시퀀스의 경우, 처음 몇 번의 반복이 표시된 다음, 정확한 추가의 반복 횟수를 나타내는 요약 줄이 표시됩니다.

    버전 3.6에서 변경: 반복되는 프레임의 긴 시퀀스가 이제 축약됩니다.

## `FrameSummary` 객체

버전 3.5에 추가.

`FrameSummary` 객체는 트레이스백에서 단일 프레임을 나타냅니다.

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

  포맷되거나 인쇄 중인 트레이스백이나 스택의 단일 프레임을 나타냅니다. 선택적으로 문자열로 변환된 버전의 프레임 지역 변수를 포함할 수 있습니다. lookup_line이 `False`이면, `FrameSummary`의 `line` 어트리뷰트에 액세스할 때까지 (튜플로 캐스트 할 때도 발생합니다) 소스 코드를 찾지 않습니다. `line`은 직접 제공될 수 있으며, 줄 조회가 전혀 발생하지 않도록 합니다. locals는 선택적 지역 변수 딕셔너리이며, 제공되면 변수 표현(representation)은 나중에 표시할 수 있도록 요약에 저장됩니다.

## 트레이스백 예제

이 간단한 예제는 표준 파이썬 대화식 인터프리터 루프와 비슷하지만 (하지만 덜 유용한) 기본적인 읽기-평가-인쇄 루프를 구현합니다. 인터프리터 루프의 더욱 완전한 구현은 `code` 모듈을 참조하십시오.

    import sys, traceback

    def run_user_code(envdir):
        source = input(">>> ")
        try:
            exec(source, envdir)
        except Exception:
            print("Exception in user code:")
            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']