Поиск мертвого кода в большом проекте python

Я видел Как вы можете найти неиспользуемые функции в коде Python? но это действительно старо и не отвечает на мой вопрос.

У меня большой проект python с несколькими библиотеками, которые разделяются несколькими сценариями точек входа. Этот проект много лет носился со многими авторами, поэтому есть много мертвого кода. Вы знаете, что делать.

Я знаю, что найти все мертвые коды невозможно. Все, что мне нужно – это инструмент, который найдет все функции, которые нигде не называются. Мы ничего не делаем с вызовами функций, основанных на строке имени функции, поэтому я не беспокоюсь ни о чем патологическом …

Я просто установил pylint, но он, похоже, основан на файлах, и не уделяет много внимания зависимостям между файлами или даже зависимостям между функциями.

Ясно, что я мог бы grep для def во всех файлах, получить от них все имена функций и сделать grep для каждого из этих имен функций. Я просто надеюсь, что есть что-то более умное, чем это уже есть.

ETA: Обратите внимание, что я не ожидаю и не хочу что-то совершенное. Я знаю, что моя проблема с остановкой – так же хорошо, как и все (я действительно не преподавал теорию вычислений, которую знаю, когда я смотрю на то, что рекурсивно перечислимо). Любая вещь, которая пытается аппроксимировать ее, фактически запустив код, займет слишком много времени. Я просто хочу что-то синтаксически проходит через код и говорит: «Эта функция определенно используется. Эта функция МОЖЕТ использоваться, и эта функция, безусловно, НЕ используется, никто другой даже не знает, что она существует!» И первые две категории не важны.

  • Исключая абстрактные свойства отчетов об охвате
  • Организация папок и файлов для разработки Python
  • Учитывает ли cover.py функции и определения классов?
  • Форматирование десятичного выравнивания в Python
  • В Python, как мне декодировать кодировку GZIP?
  • Кто-нибудь нашел хороший набор плагинов для python для vim - в частности, для завершения модуля?
  • 7 Solutions collect form web for “Поиск мертвого кода в большом проекте python”

    Возможно, вам захочется попробовать стервятника . Он не может поймать все из-за динамической природы Python, но он ловит совсем немного, не требуя полного набора тестов, такого как cover.py, а другие должны работать.

    Попробуйте запустить cover.py Ned Batchelder .

    Coverage.py – это инструмент для оценки охвата кода программ Python. Он контролирует вашу программу, отмечая, какие части кода были выполнены, а затем анализирует источник, чтобы определить код, который мог быть выполнен, но не был.

    Очень сложно определить, какие функции и методы вызывать без выполнения кода, даже если код не делает каких-либо причудливых вещей. Обычные вызовы функций довольно легко обнаружить, но вызовы методов действительно сложны. Простой пример:

     class A(object): def f(self): pass class B(A): def f(self): pass a = [] a.append(A()) a.append(B()) a[1].f() 

    Ничего необычного здесь, но любой скрипт, который пытается определить, будут ли Af() или Bf() будет иметь довольно трудное время для этого, не выполняя фактически код.

    Хотя вышеприведенный код не делает ничего полезного, он, безусловно, использует шаблоны, которые появляются в реальном коде, а именно – размещение экземпляров в контейнерах. Реальный код обычно выполняет даже более сложные вещи – травление и рассыпание, иерархические структуры данных, условные обозначения.

    Как указывалось ранее, просто обнаружение простых функций в виде формы

     function(...) 

    или

     module.function(...) 

    будет довольно легко. Вы можете использовать модуль ast для анализа ваших исходных файлов. Вам нужно будет записать весь импорт и имена, используемые для импорта других модулей. Вам также необходимо будет отслеживать определения функций верхнего уровня и вызовы внутри этих функций. Это даст вам график зависимостей, и вы можете использовать NetworkX для обнаружения подключенных компонентов этого графика.

    Хотя это может показаться довольно сложным, возможно, это может быть сделано с менее чем 100 строк кода. К сожалению, почти все основные проекты Python используют классы и методы, поэтому это будет мало помогать.

    Вот решение, которое я использую, по крайней мере, предварительно:

     grep 'def ' *.py > defs # ... # edit defs so that it just contains the function names # ... for f in `cat defs` do cat $f >> defCounts cat *.py | grep -c $f >> defCounts echo >> defCounts done 

    Затем я смотрю на отдельные функции, у которых очень мало ссылок (<3)

    это уродливо, и это дает мне приблизительные ответы, но я думаю, что это достаточно хорошо для начала. Какие у вас мысли?

    В следующей строке вы можете перечислить все определения функций, которые явно не используются в качестве атрибута, вызов функции, декоратор или возвращаемое значение. Таким образом, это примерно то, что вы ищете. Он не идеален, он медленный, но у меня никогда не было никаких ложных срабатываний. (С linux вам нужно заменить ack на ack-grep )

     for f in $(ack --python --ignore-dir tests -h --noheading "def ([^_][^(]*).*\):\s*$" --output '$1' | sort| uniq); do c=$(ack --python -ch "^\s*(|[^#].*)(@|return\s+|\S*\.|.*=\s*|)"'(?<!def\s)'"$f\b"); [ $c == 0 ] && (echo -n "$f: "; ack --python --noheading "$f\b"); done 

    Если у вас есть код с большим количеством тестов (это вообще очень полезно), запустите их с плагином кода и вы можете увидеть неиспользуемый код.)

    IMO, которая может быть достигнута довольно быстро с помощью простого плагина pylint, который:

    • помните каждую анализируемую функцию / метод (/ класс?) в наборе S1
    • отслеживать каждую вызванную функцию / метод (/ класс?) в наборе S2
    • отобразить S1 – S2 в отчете

    Тогда вам придется называть pylint на всей вашей базе кода, чтобы получить что-то, что имеет смысл. Конечно, как сказано, это нужно будет проверить, так как могут быть неудачи вывода или такие, которые приведут к ложному срабатыванию. Во всяком случае, это, вероятно, значительно снизит количество grep.

    У меня не так много времени, чтобы сделать это самостоятельно, но каждый найдет помощь в списке рассылки python-projects@logilab.org.

    Python - лучший язык программирования в мире.