"traceback" --- スタックトレースの表示または取得
************************************************

**ソースコード:** Lib/traceback.py

======================================================================

このモジュールは、Python プログラムのスタックトレースを抽出、書式化、
表示する標準的なインターフェースを提供します。 インタープリタのデフォ
ルトのトレースバック表示より柔軟で、出力の一部をカスタマイズできます。
また、実際の例外への参照を保存せずに、後で表示するために十分な情報を取
得するユーティリティもあります。 例外は、多数のオブジェクトが参照でつ
ながった構造の起点になることがあるため、このユーティリティを使うとメモ
リ管理を大幅に改善できます。

このモジュールは トレースバックオブジェクト を使います。 これは
"types.TracebackType" 型のオブジェクトで、"BaseException" インスタンス
の "__traceback__" フィールドに代入されます。

参考:

  "faulthandler" モジュール
     明示的な呼び出し時、障害発生時、タイムアウト後、またはユーザーシ
     グナルの受信時に、Python のトレースバックを出力するために使います
     。

  "pdb" モジュール
     Python プログラム用の対話的なソースコードデバッガです。

モジュールの API は 2 つに分けられます。

* 基本的な機能を提供するモジュールレベルの関数。 例外やトレースバック
  を対話的に調べるときに便利です。

* "TracebackException" クラスと、それを補助する "StackSummary" および
  "FrameSummary" クラス。 生成する出力をより柔軟に制御できるほか、実際
  の例外オブジェクトやトレースバックオブジェクトへの参照を保持せずに、
  後で書式化するために必要な情報を保存できます。


モジュールレベルの関数
======================

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

   *limit* が正の場合、トレースバックオブジェクト *tb* から、呼び出し
   元のフレームを先頭に最大 *limit* 個のスタックトレース項目を出力しま
   す。 それ以外の場合は、末尾の "abs(limit)" 個の項目を出力します。
   *limit* を省略するか "None" を指定すると、すべての項目を出力します
   。 *file* を省略するか "None" を指定すると、"sys.stderr" に出力しま
   す。 それ以外の場合は、出力を受け取る開かれた *ファイル* または
   *file-like object* を指定してください。

   注釈:

     *limit* 引数の意味は "sys.tracebacklimit" とは異なります。 負の
     *limit* は正の "sys.tracebacklimit" に相当しますが、正の *limit*
     の動作は "sys.tracebacklimit" では実現できません。

   バージョン 3.5 で変更: 負の *limit* がサポートされました。

traceback.print_exception(exc, /, [value, tb, ]limit=None, file=None, chain=True)

   トレースバックオブジェクト *tb* から例外の情報とスタックトレースの
   項目を *file* に出力します。 この関数は以下の点で "print_tb()" と異
   なります:

   * *tb* が "None" でない場合ヘッダ "Traceback (most recent call
     last):" を出力します

   * スタックトレースの後に例外タイプと *value* を出力します

   * *type(value)* が "SyntaxError" であり、 *value* が適切な形式を持
     っていれば、そのエラーのおおよその位置を示すマークと共にシンタッ
     クスエラーが発生した行が表示されます。

   Python 3.10 以降では、*value* と *tb* を渡す代わりに、最初の引数と
   して例外オブジェクトを渡せます。 *value* と *tb* を指定した場合は、
   後方互換性のために最初の引数を無視します。

   オプション引数 *limit* の意味は  "print_tb()" のものと同じです。
   *chain* が真の場合 (デフォルト)、連鎖した例外 (例外の "__cause__"
   か "__context__" 属性) も出力されます。 これはインタープリタ自身が
   処理されていない例外を出力するときと同じです。

   バージョン 3.5 で変更: 引数 *etype* は無視され、 *value* の型から推
   論されます。

   バージョン 3.10 で変更: *etype* 引数は *exc* に名前が変わり、位置専
   用引数になりました。

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

   "print_exception(sys.exception(), limit=limit, file=file,
   chain=chain)" の省略表現です。

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

   "print_exception(sys.last_exc, limit=limit, file=file,
   chain=chain)" の省略表現です。 一般に、例外が対話的なプロンプトに達
   した後にのみ機能します ("sys.last_exc" 参照)。

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

   *limit* が正の場合、呼び出し地点からさかのぼった最大 *limit* 個のス
   タックトレース項目を出力します。 0 以下の場合は、スタックをさかのぼ
   った末尾側の "abs(limit)" 個、つまり最も古い側の項目を出力します。
   *limit* が省略されるか "None" の場合は、すべての項目を出力します。
   オプションの *f* 引数で、開始する スタックフレーム を指定できます。
   オプションの *file* 引数は "print_tb()" の場合と同じ意味です。

   バージョン 3.5 で変更: 負の *limit* がサポートされました。

