23.2.6 例外はどう扱えばよいのですか?

例で生成される出力がトレースバックのみである限り問題ありません: 単にトレースバックを貼り付けてください。23.1トレースバックには、 頻繁に変更されがちな情報が入っている (例えばファイルパスや行番号など) ものなので、受け入れるべきテスト結果に柔軟性を持たせようと doctest が 苦労している部分の一つです。

簡単な例を示しましょう:

>>> [1, 2, 3].remove(42)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: list.remove(x): x not in list
>>>

この doctest は ValueError が送出され、かつ詳細情報に "list.remove(x): x not in list" が入っている場合にのみ成功します。

例外が発生したときの予想出力はトレースバックヘッダから始まっていなければ なりません。トレースバックの形式は以下の二通りの行のいずれかでよく、 例題の最初の行と同じインデントでなければりません:

Traceback (most recent call last):
Traceback (innermost last):

トレースバックヘッダの後ろにトレースバックスタックを続けてもかまいませんが、 doctest はその内容を無視します。普通はトレースバックスタックを無視するか、 対話セッションからそのままコピーしてきます。

トレースバックスタックの後ろにはもっとも有意義な部分、例外の型と 詳細情報の入った行があります。通常、この行はトレースバックの末尾 にあるのですが、例外が複数行の詳細情報を持っている場合、複数の行 にわたることもあります:

>>> raise ValueError('multi\n    line\ndetail')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: multi
    line
detail

上の例では、最後の 3 行 (ValueError から始まる行) における例外の型と詳細情報だけが比較され、それ以外の部分は無視 されます。

例外を扱うコツは、例題をドキュメントとして読む上で明らかに価値の ある情報でない限り、トレースバックスタックは無視する、ということ です。従って、先ほどの例は以下のように書くべきでしょう:

>>> raise ValueError('multi\n    line\ndetail')
Traceback (most recent call last):
    ...
ValueError: multi
    line
detail

トレースバックの扱いは非常に特殊なので注意してください。特に、 上の書き直した例題では、"..." の扱いが doctest の ELLIPSIS オプションによって変わります。この例での省略記号 は何かの省略を表しているかもしれませんし、コンマや数字が 3 個 (または 300 個かもしれませんし、Monty Python のスキットをインデントして 書き写したものかもしれません。

以下の詳細はずっと覚えておく必要はないのですが、一度目を通しておいて ください:

バージョン 2.4 で 変更 された仕様: 複数行からなる例外の詳細情報を扱えるようにし、 doctest オプションIGNORE_EXCEPTION_DETAIL を追加しました



脚注

... 単にトレースバックを貼り付けてください。23.1
予想出力結果 と例外の両方を含んだ例はサポートされていません。一方の終わりと 他方の始まりを見分けようとするのはエラーの元になりがちですし、 解りにくいテストになってしまいます。



Subsections
ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。