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 能夠運行它,您通常需要進行一些修改。
我們在vulture/whitelists/
中收集常見 Python 模組和套件的白名單(歡迎拉取請求)。
如果您想忽略整個檔案或目錄,請使用--exclude
參數(例如--exclude "*settings.py,*/docs/*.py,*/test_*.py,*/.venv/*.py"
)。排除模式與絕對路徑進行比對。
為了與 flake8 相容,Vulture 支援 F401 和 F841 錯誤代碼,以忽略未使用的導入 ( # noqa: F401
) 和未使用的局部變數 ( # noqa: F841
)。但是,我們建議使用白名單而不是noqa
註釋,因為noqa
註釋會增加程式碼的視覺幹擾並使其難以閱讀。
您可以使用--ignore-names foo*,ba[rz]
讓 Vulture 忽略所有以foo
開頭的名稱以及名稱bar
和baz
。此外, --ignore-decorators
選項可用於忽略用給定裝飾器裝飾的函數名稱(但不是它們的參數或函數體)。這在 Flask 專案中很有用,您可以使用--ignore-decorators "@app.route"
來忽略所有帶有@app.route
裝飾器的函數名稱。請注意,Vulture 簡化了它無法解析的裝飾器: @foo.bar(x, y)
變成“@foo.bar”, @foo.bar(x, y).baz
在內部變成“@”。
我們建議盡可能使用白名單而不是--ignore-names
或--ignore-decorators
,因為白名單在傳遞給Vulture 時會自動檢查語法正確性,通常您甚至可以將它們傳遞給Python 解釋器並讓它檢查所有白名單代碼實際上仍然存在於您的專案中。
在某些情況下,您不能只刪除未使用的變量,例如函數簽名中的變數。建議的解決方案是使用del
關鍵字,如 PyLint 手冊和 StackOverflow 所述:
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-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
文件,並指定 Vulture 應在[tool.vulture] --> paths
下檢查的所有文件(請參閱上文)。
還有一個針對 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 報告任何問題或提出拉取請求。