tabnanny – インデントバリデータ

目的:Python のソースコードから不審なインデントを探して検査する
利用できるバージョン:2.1.3 以上

Python のようなプログラミング言語では、スペースが重要な意味を持つので一貫したインデントを使用することが重要です。 tabnanny モジュールは “不明瞭な” インデントの使用を検出する機能を提供します。

コマンドラインから実行する

tabnanny を使用する最も簡単な方法は検査するファイル名を渡してコマンドラインから実行します。ディレクトリ名を渡せば、そのディレクトリに含まれる .py を再帰的に探して検査します。

PyMOTW のソースコードに対して tabnanny を実行したとき、スペースではなくタブでコーディングされた古いモジュールを発見しました。

$ python -m tabnanny .
./PyMOTW/Queue/fetch_podcasts.py 78 "\t\tfor enclosure in entry.get('enclosures', []):\n"

案の定 fetch_podcasts.py の78行目に8つのスペースではなく2つのタブがありました。私は tabstop を4スペースに設定していて見た目には違いがないので、エディタで見ているだけではこのことを見つけられませんでした。

for enclosure in entry.get('enclosures', []):
    print 'Queuing:', enclosure['url']
    enclosure_queue.put(enclosure['url'])

78行目を修正してもう一度 tabnanny を実行すると79行目に別のエラーが出ました。最後にもう一度80行目にも問題がありました。

ファイルを検査してもエラーの詳細を見たくないなら、ファイル名以外の情報を抑制する -q オプションを使用します。

$ python -m tabnanny -q .
./PyMOTW/Queue/fetch_podcasts.py

検査対象ファイルのもっと詳細な情報を見るには -v オプションを使用してください。

$ python -m tabnanny -v ./PyMOTW/Queue
'./PyMOTW/Queue': listing directory
'./PyMOTW/Queue/__init__.py': Clean bill of health.
'./PyMOTW/Queue/feedparser.py': Clean bill of health.
'./PyMOTW/Queue/fetch_podcasts.py': *** Line 78: trouble in tab city! ***
offending line: "\t\tfor enclosure in entry.get('enclosures', []):\n"
indent not greater e.g. at tab sizes 1, 2

プログラム内から使用する

Queue のサンプルプログラムの間違いを見つけてすぐに私は PyMOTW のビルド処理に自動チェックを追加することに決めました。私は paver tabcheck を実行して PyMOTW のコードを検査できるのように PyMOTW の pavement.py ビルドスクリプトに tabcheck タスクを作成しました。これは tabnanny はパブリック API として check() 関数を提供するので実現できます。

ここに Paver のタスク定義を理解していなくても使える tabnanny のサンプルがあります。

import sys
import tabnanny

# 冗長モードを有効にする
tabnanny.verbose = 1

for dirname in sys.argv[1:]:
    tabnanny.check(dirname)

実行結果です。

$ python tabnanny_check.py ../Queue
'../Queue': listing directory
'../Queue/__init__.py': Clean bill of health.
'../Queue/feedparser.py': Clean bill of health.
'../Queue/fetch_podcasts.py': *** Line 78: trouble in tab city! ***
offending line: "\t\tfor enclosure in entry.get('enclosures', []):\n"
indent not greater e.g. at tab sizes 1, 2

Note

PyMOTW コードに対してこれらのサンプルプログラムを実行しても、今回のリリースで私がコードを修正したので同じエラーは検出されません。

See also

tabnanny
本モジュールの標準ライブラリドキュメント
tokenize
Python ソースコードの字句解析器
Bookmark and Share