traceback.extract_tb(tb, limit=None)

   トレースバックオブジェクト *tb* から抽出した「前処理済み」のスタッ
   クトレース項目のリストを表す、"StackSummary" オブジェクトを返します
   。 スタックトレースを別の形式に整えるときに便利です。 省略可能な
   *limit* 引数の意味は "print_tb()" と同じです。 「前処理済み」のスタ
   ックトレース項目は "FrameSummary" オブジェクトで、通常のスタックト
   レースに表示される情報を属性として持ちます。

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

   現在の スタックフレーム から生のトレースバックを取り出します。戻り
   値は "extract_tb()" と同じ形式です。オプションの *f* と *limit* 引
   数は "print_stack()" と同じ意味を持ちます。

traceback.print_list(extracted_list, file=None)

   Print the list of tuples as returned by "extract_tb()" or
   "extract_stack()" as a formatted stack trace to the given file. If
   *file* is "None", the output is written to "sys.stderr".

traceback.format_list(extracted_list)

   "extract_tb()" または "extract_stack()" が返すような、タプルまたは
   "FrameSummary" オブジェクトからなるリストを受け取り、表示用に整えた
   文字列のリストを返します。 戻り値の各文字列は、引数のリストの同じイ
   ンデックスにある要素に対応します。 各文字列の末尾には改行が付きます
   。 ソースコード行が "None" でない要素については、文字列の途中にも改
   行が含まれることがあります。

traceback.format_exception_only(exc, /, [value, ]*, show_group=False)

   "sys.last_exc" などで得られる例外の値を使い、トレースバックの例外部
   分を書式化します。 戻り値は、各要素が改行で終わる文字列のリストです
   。 リストには例外のメッセージが含まれ、通常は 1 つの文字列になりま
   す。 ただし "SyntaxError" の場合は、構文エラーの位置についての詳細
   を表示する複数行が含まれます。 メッセージの後には、例外の "注釈" が
   含まれます。

   Python 3.10 以降では、*value* を渡す代わりに、最初の引数として例外
   オブジェクトを渡せます。 *value* を指定した場合は、後方互換性のため
   に最初の引数を無視します。

   *show_group* が "True" で、例外が "BaseExceptionGroup" のインスタン
   スである場合は、ネストした例外も再帰的に含め、ネストの深さに応じて
   インデントします。

   バージョン 3.10 で変更: *etype* 引数は *exc* に名前が変わり、位置専
   用引数になりました。

   バージョン 3.11 で変更: 返されるリストに、例外に付けられた "注釈"
   も含まれるようになりました。

   バージョン 3.13 で変更: *show_group* 引数が追加されました。

traceback.format_exception(exc, /, [value, tb, ]limit=None, chain=True)

   スタックトレースと例外情報を書式化します。引数は
   "print_exception()" の対応する引数と同じ意味を持ちます。戻り値は文
   字列のリストで、それぞれの文字列は改行で終わり、そのいくつかは内部
   に改行を含みます。これらの行が連結されて出力される場合は、厳密に
   "print_exception()" と同じテキストが出力されます。

   バージョン 3.5 で変更: 引数 *etype* は無視され、 *value* の型から推
   論されます。

   バージョン 3.10 で変更: 動作とシグネチャが "print_exception()" に合
   わせて変更されました。

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()" メソッド
   を呼び出し、すべてのスタックフレームのローカル変数を消去します。

   Added in version 3.4.

traceback.walk_stack(f)

   指定されたフレームから "f.f_back" をたどってスタックを走査し、各フ
   レームとその行番号を生成します。 *f* が "None" の場合は現在のスタッ
   クを使います。 この補助関数は "StackSummary.extract()" と組み合わせ
   て使います。

   Added in version 3.5.

   バージョン 3.14 で変更: 以前は、最初に反復されたときにスタックを走
   査するジェネレータを返していました。 現在返されるジェネレータは、
   "walk_stack" が呼ばれた時点のスタックの状態を表します。

