Vulture は、Python プログラム内の未使用のコードを見つけます。これは、大規模なコード ベースのエラーをクリーンアップして検出するのに役立ちます。ライブラリとテスト スイートの両方で Vulture を実行すると、テストされていないコードが見つかる可能性があります。
Python の動的な性質により、Vulture のような静的コード アナライザーはデッド コードを見逃してしまう可能性があります。また、暗黙的にのみ呼び出されるコードは、未使用として報告される場合があります。それにもかかわらず、Vulture はコードの品質を高めるための非常に役立つツールです。
--sort-by-size
を使用して、未使用のクラスと関数をサイズで並べ替えます $ pip install vulture
$ vulture myscript.py # or
$ python3 -m vulture myscript.py
$ vulture myscript.py mypackage/
$ vulture myscript.py --min-confidence 100 # Only report 100% dead code.
指定される引数は Python ファイルまたはディレクトリです。 Vulture はディレクトリごとに、含まれるすべての*.pyファイルを分析します。
デッドコードを見つけて削除した後、Vulture を再度実行します。これは、さらにデッドコードを検出する可能性があるためです。
Vulture は、未使用の関数やクラスなどを見つけるだけでなく、到達不能なコードを検出することもできます。デッド コードの各チャンクには 60% ~ 100% の信頼値が割り当てられます。値 100% は、コードが実行されないことが確実であることを示します。 100% 未満の値は、コードが使用されない可能性の非常に大まかな推定 (コード チャンクのタイプに基づく) です。
コードの種類 | 信頼値 |
---|---|
関数/メソッド/クラスの引数、到達不能なコード | 100% |
輸入 | 90% |
属性、クラス、関数、メソッド、プロパティ、変数 | 60% |
--min-confidence
フラグを使用して、コードが未使用として報告される最小信頼度を設定できます。分析されたファイル内で未使用であることが保証されているコードのみを報告するには、 --min-confidence 100
を使用します。
Vulture がコードのチャンクを未使用として誤って報告した場合、誤検知を抑制するためのオプションがいくつかあります。誤検知を修正することで他のユーザーにも利益がもたらされる場合は、問題レポートを提出してください。
推奨されるオプションは、未使用として報告されている使用済みコードを Python モジュールに追加し、スキャンされたパスのリストに追加することです。このようなホワイトリストを自動的に取得するには、 --make-whitelist
Vulture に渡します。
$ vulture mydir --make-whitelist > whitelist.py
$ vulture mydir whitelist.py
生成されるwhitelist.py
ファイルには有効なPython構文が含まれていますが、Pythonで実行できるようにするには、通常、いくつかの変更を加える必要があることに注意してください。
一般的な Python モジュールとパッケージのホワイトリストをvulture/whitelists/
に収集しています (プル リクエストは歓迎です)。
ファイルまたはディレクトリ全体を無視したい場合は、 --exclude
パラメータを使用します (例: --exclude "*settings.py,*/docs/*.py,*/test_*.py,*/.venv/*.py"
)。除外パターンは絶対パスと照合されます。
flake8 との互換性のために、Vulture は未使用のインポート ( # noqa: F401
) と未使用のローカル変数 ( # noqa: F841
) を無視するための F401 および F841 エラー コードをサポートします。ただし、 noqa
コメントはコードに視覚的なノイズを追加し、読みにくくするため、 noqa
コメントの代わりにホワイトリストを使用することをお勧めします。
--ignore-names foo*,ba[rz]
を使用すると、Vulture がfoo
で始まるすべての名前と、 bar
およびbaz
名前を無視できます。さらに、 --ignore-decorators
オプションを使用すると、指定されたデコレータで修飾された関数の名前を無視できます (ただし、引数や関数本体は無視しません)。これは、たとえば--ignore-decorators "@app.route"
を使用して@app.route
デコレータを持つすべての関数名を無視できる Flask プロジェクトで役立ちます。 Vulture は解析できないデコレータを簡素化していることに注意してください。 @foo.bar(x, y)
は "@foo.bar" になり、 @foo.bar(x, y).baz
内部的に "@" になります。
ホワイトリスト--ignore-decorators
--ignore-names
Vulture に渡されるときに構文の正しさが自動的にチェックされ、多くの場合、それらを Python インタープリタに渡して、すべてがホワイトリストに登録されていることをチェックさせることもできるため、可能な限り --ignore-names や --ignore-decorators の代わりにホワイトリストを使用することをお勧めします。コードは実際にはプロジェクト内にまだ存在します。
関数シグネチャなど、未使用の変数を単純に削除できない状況があります。推奨される解決策は、PyLint マニュアルおよび StackOverflow で説明されているように、 del
キーワードを使用することです。
def foo ( x , y ):
del y
return x + 3
また、Vulture はアンダースコアで始まるすべての変数を無視するため、 _x, y = get_pos()
使用して、未使用のタプル代入または関数引数 (例: def foo(x, _y)
をマークできます。
--min-confidence
フラグを使用して、最小信頼値を上げます。
Vulture がif False:
のようなコードについて文句を言う場合は、ブール値フラグdebug = False
を使用し、代わりにif debug:
と書くことができます。これにより、コードが読みやすくなり、Vulture が沈黙します。
#216を参照してください。たとえば、 def foo(arg: "Sequence"): ...
の代わりに、次を使用することをお勧めします。
from __future__ import annotations
def foo ( arg : Sequence ):
...
コマンド ライン引数をpyproject.toml
のtool.vulture
セクションに保存することもできます。先頭のダッシュを削除し、残りのダッシュをすべてアンダースコアに置き換えるだけです。
コマンドラインで指定されたオプションは、 pyproject.toml
のオプションより優先されます。
設定例:
[ tool . vulture ]
exclude = [ " *file*.py " , " dir/ " ]
ignore_decorators = [ " @app.route " , " @require_* " ]
ignore_names = [ " visit_* " , " do_* " ]
make_whitelist = true
min_confidence = 80
paths = [ " myscript.py " , " mydir " , " whitelist.py " ]
sort_by_size = true
verbose = true
Vulture は、現在の作業ディレクトリでpyproject.toml
を自動的に検索します。
別のディレクトリでpyproject.toml
使用するには、 --config path/to/pyproject.toml
フラグを使用します。
コミット前フックを使用して、各コミットの前に Vulture を実行できます。このためには、pre-commit をインストールし、リポジトリの.pre-commit-config.yaml
ファイルに以下を追加します。
repos :
- repo : https://github.com/jendrikseipp/vulture
rev : ' v2.3 ' # or any later Vulture version
hooks :
- id : vulture
次に、 pre-commit install
実行します。最後に、リポジトリにpyproject.toml
ファイルを作成し、 [tool.vulture] --> paths
(上記を参照) で Vulture がチェックする必要があるすべてのファイルを指定します。
Vulture 用の GitHub Action もあり、プログラムで Vulture を使用できます。例えば:
import vulture
v = vulture . Vulture ()
v . scavenge ([ '.' ])
unused_code = v . get_unused_code () # returns a list of `Item` objects
Vulture は、 ast
モジュールを使用して、指定されたすべてのファイルの抽象構文ツリーを構築します。すべての構文ツリーを走査しながら、定義済みおよび使用されているオブジェクトの名前を記録します。その後、定義されているが使用されていないオブジェクトを報告します。この分析ではスコープは無視され、オブジェクト名のみが考慮されます。
Vulture はまた、 return
、 break
、 continue
、 raise
ステートメントの後のコードを検索したり、満たされないif
やwhile
条件を検索したりすることによって、到達不能なコードを検出します。
--sort-by-size
オプションを使用すると、Vulture は未使用のコードを行数で並べ替えます。これは、開発者がデッドコードを最初に探す場所の優先順位を付けるのに役立ちます。
次の Python スクリプト ( dead_code.py
) について考えてみましょう。
import os
class Greeter :
def greet ( self ):
print ( "Hi" )
def hello_world ():
message = "Hello, world!"
greeter = Greeter ()
func_name = "greet"
greet_func = getattr ( greeter , func_name )
greet_func ()
if __name__ == "__main__" :
hello_world ()
電話をかける:
$ vulture dead_code.py
結果は次の出力になります。
dead_code.py:1: unused import 'os' (90% confidence)
dead_code.py:4: unused function 'greet' (60% confidence)
dead_code.py:8: unused variable 'message' (60% confidence)
Vulture は、 os
とmessage
未使用として正しく報告しますが、 greet
実際に使用されていることを検出できません。このような誤検知に対処するための推奨方法は、ホワイトリスト Python ファイルを作成することです。
ホワイトリストの準備
ホワイトリストでは、変数、属性などの使用法をシミュレートします。上記のプログラムの場合、ホワイトリストは次のようになります。
# whitelist_dead_code.py
from dead_code import Greeter
Greeter . greet
あるいは、 --make-whitelist
Vulture に渡して、自動生成されたホワイトリストを取得することもできます。
元のプログラムとホワイトリストの両方を Vulture に渡す
$ vulture dead_code.py whitelist_dead_code.py
Vulture がgreet
メソッドを無視するようにします。
dead_code.py:1: unused import 'os' (90% confidence)
dead_code.py:8: unused variable 'message' (60% confidence)
終了コード | 説明 |
---|---|
0 | デッドコードは見つかりませんでした |
1 | 無効な入力 (ファイルの欠落、構文エラー、間違ったエンコード) |
2 | 無効なコマンドライン引数 |
3 | デッドコードが見つかりました |
問題を報告したりプルリクエストを行ったりするには、https://github.com/jendrikseipp/vulture にアクセスしてください。