Vulture findet ungenutzten Code in Python-Programmen. Dies ist nützlich, um große Codebasen zu bereinigen und Fehler zu finden. Wenn Sie Vulture sowohl in Ihrer Bibliothek als auch in Ihrer Testsuite ausführen, können Sie ungetesteten Code finden.
Aufgrund der dynamischen Natur von Python übersehen statische Code-Analysatoren wie Vulture wahrscheinlich toten Code. Außerdem kann Code, der nur implizit aufgerufen wird, als nicht verwendet gemeldet werden. Dennoch kann Vulture ein sehr hilfreiches Tool für eine höhere Codequalität sein.
--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.
Die bereitgestellten Argumente können Python-Dateien oder -Verzeichnisse sein. Für jedes Verzeichnis analysiert Vulture alle enthaltenen *.py- Dateien.
Nachdem Sie toten Code gefunden und gelöscht haben, führen Sie Vulture erneut aus, da möglicherweise weiterer toter Code entdeckt wird.
Vulture kann nicht nur ungenutzte Funktionen, Klassen usw. finden, sondern auch nicht erreichbaren Code erkennen. Jedem Teil des toten Codes wird ein Konfidenzwert zwischen 60 % und 100 % zugewiesen, wobei ein Wert von 100 % signalisiert, dass der Code mit Sicherheit nicht ausgeführt wird. Werte unter 100 % sind sehr grobe Schätzungen (basierend auf der Art des Codeblocks), wie wahrscheinlich es ist, dass der Code nicht verwendet wird.
Codetyp | Vertrauenswert |
---|---|
Funktions-/Methoden-/Klassenargument, nicht erreichbarer Code | 100 % |
Import | 90 % |
Attribut, Klasse, Funktion, Methode, Eigenschaft, Variable | 60 % |
Sie können das Flag --min-confidence
verwenden, um die Mindestkonfidenz dafür festzulegen, dass Code als nicht verwendet gemeldet wird. Verwenden Sie --min-confidence 100
um nur Code zu melden, der in den analysierten Dateien garantiert nicht verwendet wird.
Wenn Vulture fälschlicherweise Codeabschnitte als ungenutzt meldet, haben Sie mehrere Möglichkeiten, die Fehlalarme zu unterdrücken. Wenn die Behebung Ihrer Fehlalarme auch anderen Benutzern zugute kommen könnte, reichen Sie bitte einen Problembericht ein.
Die empfohlene Option besteht darin, verwendeten Code, der als nicht verwendet gemeldet wird, einem Python-Modul hinzuzufügen und ihn der Liste der gescannten Pfade hinzuzufügen. Um eine solche Whitelist automatisch zu erhalten, übergeben Sie --make-whitelist
an Vulture:
$ vulture mydir --make-whitelist > whitelist.py
$ vulture mydir whitelist.py
Beachten Sie, dass die resultierende Datei whitelist.py
eine gültige Python-Syntax enthält. Damit Python sie jedoch ausführen kann, müssen Sie normalerweise einige Änderungen vornehmen.
Wir sammeln Whitelists für gängige Python-Module und -Pakete in vulture/whitelists/
(Pull-Requests sind willkommen).
Wenn Sie eine ganze Datei oder ein ganzes Verzeichnis ignorieren möchten, verwenden Sie den Parameter --exclude
(z. B. --exclude "*settings.py,*/docs/*.py,*/test_*.py,*/.venv/*.py"
). Die Ausschlussmuster werden mit absoluten Pfaden abgeglichen.
Aus Kompatibilitätsgründen mit flake8 unterstützt Vulture die Fehlercodes F401 und F841 zum Ignorieren nicht verwendeter Importe ( # noqa: F401
) und nicht verwendeter lokaler Variablen ( # noqa: F841
). Wir empfehlen jedoch die Verwendung von Whitelists anstelle von noqa
-Kommentaren, da noqa
-Kommentare dem Code visuelles Rauschen hinzufügen und ihn schwerer lesbar machen.
Sie können --ignore-names foo*,ba[rz]
verwenden, um Vulture alle Namen ignorieren zu lassen, die mit foo
beginnen, sowie die Namen bar
und baz
. Darüber hinaus kann die Option --ignore-decorators
verwendet werden, um die Namen von Funktionen zu ignorieren, die mit dem angegebenen Dekorator dekoriert sind (jedoch nicht deren Argumente oder Funktionskörper). Dies ist beispielsweise in Flask-Projekten hilfreich, wo Sie mit --ignore-decorators "@app.route"
alle Funktionsnamen mit dem @app.route
Dekorator ignorieren können. Beachten Sie, dass Vulture Dekoratoren vereinfacht, die es nicht analysieren kann: @foo.bar(x, y)
wird intern zu „@foo.bar“ und @foo.bar(x, y).baz
wird intern zu „@“.
Wir empfehlen, wann immer möglich, Whitelists anstelle von --ignore-names
oder --ignore-decorators
zu verwenden, da Whitelists automatisch auf syntaktische Korrektheit überprüft werden, wenn sie an Vulture übergeben werden. Oft können Sie sie sogar an Ihren Python-Interpreter übergeben und ihn überprüfen lassen, ob alle Whitelists vorhanden sind Der Code ist tatsächlich noch in Ihrem Projekt vorhanden.
Es gibt Situationen, in denen Sie ungenutzte Variablen nicht einfach entfernen können, z. B. in Funktionssignaturen. Die empfohlene Lösung besteht darin, das Schlüsselwort del
zu verwenden, wie im PyLint-Handbuch und auf StackOverflow beschrieben:
def foo ( x , y ):
del y
return x + 3
Vulture ignoriert auch alle Variablen, die mit einem Unterstrich beginnen, sodass Sie _x, y = get_pos()
verwenden können, um nicht verwendete Tupelzuweisungen oder Funktionsargumente zu markieren, z. B. def foo(x, _y)
.
Erhöhen Sie den minimalen Konfidenzwert mit der Flagge --min-confidence
.
Wenn Vulture sich über Code wie if False:
beschwert, können Sie ein boolesches Flag debug = False
verwenden und stattdessen if debug:
schreiben. Dies macht den Code besser lesbar und bringt Vulture zum Schweigen.
Siehe #216. Anstelle von def foo(arg: "Sequence"): ...
empfehlen wir beispielsweise die Verwendung
from __future__ import annotations
def foo ( arg : Sequence ):
...
Sie können Befehlszeilenargumente auch in pyproject.toml
im Abschnitt tool.vulture
speichern. Entfernen Sie einfach die führenden Bindestriche und ersetzen Sie alle verbleibenden Bindestriche durch Unterstriche.
In der Befehlszeile angegebene Optionen haben Vorrang vor Optionen in pyproject.toml
.
Beispielkonfiguration:
[ 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 sucht automatisch nach einer pyproject.toml
im aktuellen Arbeitsverzeichnis.
Um ein pyproject.toml
in einem anderen Verzeichnis zu verwenden, können Sie das Flag --config path/to/pyproject.toml
verwenden.
Sie können einen Pre-Commit-Hook verwenden, um Vulture vor jedem Commit auszuführen. Installieren Sie dazu pre-commit und fügen Sie Folgendes zur Datei .pre-commit-config.yaml
in Ihrem Repository hinzu:
repos :
- repo : https://github.com/jendrikseipp/vulture
rev : ' v2.3 ' # or any later Vulture version
hooks :
- id : vulture
Führen Sie dann pre-commit install
aus. Erstellen Sie abschließend eine pyproject.toml
Datei in Ihrem Repository und geben Sie unter [tool.vulture] --> paths
(siehe oben) alle Dateien an, die Vulture überprüfen soll.
Es gibt auch eine GitHub-Aktion für Vulture und Sie können Vulture programmgesteuert verwenden. Zum Beispiel:
import vulture
v = vulture . Vulture ()
v . scavenge ([ '.' ])
unused_code = v . get_unused_code () # returns a list of `Item` objects
Vulture verwendet das ast
Modul, um abstrakte Syntaxbäume für alle angegebenen Dateien zu erstellen. Beim Durchlaufen aller Syntaxbäume werden die Namen definierter und verwendeter Objekte aufgezeichnet. Anschließend werden die definierten, aber nicht verwendeten Objekte gemeldet. Bei dieser Analyse werden Bereiche ignoriert und nur Objektnamen berücksichtigt.
Vulture erkennt auch nicht erreichbaren Code, indem es nach den Anweisungen return
, break
, continue
und raise
nach Code sucht und nach unerfüllbaren if
und while
-Bedingungen sucht.
Bei Verwendung der Option --sort-by-size
sortiert Vulture nicht verwendeten Code nach der Anzahl der Zeilen. Dies hilft Entwicklern dabei, Prioritäten zu setzen, wo zuerst nach totem Code gesucht werden soll.
Betrachten Sie das folgende Python-Skript ( 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 ()
Aufruf:
$ vulture dead_code.py
führt zu folgender Ausgabe:
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 meldet os
und message
korrekt als nicht verwendet, erkennt jedoch nicht, dass greet
tatsächlich verwendet wird. Die empfohlene Methode zum Umgang mit solchen Fehlalarmen besteht darin, eine Whitelist-Python-Datei zu erstellen.
Whitelists vorbereiten
In einer Whitelist simulieren wir die Verwendung von Variablen, Attributen usw. Für das obige Programm könnte eine Whitelist wie folgt aussehen:
# whitelist_dead_code.py
from dead_code import Greeter
Greeter . greet
Alternativ können Sie --make-whitelist
an Vulture übergeben und eine automatisch generierte Whitelist erhalten.
Übergabe des Originalprogramms und der Whitelist an Vulture
$ vulture dead_code.py whitelist_dead_code.py
lässt Vulture die greet
-Methode ignorieren:
dead_code.py:1: unused import 'os' (90% confidence)
dead_code.py:8: unused variable 'message' (60% confidence)
Exit-Code | Beschreibung |
---|---|
0 | Kein toter Code gefunden |
1 | Ungültige Eingabe (Datei fehlt, Syntaxfehler, falsche Codierung) |
2 | Ungültige Befehlszeilenargumente |
3 | Toter Code gefunden |
Bitte besuchen Sie https://github.com/jendrikseipp/vulture, um etwaige Probleme zu melden oder Pull-Anfragen zu stellen.