traceback.walk_tb(tb)

   "tb_next" をたどってトレースバックを走査し、各フレームとその行番号
   を生成します。 この補助関数は "StackSummary.extract()" と組み合わせ
   て使います。

   Added in version 3.5.


"TracebackException" オブジェクト
=================================

Added in version 3.5.

"TracebackException" オブジェクトは、実際の例外から作成され、後で表示
するためのデータを保持します。 トレースバック オブジェクトや フレーム
オブジェクトへの参照を保持せず、より軽量に情報を保存できます。 また、
上記のモジュールレベルの関数よりも多くの出力設定オプションがあります。

class traceback.TracebackException(exc_type, exc_value, exc_traceback, *, limit=None, lookup_lines=True, capture_locals=False, compact=False, max_group_width=15, max_group_depth=10)

   後で表示するために例外の情報を取得します。 *limit*、*lookup_lines*
   、*capture_locals* の意味は "StackSummary" クラスと同じです。

   *compact* が真の場合は、"TracebackException" の "format()" メソッド
   に必要なデータだけをクラスの属性に保存します。 特に、"__context__"
   フィールドを計算するのは、"__cause__" が "None" かつ
   "__suppress_context__" が偽の場合だけです。

   局所変数がキャプチャされたとき、それらはトレースバックに表示される
   ことに注意してください。

   *max_group_width* と *max_group_depth* は例外グループの書式化を制御
   します ("BaseExceptionGroup" を参照)。 深さはグループのネストの段数
   、幅は 1 つの例外グループの例外配列のサイズを指します。 どちらかの
   上限を超えると、書式化された出力を切り詰めます。

   バージョン 3.10 で変更: *compact* 引数が追加されました。

   バージョン 3.11 で変更: *max_group_width* と *max_group_depth* 引数
   が追加されました。

   __cause__

      元々の "__cause__" の "TracebackException"。

   __context__

      元々の "__context__" の "TracebackException"。

   exceptions

      If "self" represents an "ExceptionGroup", this field holds a
      list of "TracebackException" instances representing the nested
      exceptions. Otherwise it is "None".

      Added in version 3.11.

   __suppress_context__

      元々の例外からの "__suppress_context__"。

   __notes__

      元の例外の "__notes__" の値で、例外に注釈がなければ "None" です
      。 "None" でなければ、トレースバック内で例外の文字列の後に書式化
      して表示します。

      Added in version 3.11.

   stack

      トレースバックを表す "StackSummary"。

   exc_type

      元の例外のクラス。

      バージョン 3.13 で非推奨.

   exc_type_str

      元の例外のクラスの表示用文字列。

      Added in version 3.13.

   filename

      構文エラー用 - エラーが発生したファイルの名前。

   lineno

      構文エラー用 - エラーが発生した行番号。

   end_lineno

      構文エラー用 - エラーが発生した範囲の末尾の行番号。 情報がない場
      合は "None" になることがあります。

      Added in version 3.10.

   text

      構文エラー用 - エラーが発生したテクスト。

   offset

      構文エラー用 - エラーが発生したテクストへのオフセット。

   end_offset

      構文エラー用 - エラーが発生した範囲のテキスト内の末尾のオフセッ
      ト。 情報がない場合は "None" になることがあります。

      Added in version 3.10.

   msg

      構文エラー用 - コンパイラのエラーメッセージ。

   classmethod from_exception(exc, *, limit=None, lookup_lines=True, capture_locals=False, compact=False, max_group_width=15, max_group_depth=10)

      後のレンダリングのために例外をキャプチャします。 *limit*、
      *lookup_lines*、*capture_locals* は "StackSummary" class のもの
      です。

      局所変数がキャプチャされたとき、それらはトレースバックに表示され
      ることに注意してください。

   print(*, file=None, chain=True)

      "format()" が返す例外情報を *file* (デフォルトは "sys.stderr")
      に出力します。

      Added in version 3.11.

   format(*, chain=True)

      例外を書式化します。

      *chain* が "True" でない場合 "__cause__" と "__context__" は書式
      化されません。

      返り値は文字列のジェネレータで、それぞれ改行で終わりますが、内部
      に改行を持つものもあります。 "print_exception()" はこのメソッド
      のラッパで、単にファイルに出力します。

   format_exception_only(*, show_group=False)

      トレースバックの例外部を書式化します。

      返り値は文字列のジェネレータで、それぞれ改行で終わります。

      *show_group* が "False" の場合、ジェネレータは例外のメッセージと
      、存在する場合はその注釈を順に生成します。 例外のメッセージは通
      常 1 つの文字列ですが、"SyntaxError" の場合は、構文エラーの位置
      についての詳細を表示する複数行からなります。

      *show_group* が "True" で、例外が "BaseExceptionGroup" のインス
      タンスである場合は、ネストした例外も再帰的に含め、ネストの深さに
      応じてインデントします。

      バージョン 3.11 で変更: 例外の "注釈" が出力に含まれるようになり
      ました。

      バージョン 3.13 で変更: *show_group* パラメータが追加されました
      。


