|
カテゴリ:Python
Python の文法チェックには何を使う? lint はないの? で Python だと lint 相当のものは何があるということで pyChecker と pylint を取り上げたが、pyflakes もシンプルなので、うるさすぎる警告で肝心な警告を見逃すことがないからよいということで教えていただいた。
実を言うと、一回試して、ちゃんと動かない止めと思って書かなかったのだった。「pflks.py など pyflakes.py 以外の名前にリネームします(中で import pyflakes を実行してるので、pyflakes.py にすると自分自身をインポートしてしまう)。」、というところで、ろくすっぽ見ずに、これをやって投げてしまっていた。あほな。。。あらためて、yasusiiさんありがとうございます。 ということで、改めて pyflakes についても触れてみる。 pyflakes のコマンドを眺めてみると、最初に標準モジュールの compiler を使って (compiler.parse)、ソースコードをコンパイルしてしまい、構文木を得る。コンパイルエラーが出るようなコードであれば、エラーを表示する。コンパイルに成功した場合には、得られた構文木を pyflakes の checker.Checker にかけるという流れになっているようだ。 エラー処理や複数ファイルの処理をなくして、単純化して、途中の結果を見てみる。
そうすると次のような出力が得られる(長いのやるとすごい量になる)。
実際に pyflakes を実行したときに出力されるのは、最後の「a.py:1: 'sys' imported but unused」だけのシンプルなもの。pyflakes は、***** の部分のように構文解析されたものに対して、チェックしている。ということで、import 文があっても読み込むことはしないし、命令も実行されないので安全。上のチェックは下の意味のないコードにしたものだが、import sonnanonaiyo に対してはチェックがかからない。naiyo = sonnanonaiyo.usoclass() に対しても。要するに構文的に OK で、それが不使用でなければチェックはされない。import sys は、使われていないのでチェック対象になっている。 parser -- Python解析木にアクセスする、 19.3 Python 抽象構文。
これを pyChecker で試してみると、
と、import sonnanonaiyo の時点でエラーを出す。が、それ以上のチェックは行えない。要するに、pyChecker はインポート文を実行しながら動く。つまり、ファイルを読み込むときに実際にインポートしてしまうので (print "OK" は実行されてしまう)、自分で動きを把握してないものに対して使うと、インポートしたときに何があるか分からないのでセキュリティ上はよろしくない。これに対して、pyflakes は実際にはインポートしないので、その点は安全だし、インポートしないだけ軽く動く。逆に言えば、sonnanonaiyo というモジュールがあり、sonnanonaiyo.usoclass() を呼び出すコードがあったとき、usoclass() がないというのを pyChecker は sonnanonaiyo をインポートしているので、正しくあるなしを判定してくれるのに対して、pychecker は読み込まないので、構文的に正しければ、エラーにはならない。 このソースの場合、その点を除けば、pyChecker と pyflakes はほぼ同じような結果が得られる。要するに import sys だけがチェック対象。そして、途中にエラーがあるソースに対しては、エラーが出たところまでしかチェックすることができない。エラーのチェックという点では十分といえば十分。 では pylint を使うとどうなるか。pylint だけは、import できない行があっても気にせずに処理してくれる。そして、下のようなメッセージを出す。デフォルトの状態だと、まああれこれうるさい。チェック時に実際にインポートを実行してないという点では pyflakes と同様のメリットがある。E から始まっている行だけを grep などで絞り込んでしまえば、たくさんありすぎて重要なものを見失うということもなさそう(大量のソースをやると、まあ、それもあれだが)。おもしろいのは、W: 12:test_func: Unused argument 'x' で、 x は print 文で使っているけれども、こういうのもチェック対象になるところかな。 やはり、設定ファイルを自分でちゃんと作って、制御しないと辛いところがあるかもしれないのは事実。ちなみに、もし、sonnanonaiyo が存在して、test がないのに sonnanonaiyo.test() を呼び出せば、pylint は、「E: 13: Module 'sonnanonaiyo' has no 'usoclass' member」のようにチェックしてくれる。print の結果は表示されないので、命令を実行はしないけれど、ちゃんとインポートしているファイルは追跡している。
さらにおもしろいのは、エラー時のメッセージ量。
pyChecker と pyflakes はエラー箇所の文字列まで表示するのに対して、pylint は行と原因までしか分からない。 ざっくりとした印象として
pylint をちゃんと設定して使うのがよいのだろうけど、それもプロジェクトで本格的に使うのでなければ面倒ねと。 バランス的に、一定のレベルにある人がさくさくと使えて、最低限の要をなしてくれるプロが生産性のために pyflakes を好むのも分かる感じがする。けれども、ドキュメントストリングや変数名の規約を含めて複数の人間が一定の量のソースコードの品質を上げようとするならば pylint が好ましいとも思える。問題を分かった上で使うのであれば、pyChecker が個人で使うには、便利な面もある、けれど、やっぱり使うときに注意はすべきだし、本来デバグしているファイル以外の影響でインポート時に落ちてしまえば、そのファイルのチェックができないという弱点もある。 お気に入りの記事を「いいね!」で応援しよう
[Python] カテゴリの最新記事
|