プログラムをステップ実行する
Python標準のpdbモジュールを使うことでプログラムをstep実行することが出来ます。pdbモジュールの詳しい使い方は Pythonデバッガ を参照してください。ここではZopeプロダクトを例に、使い方を簡単に説明します。
とりあえず埋め込んでみる
まず、step実行するときには「このあたりの動作が怪しい」という箇所があるとおもいますので、そのあたりに以下のようにpdbのコードを仕込みます。
次に、Zopeをforgroundで動作させるためにrunzopeで起動します(zopectlによるdaemonモードは使用しないでください)。これで、この行が実行される時にrunzopeしているコンソール画面が以下のようにPythonの対話モードになります。(コードはjaMailHost/__init__.py (ver0.4.3)の例です)
-> if decode_header:
(Pdb)
(pdb) という表示は対話モードのプロンプトです。ここで使用できるコマンドについてはhelpと入力して調べてみてください。たとえば list (あるいはl)と入力すると前後のソースコードが表示されます。
24 debug=1
25 def tojis(s, enc, decode_header = False):
26 """ Convert to 'iso-2022-jp' encoding from encoding enc.
27 """
28 import pdb;pdb.set_trace()
29 -> if decode_header:
30 us = u''
31 for senc in email.Header.decode_header(s):
32 hs, henc = senc
33 if henc:
34 us += unicode(hs, henc, 'replace')
変数名などにもアクセスできるので、場合にもよりますがprint文を仕込むデバッグよりは色々な情報を集めることが出来ます。変数の値を表示するには変数名を入力します。また関数の引数の値一覧を表示するには args と入力します。
False
(Pdb) enc
'utf-8'
(Pdb) args
s = hogehoge
enc = utf-8
decode_header = False
(Pdb)
実行を進めるには next で関数呼び出しの中に入らずに次の行へ、 step で関数呼び出しの中に入って実行、 return で関数呼出元に戻る、 up, down で関数呼び出しスタックの上位、下位の参照などができます。
一定条件でのみdebugモードに
デバッグ中は、ある条件でだけbreakしたい場合などもあります。そのような場合は pdb.set_trace() をある条件でのみ実行するように埋め込んでおきます。たとえば以下のように記述すると、引数sにdebugという文字列が含まれる場合のみデバッグコンソールに移行することができるようになります。
""" Convert to 'iso-2022-jp' encoding from encoding enc.
"""
if 'debug' in s:
import pdb;pdb.set_trace()
if decode_header:
us = u''
Zopeを再起動せずにpdb埋め込みを反映
pdbを埋め込む対象のプロダクトがrefresh可能な場合、ZMIのControl_Panelsから対象プロダクトをrefreshする事が出来ます。これを応用すると、pdbを埋め込んだりした場合にZopeを再起動せずにデバッグすることが出来ます。
Zope本体や他のプロダクトの挙動を調べる
プロダクトの各コードはZope本体から必要なタイミングで呼び出されます。つまりプロダクトコードの呼出元は常にZope本体のコードなので、プロダクトに埋め込んだpdbの実行箇所からreturnを繰り返すことにより呼出元のZopeコードをたどることが出来ます。
また、Zope本体も大部分がpythonで記述されているので、Zopeのソースコードにpdbを埋め込んで実行することにより、step実行でZopeの挙動を追うことが出来ます。
こういった応用により、自分が作ったプロダクトの関数に渡ってくる値や返すべき値を調べたり、他のプロダクトと連携している場合はそれらのプログラムの挙動を調べることが出来るようになります。
スレッド数の変更
Zopeはデフォルトで2つ以上のスレッドで動作しています。このため、デバッグコンソールの対話モード中にも別のブラウザからのリクエストを別のスレッドが受け取ってしまい、デバッグコンソールがどのスレッドを扱っているのか分からなくなってしまうということも起きてしまいます。この問題は zope.conf のスレッド数を1に変更する方法で回避することが出来ます。
まとめ
pdb埋め込みによるデバッグコンソールでは、Pythonの対話モードとほぼ同じ事が出来るので、import文でモジュールを読み込んだり、Zopeや他のプロダクトのAPIの使い方を調べながら開発したり、など色々と応用する事が出来ます。
This How-to applies to: Zope 2.10.x, Zope 2.9.x, Zope 2.8.x, Zope 2.7.x