"StackSummary" オブジェクト
===========================

Added in version 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" のローカル変数を、オブジェクト
      の "repr()" の結果として保存します。

      バージョン 3.12 で変更: ローカル変数の "repr()" が送出する例外が
      、呼び出し元へ伝播しなくなりました (*capture_locals* が "True"
      の場合)。

   classmethod from_list(a_list)

      指定された "FrameSummary" オブジェクトのリスト、または従来のタプ
      ルのリストから "StackSummary" オブジェクトを構築します。 各タプ
      ルは、*filename*、*lineno*、*name*、*line* を要素とする 4 要素の
      タプルにしてください。

   format()

      表示用に整えた文字列のリストを返します。 各文字列は、スタック内
      の 1 つの フレーム に対応します。 各文字列の末尾には改行が付きま
      す。 ソースコード行を含む項目では、文字列の途中にも改行が含まれ
      ることがあります。

      同じフレームと行が長く繰り返される場合は、最初の数回を表示し、続
      いて残りの繰り返し回数を正確に示す要約行を表示します。

      バージョン 3.6 で変更: フレームの長い繰り返しが省略されるように
      なりました。

   format_frame_summary(frame_summary)

      スタック内の 1 つの フレーム を表示するための文字列を返します。
      "StackSummary.format()" が表示する各 "FrameSummary" オブジェクト
      に対して呼び出されます。 "None" を返した場合、そのフレームは出力
      から除外されます。

      Added in version 3.11.


"FrameSummary" オブジェクト
===========================

Added in version 3.5.

"FrameSummary" オブジェクトは、トレースバック 内の 1 つの フレーム を
表します。

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

   書式化または表示する トレースバック やスタック内の、1 つの フレーム
   を表します。 必要に応じて、そのフレームのローカル変数を文字列にした
   ものも含められます。 *lookup_line* が "False" の場合、
   "FrameSummary" の "line" 属性にアクセスするまでソースコードを取得し
   ません ("tuple" への変換時にも、この属性へのアクセスが発生します)。
   "line" を直接指定すると、ソースコード行の取得を完全に避けられます。
   *locals* は省略可能なローカル変数のマッピングです。 指定すると、後
   で表示するために変数の "repr()" の結果を保存します。

   "FrameSummary" インスタンスは以下の属性を持ちます:

   filename

      このフレームのソースコードのファイル名。 フレームオブジェクト
      *f* の "f.f_code.co_filename" へのアクセスと同等です。

   lineno

      このフレームのソースコードの行番号。

   name

      フレームオブジェクト *f* の "f.f_code.co_name" へのアクセスと同
      等です。

   line

      A string representing the source code for this frame, with
      leading and trailing whitespace stripped. If the source is not
      available, it is "None".

   end_lineno

      このフレームのソースコードの末尾の行番号。 デフォルトは "lineno"
      で、行番号は 1 から始まります。

      バージョン 3.13 で変更: デフォルト値が "None" から "lineno" に変
      わりました。

   colno

      このフレームのソースコードの列番号。 デフォルトは "None" で、列
      番号は 0 から始まります。

   end_colno

      このフレームのソースコードの末尾の列番号。 デフォルトは "None"
      で、列番号は 0 から始まります。


