Vulture trouve du code inutilisé dans les programmes Python. Ceci est utile pour nettoyer et rechercher des erreurs dans de grandes bases de code. Si vous exécutez Vulture à la fois sur votre bibliothèque et sur votre suite de tests, vous pouvez trouver du code non testé.
En raison de la nature dynamique de Python, les analyseurs de code statique comme Vulture risquent de manquer du code mort. De plus, le code appelé uniquement implicitement peut être signalé comme inutilisé. Néanmoins, Vulture peut être un outil très utile pour une meilleure qualité de code.
--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.
Les arguments fournis peuvent être des fichiers ou des répertoires Python. Pour chaque répertoire, Vulture analyse tous les fichiers *.py contenus.
Après avoir trouvé et supprimé le code mort, exécutez à nouveau Vulture, car il pourrait découvrir davantage de code mort.
En plus de trouver les fonctions, classes, etc. inutilisées, Vulture peut détecter le code inaccessible. Chaque morceau de code mort se voit attribuer une valeur de confiance comprise entre 60 % et 100 %, où une valeur de 100 % indique qu'il est certain que le code ne sera pas exécuté. Les valeurs inférieures à 100 % sont des estimations très approximatives (basées sur le type de morceau de code) de la probabilité que le code soit inutilisé.
Type de code | Valeur de confiance |
---|---|
argument fonction/méthode/classe, code inaccessible | 100% |
importer | 90% |
attribut, classe, fonction, méthode, propriété, variable | 60% |
Vous pouvez utiliser l'indicateur --min-confidence
pour définir la confiance minimale pour que le code soit signalé comme inutilisé. Utilisez --min-confidence 100
pour signaler uniquement le code dont l'inutilisation est garantie dans les fichiers analysés.
Lorsque Vulture signale à tort des morceaux de code comme inutilisés, vous disposez de plusieurs options pour supprimer les faux positifs. Si la correction de vos faux positifs peut également bénéficier à d’autres utilisateurs, veuillez déposer un rapport de problème.
L'option recommandée consiste à ajouter le code utilisé signalé comme inutilisé à un module Python et à l'ajouter à la liste des chemins analysés. Pour obtenir automatiquement une telle liste blanche, transmettez --make-whitelist
à Vulture :
$ vulture mydir --make-whitelist > whitelist.py
$ vulture mydir whitelist.py
Notez que le fichier whitelist.py
résultant contiendra une syntaxe Python valide, mais pour que Python puisse l' exécuter , vous devrez généralement apporter quelques modifications.
Nous collectons des listes blanches pour les modules et packages Python courants dans vulture/whitelists/
(les demandes d'extraction sont les bienvenues).
Si vous souhaitez ignorer un fichier ou un répertoire entier, utilisez le paramètre --exclude
(par exemple, --exclude "*settings.py,*/docs/*.py,*/test_*.py,*/.venv/*.py"
). Les modèles d'exclusion sont comparés aux chemins absolus.
Pour des raisons de compatibilité avec flake8, Vulture prend en charge les codes d'erreur F401 et F841 pour ignorer les importations inutilisées ( # noqa: F401
) et les variables locales inutilisées ( # noqa: F841
). Cependant, nous vous recommandons d'utiliser des listes blanches au lieu des commentaires noqa
, car les commentaires noqa
ajoutent du bruit visuel au code et le rendent plus difficile à lire.
Vous pouvez utiliser --ignore-names foo*,ba[rz]
pour permettre à Vulture d'ignorer tous les noms commençant par foo
et les noms bar
et baz
. De plus, l'option --ignore-decorators
peut être utilisée pour ignorer les noms des fonctions décorées avec le décorateur donné (mais pas leurs arguments ou le corps de la fonction). Ceci est utile par exemple dans les projets Flask, où vous pouvez utiliser --ignore-decorators "@app.route"
pour ignorer tous les noms de fonctions avec le décorateur @app.route
. Notez que Vulture simplifie les décorateurs qu'il ne peut pas analyser : @foo.bar(x, y)
devient "@foo.bar" et @foo.bar(x, y).baz
devient "@" en interne.
Nous vous recommandons d'utiliser des listes blanches au lieu de --ignore-names
ou --ignore-decorators
autant que possible, car les listes blanches sont automatiquement vérifiées pour leur exactitude syntaxique lorsqu'elles sont transmises à Vulture et vous pouvez souvent même les transmettre à votre interpréteur Python et le laisser vérifier que toutes les listes blanches sont sur la liste blanche. le code existe toujours dans votre projet.
Il existe des situations dans lesquelles vous ne pouvez pas simplement supprimer les variables inutilisées, par exemple dans les signatures de fonctions. La solution recommandée consiste à utiliser le mot-clé del
comme décrit dans le manuel PyLint et sur StackOverflow :
def foo ( x , y ):
del y
return x + 3
Vulture ignorera également toutes les variables commençant par un trait de soulignement, vous pouvez donc utiliser _x, y = get_pos()
pour marquer les affectations de tuples ou les arguments de fonction inutilisés, par exemple, def foo(x, _y)
.
Augmentez la valeur de confiance minimale avec l'indicateur --min-confidence
.
Si Vulture se plaint d'un code comme if False:
, vous pouvez utiliser un indicateur booléen debug = False
et écrire if debug:
à la place. Cela rend le code plus lisible et fait taire Vulture.
Voir #216. Par exemple, au lieu de def foo(arg: "Sequence"): ...
, nous vous recommandons d'utiliser
from __future__ import annotations
def foo ( arg : Sequence ):
...
Vous pouvez également stocker les arguments de ligne de commande dans pyproject.toml
sous la section tool.vulture
. Supprimez simplement les tirets de début et remplacez tous les tirets restants par des traits de soulignement.
Les options données sur la ligne de commande ont priorité sur les options de pyproject.toml
.
Exemple de configuration :
[ 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 recherchera automatiquement un pyproject.toml
dans le répertoire de travail actuel.
Pour utiliser un pyproject.toml
dans un autre répertoire, vous pouvez utiliser l'indicateur --config path/to/pyproject.toml
.
Vous pouvez utiliser un hook de pré-validation pour exécuter Vulture avant chaque validation. Pour cela, installez pre-commit et ajoutez ce qui suit au fichier .pre-commit-config.yaml
dans votre référentiel :
repos :
- repo : https://github.com/jendrikseipp/vulture
rev : ' v2.3 ' # or any later Vulture version
hooks :
- id : vulture
Ensuite, exécutez pre-commit install
. Enfin, créez un fichier pyproject.toml
dans votre référentiel et spécifiez tous les fichiers que Vulture doit vérifier sous [tool.vulture] --> paths
(voir ci-dessus).
Il existe également une action GitHub pour Vulture et vous pouvez utiliser Vulture par programmation. Par exemple:
import vulture
v = vulture . Vulture ()
v . scavenge ([ '.' ])
unused_code = v . get_unused_code () # returns a list of `Item` objects
Vulture utilise le module ast
pour créer des arbres de syntaxe abstraite pour tous les fichiers donnés. En parcourant toutes les arborescences syntaxiques, il enregistre les noms des objets définis et utilisés. Ensuite, il rapporte les objets qui ont été définis, mais non utilisés. Cette analyse ignore les étendues et prend uniquement en compte les noms d'objets.
Vulture détecte également le code inaccessible en recherchant le code après les instructions return
, break
, continue
et raise
, et en recherchant les conditions if
et while
insatisfaisantes.
Lorsque vous utilisez l'option --sort-by-size
, Vulture trie le code inutilisé en fonction de son nombre de lignes. Cela aide les développeurs à prioriser où rechercher le code mort en premier.
Considérez le script Python suivant ( 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 ()
Appel :
$ vulture dead_code.py
donne le résultat suivant :
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 signale correctement os
et message
comme inutilisés, mais il ne parvient pas à détecter que greet
est réellement utilisé. La méthode recommandée pour traiter les faux positifs comme celui-ci consiste à créer un fichier Python sur liste blanche.
Préparation des listes blanches
Dans une liste blanche, nous simulons l'utilisation de variables, d'attributs, etc. Pour le programme ci-dessus, une liste blanche pourrait ressembler à ceci :
# whitelist_dead_code.py
from dead_code import Greeter
Greeter . greet
Alternativement, vous pouvez transmettre --make-whitelist
à Vulture et obtenir une liste blanche générée automatiquement.
Passer à la fois le programme original et la liste blanche à Vulture
$ vulture dead_code.py whitelist_dead_code.py
fait que Vulture ignore la méthode greet
:
dead_code.py:1: unused import 'os' (90% confidence)
dead_code.py:8: unused variable 'message' (60% confidence)
Code de sortie | Description |
---|---|
0 | Aucun code mort trouvé |
1 | Entrée invalide (fichier manquant, erreur de syntaxe, mauvais encodage) |
2 | Arguments de ligne de commande invalides |
3 | Code mort trouvé |
Veuillez visiter https://github.com/jendrikseipp/vulture pour signaler tout problème ou pour faire des demandes d'extraction.