Pylons におけるデバッグ方法
社内向けに書いたドキュメントですが、汎用的で役に立ちそうなので、少し手を入れて公開することにしました。
ログ出力
ファイルの先頭でログ出力用オブジェクトをを初期化し、以下のようにログを書き出してください。
import logging log = logging.getLogger(__name__) log.warn("Some Message")
デフォルトでは、サーバを実行しているコンソールにログが書き出されます。なお、 development.ini にログの設定を細かく書くことができます。詳しくは Logging を参照してください。
インタラクティブデバッガ
Pylons を debug=true で利用していると、エラー画面にデバッグ画面が表示されます。ここにはスタックトレースが表示され、各種変数を参照したり、Python コードを実行することができ、とても便利です。詳しくは Interactive Application Debugging を参照してください。
典型的なエラーを見て、間違いを発見する
例:
- KeyError: 辞書型に対応するkeyが存在しない
デバッグ画面のコンソールを利用する
デバッグ画面のコンソールでは、任意のコードを実行することができます。
>>> help(foo) >>> dir(foo) >>> foo() >>> foo.__dict__
インポートもできます。
>>> from pylons import config # 設定情報 >>> from pylons import request >>> request.environ
整形出力したい場合は、pprint が便利です。
>>> import pprint
>>> pprint.pprint(environ)
Extra Data タブ
設定情報( pylons.config )や environ の中身を確認することができます。
わざと例外を起こす
Pylons 開発で慣れている人が良く用いる手法だと思いますが、raise をコード中に書いてわざと例外を起こし、デバッグ画面を起動します。
なお、 raise の代わりに raise RuntimeError を記述すると、try ブロックの中などでも例外が補足されづらく、便利です。
environ に値を格納する
例外を発生させられない特別な場所で利用される変数の値などは、environ に参照したい値や関数を格納しておくと、別の場所で例外を起こしてもデバッグ画面で値を参照できます。
値の格納(ソースコード上)
from pylons import request request.environ["foo"] = some_value
値の参照(デバッグ画面)
>>> from pylons import request >>> request.environ["foo"]
Jinja の中で例外を起こす
Jinja の中で raise を実行することはできませんが、以下のような不正なコードで例外を発生させることができます。
{{ 0+"" }}
_ の振舞い
デバッグ画面のコンソール上では、 _ が特別な変数として認識され、1つ前に実行したコマンドの実行結果が格納されます。
この _ が国際化で利用される _ 関数と衝突するため、デバッグ画面を閉じた後に translate に関するエラーが表示されることがあります。このときはサーバを再起動してください。
Python シェルの _ については Python Quick Reference に説明があります。
注意事項
インタラクティブデバッガはセキュリティ上危険なので、リリース時には debug=False として、この画面を表示しないようにしましょう。
プロファイル
以下のコードを myproj.config.middleware でのアプリケーションの初期化に記述すると、デバッグモードで起動している際にページ下部にプロファイル情報を表示することができます。
if config.get('debug'): from paste.debug.profile import ProfileMiddleware app = ProfileMiddleware(app, global_conf)
profile_decorator というデコレータを利用することもできます。詳しくは下記のページを参照してください。
Python シェル
Python シェル
WEB アプリの初期化に依存しないようなコードの確認であれば、 Python シェルが使えます。なお、きめ細やかな操作をサポートしている ipython を入れておくことをお勧めします。
$ easy_install ipython
pdb
pdb を使うには、ソースコード内で割り込みたい個所に以下のようなコードを記述してください。paster serve を起動しているシェルで、 pdb のシェルが自動的に立ち上がります。
import pdb; pdb.set_trace()
pdb でよく使うコマンドには、以下のようなものがあります。
- help: ヘルプを表示
- n: 次へ
- s: 関数の中へ
- r: 1つ上へ
- p: 値を表示
- pp: 値を表示(pprint)
- help: ヘルプを表示
- q: pdbを抜ける
pdb シェル内で普通の python コマンドも実行できますが、先頭文字がコマンド文字列と同じ場合は、 ! を先頭につけてください。
(Pdb) !p = 1 (Pdb) p p 1
参考
emacs ユーザのための Tips
emacs 上でのコード実行
emacs に python-mode がインストールされている場合、C-c C-c (py-execute-buffer) でファイルの中身を直接実行できます。
if __name__ == "__main__" ブロック内のコードは、このファイルが直接実行されたときのみ実行されるため、ここにデバッグコードを書いて実行すると便利です。
def foo(): print "Hello World" if __name__ == "__main__": foo()
vc-annotate
M-x vc-annotate で Subversion の変更ログを見ることができます。
(vc-annotate で表示されている内容は、 :command:svn blame foo.txt を実行したときに見られる内容と同じです。)
- A: vc-annotate-revision-previous-to-line
- D: vc-annotate-show-diff-revision-at-line (diff 表示する)
- J: vc-annotate-revision-at-line
- L: vc-annotate-show-log-revision-at-line (ログ表示)
- N: vc-annotate-next-version
- P: vc-annotate-prev-version
- W: vc-annotate-workfile-version
なお、vc-annotate を表示した画面で describe-mode を実行すると、利用可能なコマンドの一覧が表示されます。
参考
posted by id:junya_hayashi