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 поддерживает коды ошибок 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 и добавьте следующее в файл .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
(см. выше).
Также есть действие GitHub для Vulture, и вы можете использовать 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, чтобы сообщить о любых проблемах или сделать запросы на включение.