cgitb – 詳細なトレースバックレポート¶
目的: | cgitb は traceback よりも詳細なトレースバック情報を提供する |
---|---|
利用できるバージョン: | 2.2 以上 |
もともと cgitb は、web アプリケーションのエラーとデバッグ情報の表示を目的に設計されていました。後になってプレーンテキストの出力も同様に含めるように拡張されましたが、残念ながら名前は変更されませんでした。この名前は分かり難いので、このモジュールはあまり使われていません。そうとは言え cgitb は標準ライブラリの優れたデバッグツールです。
標準トレースバックの出力¶
Python のデフォルトの例外処理の動作は、エラーが発生した箇所へ至るコールスタックと トレースバック を標準エラー出力に表示します。この基本的な出力は、例外が発生した原因を理解して、その不具合を修正するのに十分な情報を提供します。
def func1(arg1):
local_var = arg1 * 2
return func2(local_var)
def func2(arg2):
local_var = arg2 + 2
return func3(local_var)
def func3(arg3):
local_var = arg2 / 2
return local_var
func1(1)
上述したサンプルプログラムは func3() に分かり難いエラーがあります。
$ python cgitb_basic_traceback.py
Traceback (most recent call last):
File "cgitb_basic_traceback.py", line 22, in <module>
func1(1)
File "cgitb_basic_traceback.py", line 12, in func1
return func2(local_var)
File "cgitb_basic_traceback.py", line 16, in func2
return func3(local_var)
File "cgitb_basic_traceback.py", line 19, in func3
local_var = arg2 / 2
NameError: global name 'arg2' is not defined
詳細なトレースバックを有効にする¶
標準のトレースバックはエラーが発生した箇所を見つけるのに十分な情報を提供しますが、 cgitb を有効にすると sys.excepthook をさらに詳細なトレースバック情報を出力するように拡張した関数に置き換えてくれます。
import cgitb
cgitb.enable(format='text')
def func1(arg1):
local_var = arg1 * 2
return func2(local_var)
def func2(arg2):
local_var = arg2 + 2
return func3(local_var)
def func3(arg3):
local_var = arg2 / 2
return local_var
func1(1)
ご覧のように、このエラーレポートはかなり広範囲に及びます。スタックの各フレームが次の内容にそって表示されます。
- ファイル名だけではなく、ソースファイルのフルパスを表示する
- スタックの各関数への引数の値を表示する
- エラーパス周辺のソースコンテキストを数行表示する
- エラーを発生させた式の変数の値を表示する
$ python cgitb_extended_traceback.py
<type 'exceptions.NameError'>
Python 2.7.2: /Users/dhellmann/Envs/pymotw-ja/bin/python
Sun Feb 17 11:32:15 2013
A problem occurred in a Python script. Here is the sequence of
function calls leading up to the error, in the order they occurred.
/Users/dhellmann/Devel/pymotw-ja/t2y/PyMOTW/cgitb/cgitb_extended_traceback.py in <module>()
21 def func3(arg3):
22 local_var = arg2 / 2
23 return local_var
24
25 func1(1)
func1 = <function func1>
/Users/dhellmann/Devel/pymotw-ja/t2y/PyMOTW/cgitb/cgitb_extended_traceback.py in func1(arg1=1)
13 def func1(arg1):
14 local_var = arg1 * 2
15 return func2(local_var)
16
17 def func2(arg2):
global func2 = <function func2>
local_var = 2
/Users/dhellmann/Devel/pymotw-ja/t2y/PyMOTW/cgitb/cgitb_extended_traceback.py in func2(arg2=2)
17 def func2(arg2):
18 local_var = arg2 + 2
19 return func3(local_var)
20
21 def func3(arg3):
global func3 = <function func3>
local_var = 4
/Users/dhellmann/Devel/pymotw-ja/t2y/PyMOTW/cgitb/cgitb_extended_traceback.py in func3(arg3=4)
20
21 def func3(arg3):
22 local_var = arg2 / 2
23 return local_var
24
local_var undefined
arg2 undefined
<type 'exceptions.NameError'>: global name 'arg2' is not defined
__class__ = <type 'exceptions.NameError'>
__delattr__ = <method-wrapper '__delattr__' of exceptions.NameError object>
__dict__ = {}
__doc__ = 'Name not found globally.'
__format__ = <built-in method __format__ of exceptions.NameError object>
__getattribute__ = <method-wrapper '__getattribute__' of exceptions.NameError object>
__getitem__ = <method-wrapper '__getitem__' of exceptions.NameError object>
__getslice__ = <method-wrapper '__getslice__' of exceptions.NameError object>
__hash__ = <method-wrapper '__hash__' of exceptions.NameError object>
__init__ = <method-wrapper '__init__' of exceptions.NameError object>
__new__ = <built-in method __new__ of type object>
__reduce__ = <built-in method __reduce__ of exceptions.NameError object>
__reduce_ex__ = <built-in method __reduce_ex__ of exceptions.NameError object>
__repr__ = <method-wrapper '__repr__' of exceptions.NameError object>
__setattr__ = <method-wrapper '__setattr__' of exceptions.NameError object>
__setstate__ = <built-in method __setstate__ of exceptions.NameError object>
__sizeof__ = <built-in method __sizeof__ of exceptions.NameError object>
__str__ = <method-wrapper '__str__' of exceptions.NameError object>
__subclasshook__ = <built-in method __subclasshook__ of type object>
__unicode__ = <built-in method __unicode__ of exceptions.NameError object>
args = ("global name 'arg2' is not defined",)
message = "global name 'arg2' is not defined"
The above is a description of an error in a Python program. Here is
the original traceback:
Traceback (most recent call last):
File "cgitb_extended_traceback.py", line 25, in <module>
func1(1)
File "cgitb_extended_traceback.py", line 15, in func1
return func2(local_var)
File "cgitb_extended_traceback.py", line 19, in func2
return func3(local_var)
File "cgitb_extended_traceback.py", line 22, in func3
local_var = arg2 / 2
NameError: global name 'arg2' is not defined
この出力の最後の方に、(message 以外のデバッグに役立つ属性を持つ場合は)例外オブジェクトの全ての詳細とオリジナルのトレースバック出力も含みます。
トレースバックのローカル変数¶
エラースタックで実行された変数へアクセスできることは、実際に例外が発生した行よりもスタックの高いところで起こる論理的なエラーを見つけるのに役立ちます。
import cgitb
cgitb.enable(format='text')
def func2(a, divisor):
return a / divisor
def func1(a, b):
c = b - 5
return func2(a, c)
func1(1, 5)
ZeroDivisionError を発生させるこのサンプルコードでは、 func2() で使用される値の計算よりも func1() で c の値の計算でこの問題が発生することが分かります。
$ python cgitb_local_vars.py
<type 'exceptions.ZeroDivisionError'>
Python 2.7.2: /Users/dhellmann/Envs/pymotw-ja/bin/python
Sun Feb 17 11:32:15 2013
A problem occurred in a Python script. Here is the sequence of
function calls leading up to the error, in the order they occurred.
/Users/dhellmann/Devel/pymotw-ja/t2y/PyMOTW/cgitb/cgitb_local_vars.py in <module>()
16 def func1(a, b):
17 c = b - 5
18 return func2(a, c)
19
20 func1(1, 5)
func1 = <function func1>
/Users/dhellmann/Devel/pymotw-ja/t2y/PyMOTW/cgitb/cgitb_local_vars.py in func1(a=1, b=5)
16 def func1(a, b):
17 c = b - 5
18 return func2(a, c)
19
20 func1(1, 5)
global func2 = <function func2>
a = 1
c = 0
/Users/dhellmann/Devel/pymotw-ja/t2y/PyMOTW/cgitb/cgitb_local_vars.py in func2(a=1, divisor=0)
12
13 def func2(a, divisor):
14 return a / divisor
15
16 def func1(a, b):
a = 1
divisor = 0
<type 'exceptions.ZeroDivisionError'>: integer division or modulo by zero
__class__ = <type 'exceptions.ZeroDivisionError'>
__delattr__ = <method-wrapper '__delattr__' of exceptions.ZeroDivisionError object>
__dict__ = {}
__doc__ = 'Second argument to a division or modulo operation was zero.'
__format__ = <built-in method __format__ of exceptions.ZeroDivisionError object>
__getattribute__ = <method-wrapper '__getattribute__' of exceptions.ZeroDivisionError object>
__getitem__ = <method-wrapper '__getitem__' of exceptions.ZeroDivisionError object>
__getslice__ = <method-wrapper '__getslice__' of exceptions.ZeroDivisionError object>
__hash__ = <method-wrapper '__hash__' of exceptions.ZeroDivisionError object>
__init__ = <method-wrapper '__init__' of exceptions.ZeroDivisionError object>
__new__ = <built-in method __new__ of type object>
__reduce__ = <built-in method __reduce__ of exceptions.ZeroDivisionError object>
__reduce_ex__ = <built-in method __reduce_ex__ of exceptions.ZeroDivisionError object>
__repr__ = <method-wrapper '__repr__' of exceptions.ZeroDivisionError object>
__setattr__ = <method-wrapper '__setattr__' of exceptions.ZeroDivisionError object>
__setstate__ = <built-in method __setstate__ of exceptions.ZeroDivisionError object>
__sizeof__ = <built-in method __sizeof__ of exceptions.ZeroDivisionError object>
__str__ = <method-wrapper '__str__' of exceptions.ZeroDivisionError object>
__subclasshook__ = <built-in method __subclasshook__ of type object>
__unicode__ = <built-in method __unicode__ of exceptions.ZeroDivisionError object>
args = ('integer division or modulo by zero',)
message = 'integer division or modulo by zero'
The above is a description of an error in a Python program. Here is
the original traceback:
Traceback (most recent call last):
File "cgitb_local_vars.py", line 20, in <module>
func1(1, 5)
File "cgitb_local_vars.py", line 18, in func1
return func2(a, c)
File "cgitb_local_vars.py", line 14, in func2
return a / divisor
ZeroDivisionError: integer division or modulo by zero
エラーを引き起こすスタックフレームで使用される変数を調べる cgitb のコードは、オブジェクトの属性を評価して表示するのにも十分実用できます。
import cgitb
cgitb.enable(format='text')
class BrokenClass(object):
"""This class has an error.
"""
def __init__(self, a, b):
"""Be careful passing arguments in here.
"""
self.a = a
self.b = b
self.c = self.a * self.b
self.d = self.a / self.b
return
o = BrokenClass(1, 0)
ここでは self.a と self.b が、エラーの発生し易いコードで実行されます。
$ python cgitb_with_classes.py
<type 'exceptions.ZeroDivisionError'>
Python 2.7.2: /Users/dhellmann/Envs/pymotw-ja/bin/python
Sun Feb 17 11:32:15 2013
A problem occurred in a Python script. Here is the sequence of
function calls leading up to the error, in the order they occurred.
/Users/dhellmann/Devel/pymotw-ja/t2y/PyMOTW/cgitb/cgitb_with_classes.py in <module>()
24 return
25
26 o = BrokenClass(1, 0)
27
28
o undefined
BrokenClass = <class '__main__.BrokenClass'>
/Users/dhellmann/Devel/pymotw-ja/t2y/PyMOTW/cgitb/cgitb_with_classes.py in __init__(self=<__main__.BrokenClass object>, a=1, b=0)
21 self.b = b
22 self.c = self.a * self.b
23 self.d = self.a / self.b
24 return
25
self = <__main__.BrokenClass object>
self.d undefined
self.a = 1
self.b = 0
<type 'exceptions.ZeroDivisionError'>: integer division or modulo by zero
__class__ = <type 'exceptions.ZeroDivisionError'>
__delattr__ = <method-wrapper '__delattr__' of exceptions.ZeroDivisionError object>
__dict__ = {}
__doc__ = 'Second argument to a division or modulo operation was zero.'
__format__ = <built-in method __format__ of exceptions.ZeroDivisionError object>
__getattribute__ = <method-wrapper '__getattribute__' of exceptions.ZeroDivisionError object>
__getitem__ = <method-wrapper '__getitem__' of exceptions.ZeroDivisionError object>
__getslice__ = <method-wrapper '__getslice__' of exceptions.ZeroDivisionError object>
__hash__ = <method-wrapper '__hash__' of exceptions.ZeroDivisionError object>
__init__ = <method-wrapper '__init__' of exceptions.ZeroDivisionError object>
__new__ = <built-in method __new__ of type object>
__reduce__ = <built-in method __reduce__ of exceptions.ZeroDivisionError object>
__reduce_ex__ = <built-in method __reduce_ex__ of exceptions.ZeroDivisionError object>
__repr__ = <method-wrapper '__repr__' of exceptions.ZeroDivisionError object>
__setattr__ = <method-wrapper '__setattr__' of exceptions.ZeroDivisionError object>
__setstate__ = <built-in method __setstate__ of exceptions.ZeroDivisionError object>
__sizeof__ = <built-in method __sizeof__ of exceptions.ZeroDivisionError object>
__str__ = <method-wrapper '__str__' of exceptions.ZeroDivisionError object>
__subclasshook__ = <built-in method __subclasshook__ of type object>
__unicode__ = <built-in method __unicode__ of exceptions.ZeroDivisionError object>
args = ('integer division or modulo by zero',)
message = 'integer division or modulo by zero'
The above is a description of an error in a Python program. Here is
the original traceback:
Traceback (most recent call last):
File "cgitb_with_classes.py", line 26, in <module>
o = BrokenClass(1, 0)
File "cgitb_with_classes.py", line 23, in __init__
self.d = self.a / self.b
ZeroDivisionError: integer division or modulo by zero
もっとコンテキストを追加する¶
たくさんのコメント、スペース、余分なコードがある長い関数があると仮定してください。その場合、デフォルトで表示される5行のコンテキストだと、ウィンドウに表示されるコードから関数の主要部分が押し出されて必要な情報がないかもしれません。 cgitb を利用するときに context に大きな値をセットすると、そういった問題に対応できます。
import cgitb
import sys
context_length = int(sys.argv[1])
cgitb.enable(format='text', context=context_length)
def func2(a, divisor):
return a / divisor
def func1(a, b):
c = b - 5
# 本当に
# 長い
# コメントが
# ここに
# 記述されます
return func2(a, c)
func1(1, 5)
トレースバックに表示されるコード量を制御するために context を enable() に渡します。
$ python cgitb_more_context.py 5
<type 'exceptions.ZeroDivisionError'>
Python 2.7.2: /Users/dhellmann/Envs/pymotw-ja/bin/python
Sun Feb 17 11:32:15 2013
A problem occurred in a Python script. Here is the sequence of
function calls leading up to the error, in the order they occurred.
/Users/dhellmann/Devel/pymotw-ja/t2y/PyMOTW/cgitb/cgitb_more_context.py in <module>()
24 # ここに
25 # 記述されます
26 return func2(a, c)
27
28 func1(1, 5)
func1 = <function func1>
/Users/dhellmann/Devel/pymotw-ja/t2y/PyMOTW/cgitb/cgitb_more_context.py in func1(a=1, b=5)
24 # ここに
25 # 記述されます
26 return func2(a, c)
27
28 func1(1, 5)
global func2 = <function func2>
a = 1
c = 0
/Users/dhellmann/Devel/pymotw-ja/t2y/PyMOTW/cgitb/cgitb_more_context.py in func2(a=1, divisor=0)
15
16 def func2(a, divisor):
17 return a / divisor
18
19 def func1(a, b):
a = 1
divisor = 0
<type 'exceptions.ZeroDivisionError'>: integer division or modulo by zero
__class__ = <type 'exceptions.ZeroDivisionError'>
__delattr__ = <method-wrapper '__delattr__' of exceptions.ZeroDivisionError object>
__dict__ = {}
__doc__ = 'Second argument to a division or modulo operation was zero.'
__format__ = <built-in method __format__ of exceptions.ZeroDivisionError object>
__getattribute__ = <method-wrapper '__getattribute__' of exceptions.ZeroDivisionError object>
__getitem__ = <method-wrapper '__getitem__' of exceptions.ZeroDivisionError object>
__getslice__ = <method-wrapper '__getslice__' of exceptions.ZeroDivisionError object>
__hash__ = <method-wrapper '__hash__' of exceptions.ZeroDivisionError object>
__init__ = <method-wrapper '__init__' of exceptions.ZeroDivisionError object>
__new__ = <built-in method __new__ of type object>
__reduce__ = <built-in method __reduce__ of exceptions.ZeroDivisionError object>
__reduce_ex__ = <built-in method __reduce_ex__ of exceptions.ZeroDivisionError object>
__repr__ = <method-wrapper '__repr__' of exceptions.ZeroDivisionError object>
__setattr__ = <method-wrapper '__setattr__' of exceptions.ZeroDivisionError object>
__setstate__ = <built-in method __setstate__ of exceptions.ZeroDivisionError object>
__sizeof__ = <built-in method __sizeof__ of exceptions.ZeroDivisionError object>
__str__ = <method-wrapper '__str__' of exceptions.ZeroDivisionError object>
__subclasshook__ = <built-in method __subclasshook__ of type object>
__unicode__ = <built-in method __unicode__ of exceptions.ZeroDivisionError object>
args = ('integer division or modulo by zero',)
message = 'integer division or modulo by zero'
The above is a description of an error in a Python program. Here is
the original traceback:
Traceback (most recent call last):
File "cgitb_more_context.py", line 28, in <module>
func1(1, 5)
File "cgitb_more_context.py", line 26, in func1
return func2(a, c)
File "cgitb_more_context.py", line 17, in func2
return a / divisor
ZeroDivisionError: integer division or modulo by zero
値を増やして再度実行すると、コード内の問題を見つけるのに十分な関数の情報を取得できます。
$ python cgitb_more_context.py 10
<type 'exceptions.ZeroDivisionError'>
Python 2.7.2: /Users/dhellmann/Envs/pymotw-ja/bin/python
Sun Feb 17 11:32:15 2013
A problem occurred in a Python script. Here is the sequence of
function calls leading up to the error, in the order they occurred.
/Users/dhellmann/Devel/pymotw-ja/t2y/PyMOTW/cgitb/cgitb_more_context.py in <module>()
19 def func1(a, b):
20 c = b - 5
21 # 本当に
22 # 長い
23 # コメントが
24 # ここに
25 # 記述されます
26 return func2(a, c)
27
28 func1(1, 5)
func1 = <function func1>
/Users/dhellmann/Devel/pymotw-ja/t2y/PyMOTW/cgitb/cgitb_more_context.py in func1(a=1, b=5)
19 def func1(a, b):
20 c = b - 5
21 # 本当に
22 # 長い
23 # コメントが
24 # ここに
25 # 記述されます
26 return func2(a, c)
27
28 func1(1, 5)
global func2 = <function func2>
a = 1
c = 0
/Users/dhellmann/Devel/pymotw-ja/t2y/PyMOTW/cgitb/cgitb_more_context.py in func2(a=1, divisor=0)
12
13 context_length = int(sys.argv[1])
14 cgitb.enable(format='text', context=context_length)
15
16 def func2(a, divisor):
17 return a / divisor
18
19 def func1(a, b):
20 c = b - 5
21 # 本当に
a = 1
divisor = 0
<type 'exceptions.ZeroDivisionError'>: integer division or modulo by zero
__class__ = <type 'exceptions.ZeroDivisionError'>
__delattr__ = <method-wrapper '__delattr__' of exceptions.ZeroDivisionError object>
__dict__ = {}
__doc__ = 'Second argument to a division or modulo operation was zero.'
__format__ = <built-in method __format__ of exceptions.ZeroDivisionError object>
__getattribute__ = <method-wrapper '__getattribute__' of exceptions.ZeroDivisionError object>
__getitem__ = <method-wrapper '__getitem__' of exceptions.ZeroDivisionError object>
__getslice__ = <method-wrapper '__getslice__' of exceptions.ZeroDivisionError object>
__hash__ = <method-wrapper '__hash__' of exceptions.ZeroDivisionError object>
__init__ = <method-wrapper '__init__' of exceptions.ZeroDivisionError object>
__new__ = <built-in method __new__ of type object>
__reduce__ = <built-in method __reduce__ of exceptions.ZeroDivisionError object>
__reduce_ex__ = <built-in method __reduce_ex__ of exceptions.ZeroDivisionError object>
__repr__ = <method-wrapper '__repr__' of exceptions.ZeroDivisionError object>
__setattr__ = <method-wrapper '__setattr__' of exceptions.ZeroDivisionError object>
__setstate__ = <built-in method __setstate__ of exceptions.ZeroDivisionError object>
__sizeof__ = <built-in method __sizeof__ of exceptions.ZeroDivisionError object>
__str__ = <method-wrapper '__str__' of exceptions.ZeroDivisionError object>
__subclasshook__ = <built-in method __subclasshook__ of type object>
__unicode__ = <built-in method __unicode__ of exceptions.ZeroDivisionError object>
args = ('integer division or modulo by zero',)
message = 'integer division or modulo by zero'
The above is a description of an error in a Python program. Here is
the original traceback:
Traceback (most recent call last):
File "cgitb_more_context.py", line 28, in <module>
func1(1, 5)
File "cgitb_more_context.py", line 26, in func1
return func2(a, c)
File "cgitb_more_context.py", line 17, in func2
return a / divisor
ZeroDivisionError: integer division or modulo by zero
例外プロパティ¶
各スタックフレームのローカル変数に加えて、 cgitb は例外オブジェクトの全てのプロパティを表示します。拡張プロパティをもつカスタム例外を扱う場合、それはエラーレポートの一部に表示されます。
import cgitb
cgitb.enable(format='text')
class MyException(Exception):
"""Add extra properties to a special exception
"""
def __init__(self, message, bad_value):
self.bad_value = bad_value
Exception.__init__(self, message)
return
raise MyException('Normal message', bad_value=99)
このサンプルでは、 bad_value プロパティが標準の message と args の間にあります。
$ python cgitb_exception_properties.py
<class '__main__.MyException'>
Python 2.7.2: /Users/dhellmann/Envs/pymotw-ja/bin/python
Sun Feb 17 11:32:15 2013
A problem occurred in a Python script. Here is the sequence of
function calls leading up to the error, in the order they occurred.
/Users/dhellmann/Devel/pymotw-ja/t2y/PyMOTW/cgitb/cgitb_exception_properties.py in <module>()
18 self.bad_value = bad_value
19 Exception.__init__(self, message)
20 return
21
22 raise MyException('Normal message', bad_value=99)
MyException = <class '__main__.MyException'>
bad_value undefined
<class '__main__.MyException'>: Normal message
__class__ = <class '__main__.MyException'>
__delattr__ = <method-wrapper '__delattr__' of MyException object>
__dict__ = {'bad_value': 99}
__doc__ = 'Add extra properties to a special exception\n '
__format__ = <built-in method __format__ of MyException object>
__getattribute__ = <method-wrapper '__getattribute__' of MyException object>
__getitem__ = <method-wrapper '__getitem__' of MyException object>
__getslice__ = <method-wrapper '__getslice__' of MyException object>
__hash__ = <method-wrapper '__hash__' of MyException object>
__init__ = <bound method MyException.__init__ of MyException('Normal message',)>
__module__ = '__main__'
__new__ = <built-in method __new__ of type object>
__reduce__ = <built-in method __reduce__ of MyException object>
__reduce_ex__ = <built-in method __reduce_ex__ of MyException object>
__repr__ = <method-wrapper '__repr__' of MyException object>
__setattr__ = <method-wrapper '__setattr__' of MyException object>
__setstate__ = <built-in method __setstate__ of MyException object>
__sizeof__ = <built-in method __sizeof__ of MyException object>
__str__ = <method-wrapper '__str__' of MyException object>
__subclasshook__ = <built-in method __subclasshook__ of type object>
__unicode__ = <built-in method __unicode__ of MyException object>
__weakref__ = None
args = ('Normal message',)
bad_value = 99
message = 'Normal message'
The above is a description of an error in a Python program. Here is
the original traceback:
Traceback (most recent call last):
File "cgitb_exception_properties.py", line 22, in <module>
raise MyException('Normal message', bad_value=99)
MyException: Normal message
トレースバックをロギングする¶
よくある環境では、トレースバック情報の詳細は標準エラー出力に表示することが最も良い方法です。しかし、本番環境では、エラーをロギングする方がもっと良いです。 enable() は、エラーロギングを有効にする logdir というオプション引数を取ります。ディレクトリ名を指定すると、それぞれの例外はそのディレクトリのログファイルにロギングされます。
import cgitb
import os
cgitb.enable(logdir=os.path.join(os.path.dirname(__file__), 'LOGS'),
display=False,
format='text',
)
def func2(a, divisor):
return a / divisor
def func1(a, b):
c = b - 5
return func2(a, c)
func1(1, 5)
エラーの出力は抑制されますが、そのエラーメッセージはエラーログを探しに行くと見つけられます。
$ python cgitb_log_exception.py
<p>A problem occurred in a Python script.
<p> /Users/dhellmann/Devel/pymotw-ja/t2y/PyMOTW/cgitb/LOGS/tmpGqH25H.txt contains the description of this error.
$ ls LOGS
tmpGqH25H.txt
$ cat LOGS/*.txt
<type 'exceptions.ZeroDivisionError'>
Python 2.7.2: /Users/dhellmann/Envs/pymotw-ja/bin/python
Sun Feb 17 11:32:15 2013
A problem occurred in a Python script. Here is the sequence of
function calls leading up to the error, in the order they occurred.
/Users/dhellmann/Devel/pymotw-ja/t2y/PyMOTW/cgitb/cgitb_log_exception.py in <module>()
21 def func1(a, b):
22 c = b - 5
23 return func2(a, c)
24
25 func1(1, 5)
func1 = <function func1>
/Users/dhellmann/Devel/pymotw-ja/t2y/PyMOTW/cgitb/cgitb_log_exception.py in func1(a=1, b=5)
21 def func1(a, b):
22 c = b - 5
23 return func2(a, c)
24
25 func1(1, 5)
global func2 = <function func2>
a = 1
c = 0
/Users/dhellmann/Devel/pymotw-ja/t2y/PyMOTW/cgitb/cgitb_log_exception.py in func2(a=1, divisor=0)
17
18 def func2(a, divisor):
19 return a / divisor
20
21 def func1(a, b):
a = 1
divisor = 0
<type 'exceptions.ZeroDivisionError'>: integer division or modulo by zero
__class__ = <type 'exceptions.ZeroDivisionError'>
__delattr__ = <method-wrapper '__delattr__' of exceptions.ZeroDivisionError object>
__dict__ = {}
__doc__ = 'Second argument to a division or modulo operation was zero.'
__format__ = <built-in method __format__ of exceptions.ZeroDivisionError object>
__getattribute__ = <method-wrapper '__getattribute__' of exceptions.ZeroDivisionError object>
__getitem__ = <method-wrapper '__getitem__' of exceptions.ZeroDivisionError object>
__getslice__ = <method-wrapper '__getslice__' of exceptions.ZeroDivisionError object>
__hash__ = <method-wrapper '__hash__' of exceptions.ZeroDivisionError object>
__init__ = <method-wrapper '__init__' of exceptions.ZeroDivisionError object>
__new__ = <built-in method __new__ of type object>
__reduce__ = <built-in method __reduce__ of exceptions.ZeroDivisionError object>
__reduce_ex__ = <built-in method __reduce_ex__ of exceptions.ZeroDivisionError object>
__repr__ = <method-wrapper '__repr__' of exceptions.ZeroDivisionError object>
__setattr__ = <method-wrapper '__setattr__' of exceptions.ZeroDivisionError object>
__setstate__ = <built-in method __setstate__ of exceptions.ZeroDivisionError object>
__sizeof__ = <built-in method __sizeof__ of exceptions.ZeroDivisionError object>
__str__ = <method-wrapper '__str__' of exceptions.ZeroDivisionError object>
__subclasshook__ = <built-in method __subclasshook__ of type object>
__unicode__ = <built-in method __unicode__ of exceptions.ZeroDivisionError object>
args = ('integer division or modulo by zero',)
message = 'integer division or modulo by zero'
The above is a description of an error in a Python program. Here is
the original traceback:
Traceback (most recent call last):
File "cgitb_log_exception.py", line 25, in <module>
func1(1, 5)
File "cgitb_log_exception.py", line 23, in func1
return func2(a, c)
File "cgitb_log_exception.py", line 19, in func2
return a / divisor
ZeroDivisionError: integer division or modulo by zero
HTML 出力¶
cgitb は、もともと web アプリケーションの例外を処理するために開発されていたので、HTML 出力のサンプルを紹介しないわけにはいきません。
import cgitb
cgitb.enable()
def func1(arg1):
local_var = arg1 * 2
return func2(local_var)
def func2(arg2):
local_var = arg2 + 2
return func3(local_var)
def func3(arg3):
local_var = arg2 / 2
return local_var
func1(1)
format 引数を取り除く(または html を指定する)ことで、トレースバック情報の出力フォーマットを HTML に変更します。
See also
- cgitb
- 本モジュールの標準ライブラリドキュメント
- traceback
- トレースバック情報を扱う標準ライブラリ
- inspect
- スタックを調べる関数を提供する inspect モジュール
- sys
- カレントの実行値と例外が発生したときに実行される excepthook ハンドラへのアクセスを提供する sys モジュール
- Improved traceback module
- traceback モジュールの改善と開発者が普段行っている機能拡張に関する Python-dev の議論