【Python】ast ライブラリを使用した簡易コードチェッカー

どうもです、タドスケです。

先日公開した、型ヒントの付け忘れをチェックしてくれるスクリプト。

同じようなやり方で他のチェックもできないか、いろいろと試行錯誤した結果、新たに2つの機能ができました。

  1. ローカル変数の再代入を行っている箇所を検出する機能
  2. docstring と実装が異なる(引数、戻り値が一致していない)箇所を検出する機能

先日の型ヒントチェック機能もまとめて一つのツールとして公開します。

目次

公開先

ソースコードは GitHub で公開しています。

tadosuke/code_checker: Python コードをチェックするスクリプト集 (github.com)

使いかた

チェック項目の確認・編集

code_checker/main.py を開き、頭のほうにあるチェック項目テーブルを確認します。

# チェック項目
_CHECKER_CLASS_LIST = (
    ReassignmentChecker,  # ローカル変数の再代入チェック
    DocstringChecker,  # docstring の整合性チェック
    TypeHintChecker,  # 型ヒントチェック
)

チェック項目ごとにクラス名が並んでいるので、チェックしたくない項目がある場合はコメントアウトしてください。

ツールの登録

PyCharm の外部ツールに code_checker/main.py を登録し、引数に「$FilePath$」を追加します。

ツールの実行

チェックしたいコードのタブの右クリックメニューから、登録したツールが実行できます。

実行結果

以下のテストコードについて実行した場合…

class MyClass:
    def __init__(self, number: int) -> None:
        self._a = number
    @property
    def a(self) -> int:
        """プロパティ."""
        return self._a
def func_a(name):
    """関数A.
    :param number: 数字
    """
    x = 1
    y = name
    x = 2
def _func_b(name: str) -> None:
    pass

コンソールに以下のように出力されます。

[ReassignmentChecker]
ローカル変数 ‘x’ は再代入されています。(20 行目)

[DocstringChecker]
func_a 関数で name が docstring にありません。(13 行目)

[TypeHintChecker]
func_a 関数の引数 name に型ヒントがありません。(13 行目)
func_a 関数の戻り値に型ヒントがありません。(13 行目)

例外設定

解析の際には、いくつか例外ルールを設けています。

  • 非公開関数は docstring がなくてもエラーにしない
  • init 関数の説明はクラスの docstring に書くので、init 関数の docstring がなくてもエラーにしない
  • 「test_」から始まるコードはテストコードとみなし、型ヒントチェックを行わない
  • self, cls などの予約語引数は型ヒントチェックを行わない

このあたりをカスタマイズしたい方は、GitHub のコードをクローンして各自で編集してください。

今後の予定

コードの解析には ast という Python の標準ライブラリを使っています。

解析をする場合はこれでも特に不足はないのですが、元のコードを書き換えたい場合、ast だと「空白行などの情報が消えてしまう」という問題があります。

これを解消する方法として、Meta が出している「LibCST — LibCST documentation」というオープンソースライブラリがあるらしいのですが、現時点では日本語の情報がほとんどないため、検証に手間取っています。

しかし元のコードの構造を変えずに、必要な箇所だけを自動で修正できるようになれば、さらにできることの幅は広がりそうです。

うまく使いこなせたら、また記事を書きたいと思います。

追記:既存のツール

後から知ったことなのですが、docstring の整合性チェックについては、pydocstyle という既存のツールがありました💦

他の機能についても探したら見つかりそうな気もするので、既存のツールについて調べてみたうえで、既存のツールにできない機能のみに絞って検証を進めたいと思います。

まあ、ast の使い方を学ぶよい機会にはなったかな😅

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次