モジュールレベルの関数の使用例
==============================

この簡単な例では基本的な read-eval-print ループを実装しています。標準
的な Python の対話インタープリタループに似ていますが、 Python のものよ
り便利ではありません。インタープリタループのより完全な実装については、
"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_life()

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

   try:
       lumberjack()
   except IndexError as exc:
       print("*** print_tb:")
       traceback.print_tb(exc.__traceback__, limit=1, file=sys.stdout)
       print("*** print_exception:")
       traceback.print_exception(exc, 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:")
       print(repr(traceback.format_exception(exc)))
       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_life()
       ~~~~~~~~~~~~~~~~~~~^^
   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_life()
       ~~~~~~~~~~~~~~~~~~~^^
   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 default[0]>", line 10, in <module>\n    lumberjack()\n    ~~~~~~~~~~^^\n',
    '  File "<doctest default[0]>", line 4, in lumberjack\n    bright_side_of_life()\n    ~~~~~~~~~~~~~~~~~~~^^\n',
    '  File "<doctest default[0]>", line 7, in bright_side_of_life\n    return tuple()[0]\n           ~~~~~~~^^^\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_life>]
   *** format_tb:
   ['  File "<doctest default[0]>", line 10, in <module>\n    lumberjack()\n    ~~~~~~~~~~^^\n',
    '  File "<doctest default[0]>", line 4, in lumberjack\n    bright_side_of_life()\n    ~~~~~~~~~~~~~~~~~~~^^\n',
    '  File "<doctest default[0]>", line 7, in bright_side_of_life\n    return tuple()[0]\n           ~~~~~~~^^^\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(an_error)
   ['IndexError: tuple index out of range\n']


"TracebackException" の使用例
=============================

補助クラスを使うと、さらに多くのオプションを利用できます。

   >>> import sys
   >>> from traceback import TracebackException
   >>>
   >>> def lumberjack():
   ...     bright_side_of_life()
   ...
   >>> def bright_side_of_life():
   ...     t = "bright", "side", "of", "life"
   ...     return t[5]
   ...
   >>> try:
   ...     lumberjack()
   ... except IndexError as e:
   ...     exc = e
   ...
   >>> try:
   ...     try:
   ...         lumberjack()
   ...     except:
   ...         1/0
   ... except Exception as e:
   ...     chained_exc = e
   ...
   >>> # limit works as with the module-level functions
   >>> TracebackException.from_exception(exc, limit=-2).print()
   Traceback (most recent call last):
     File "<python-input-1>", line 6, in lumberjack
       bright_side_of_life()
       ~~~~~~~~~~~~~~~~~~~^^
     File "<python-input-1>", line 10, in bright_side_of_life
       return t[5]
              ~^^^
   IndexError: tuple index out of range

   >>> # capture_locals adds local variables in frames
   >>> TracebackException.from_exception(exc, limit=-2, capture_locals=True).print()
   Traceback (most recent call last):
     File "<python-input-1>", line 6, in lumberjack
       bright_side_of_life()
       ~~~~~~~~~~~~~~~~~~~^^
     File "<python-input-1>", line 10, in bright_side_of_life
       return t[5]
              ~^^^
       t = ("bright", "side", "of", "life")
   IndexError: tuple index out of range

   >>> # The *chain* kwarg to print() controls whether chained
   >>> # exceptions are displayed
   >>> TracebackException.from_exception(chained_exc).print()
   Traceback (most recent call last):
     File "<python-input-19>", line 4, in <module>
       lumberjack()
       ~~~~~~~~~~^^
     File "<python-input-8>", line 7, in lumberjack
       bright_side_of_life()
       ~~~~~~~~~~~~~~~~~~~^^
     File "<python-input-8>", line 11, in bright_side_of_life
       return t[5]
              ~^^^
   IndexError: tuple index out of range

   During handling of the above exception, another exception occurred:

   Traceback (most recent call last):
     File "<python-input-19>", line 6, in <module>
       1/0
       ~^~
   ZeroDivisionError: division by zero

   >>> TracebackException.from_exception(chained_exc).print(chain=False)
   Traceback (most recent call last):
     File "<python-input-19>", line 6, in <module>
       1/0
       ~^~
   ZeroDivisionError: division by zero
