Подтвердить что ты не робот

Идентификация "чувствительного" кода в приложении

Хотите улучшить качество довольно большого проекта Python. Я доволен типами предупреждений, которые дает PyLint. Тем не менее, они слишком многочисленны и трудны для обеспечения безопасности в рамках крупной организации. Также я считаю, что некоторый код более критичен/чувствителен, чем другие, в отношении того, где может появиться следующая ошибка. Например, я хотел бы потратить больше времени на проверку библиотечного метода, который используется 100 модулями, а не script, который последний раз касался 2 года назад и не может быть использован в производстве. Также было бы интересно знать модули, которые часто обновляются.

Кто-нибудь знаком с инструментами для Python или иным образом помогает в этом типе анализа?

4b9b3361

Ответ 1

Проблема аналогична той, которую я ответил в SQA https://sqa.stackexchange.com/a/3082. Эта проблема была связана с Java, которая сделала инструмент немного проще, но у меня есть ряд предложений ниже.

Ряд других ответов говорит о том, что для Python нет хороших инструментов времени исполнения. Я не согласен с этим несколькими способами:

  • Инструменты покрытия работают очень хорошо
  • Основываясь на моем опыте в инструментах в Java, инструменты статического и динамического анализа на Python слабее, чем на строго типизированном менее динамическом языке , но будет работать более чем достаточно, чтобы дать вам хорошую эвристику здесь, Если вы не используете необычно большое патологическое число динамических функций (включая методы добавления и удаления, метод перехвата и свойства, играя с импортом, вручную изменяя пространство имен) - в этом случае любые проблемы, которые могут возникнуть у вас, могут быть связаны с этим динамизмом..
  • Pylint поднимает более простые проблемы и не будет обнаруживать проблем с динамическими модификациями класса/экземпляра и декораторами - поэтому не имеет значения, что метрические инструменты не измеряют эти
  • В любом случае, где вы можете сфокусироваться, можно определить гораздо больше, чем график зависимостей.

Эвристика для выбора кода

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

Используйте свое мнение.

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

Вот, вот мои предложения:

Высокое значение для бизнеса. Например, любой код, который может стоить вашей компании много денег. Многие из них могут быть очевидными или широко известными (поскольку они важны), или их можно обнаружить, запустив важные варианты использования в системе с включенным профилировщиком во время выполнения. Я использую Coverage.

Показатели статического кода. Есть много показателей, но те, которые касаются нас, следующие:

  • Высокий афферентные соединения. Это код, от которого зависит множество других файлов. Хотя у меня нет инструмента, который напрямую выводит это, snakefood - это хороший способ сбросить зависимости напрямую к файлу, одну строку на каждую зависимость, каждый из которых является кортежем афферентного и эфферентного файла. Мне очень жаль это говорить, но вычисление афферентного значения связи из этого файла - простое упражнение, оставленное читателю.
  • Высокая сложность McCabe (цикломатическая). Это более сложный код. PyMetrics, кажется, производит эту меру, хотя я не использовал этот инструмент.
  • Размер. Вы можете получить удивительный объем информации, просмотрев размер вашего проекта с помощью визуализатора (например, https://superuser.com/questions/8248/how-can-i-visualize-the-file-system-usage-on-windows или https://superuser.com/questions/86194/good-program-to-visualize-file-system-usage-on-mac?lq=1. Linux имеет KDirStat в Filelight). Большие файлы - это хорошее место для начала, так как исправление одного файла устраняет многие предупреждения.

Обратите внимание, что эти инструменты основаны на файлах. Это, вероятно, достаточно точное разрешение, так как вы упоминаете, что сам проект содержит сотни модулей (файлов).

Часто меняются. Часто меняются коды, которые часто меняются. Код может:

  • Исторически было много дефектов, и эмпирически может продолжать это делать
  • Быть претерпевающим изменения в разработке функций (большое количество изменений в вашем VCS)

Найдите области изменений с помощью инструмента визуализации VCS, такого как те, которые обсуждаются ниже в этом ответе.

Непокрытый код. Код не распространяется на тесты.

Если вы запускаете (или можете запускать) ваши модульные тесты, ваши другие автоматизированные тесты и типичные пользовательские тесты с покрытием, посмотрите на пакеты и файлы, не имеющие охвата. Существует две логические причины, по которым нет покрытия:

  • Код необходим (и важен), но не проверен вообще (по крайней мере автоматически). Эти области представляют собой чрезвычайно высокий риск.
  • Код может быть не использован и является кандидатом на удаление.

Спросить других разработчиков

Вы можете быть удивлены метрикой "запаха", которую вы можете собрать, имея кофе с более длительными разработчиками. Бьюсь об заклад, они будут очень рады, если кто-то очистит грязную область кодовой базы, где только самые смелые души захотят.

Видимость - обнаружение изменений со временем

Я предполагаю, что ваша среда имеет DVCS (например, Git или Mercurial) или, по крайней мере, VCS (например, SVN). Надеюсь, что вы также используете проблему или какой-либо трекер ошибок. Если да, то имеется огромное количество информации. Это даже лучше, если разработчики надежно проверяют с комментариями и номерами выпуска. Но как вы его визуализируете и используете?

Хотя вы можете решить проблему на одном рабочем столе, возможно, неплохо создать среду непрерывной интеграции (CI), возможно, используя инструмент, например Jenkins. Чтобы ответить на короткий вопрос, я буду принимать Дженкинса с этого момента. Jenkins поставляется с большим количеством плагинов, которые действительно помогают в анализе кода. Я использую:

Это дает мне видимость изменений с течением времени, и я могу научиться оттуда. Например, предположим, что нарушения в PyLint начинают увеличиваться в модуле - у меня есть доказательства увеличения, и я знаю пакет или файл, в котором это происходит, поэтому я могу узнать, кто из них участвует и разговаривать с ними.

Если вам нужны исторические данные, и вы только что установили Jenkins, посмотрите, можете ли вы запустить несколько ручных сборок, которые начинаются в начале проекта, и выполнить серию переходов вперед по времени до настоящего времени. Вы можете выбрать теги релиза (или даты) из VCS.

Другая важная область, как упоминалось выше, - обнаружение локусов изменений в базе кода. Мне это действительно понравилось Atlassian Fisheye. Помимо того, что он действительно хорошо разбирается в сообщениях фиксации (например, идентификатор ошибки) или содержимом файла в любой момент времени, он позволяет легко видеть показатели:

  • Linecount по каталогу и подкаталогу
  • Коммиттеры в любой момент времени или в определенных каталогах и/или файлах
  • Шаблоны committal, как по времени, так и по местоположению в исходном коде

Ответ 2

Я боюсь, что вы в основном по своему усмотрению.

Если у вас есть достойный набор тестов, посмотрите на покрытие кода и мертвый код.

Если у вас есть достойная настройка профилирования, используйте это, чтобы получить представление о том, что используется больше.

В конце концов, кажется, вас больше интересует анализ вентилятора/вентилятора, я не знаю никаких хороших инструментов для Python, в первую очередь потому, что статический анализ ужасно ненадежен в отношении динамического языка и до сих пор Я не видел инструментов статистического анализа.

Я считаю, что эта информация доступна в компиляторах JIT - независимо от того, какие функции (функции, аргументы) находятся в кеше (скомпилированном), они используются больше всего. Независимо от того, сможете ли вы получить эти данные из, например, PyPy У меня действительно нет подсказки.

Ответ 3

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

Если у вас нет элемента управления источником, но проект запускается из общего места, удалите все папки pycache или .pyc. Со временем/в режиме просмотра наблюдайте, какие файлы воссозданы, чтобы указать их использование.

Анализ импорта Python, напечатанного при запуске из определенных точек входа с помощью

python -v entry_point

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

Для более навязчивого решения рассмотрите возможность настройки ведения журнала проекта. Вы можете легко регистрировать показатели даже в распределенных программах.

Ответ 4

Я согласен с остальными, поскольку мне еще предстоит найти хороший инструмент анализа времени выполнения для Python, который сделает это. Есть несколько способов справиться с этим, но ни один из них не является тривиальным.

Наиболее надежным, я думаю, было бы получить источник Python и перекомпилировать двоичные файлы с каким-то встроенным протоколом выполнения. Таким образом, вы можете просто вставить его в существующую среду без каких-либо изменений кода в свой проект. Конечно, это не совсем тривиально, но у этого есть бонус, который вы когда-нибудь сможете получить, чтобы объединить его обратно в багажник для будущих поколений, а что нет.

Для неперекомпиляционных подходов первое место, которое я бы посмотрел, - раздел дефинитивного профиля профилирования профиля.

Как вы его реализуете, будет сильно зависеть от настройки вашей среды. У вас есть много отдельных сценариев и проектов, выполняемых независимо друг от друга, или только один основной script или модуль или пакет, который используется всеми другими, и вы просто хотите знать, какие части его можно обрезать, чтобы сделать обслуживание Полегче? Является ли это нагрузкой один раз, запускает навсегда какую-либо настройку или ситуацию, когда вы просто запускаете сценарии атомарно в каком-то расписании?

Вы можете реализовать ведение журнала на уровне проекта (как указано в ответе @Hardbyte), но для этого потребуется пройти через проект и добавить строки ведения журнала ко всему вашему коду. Если вы это сделаете, вы можете просто сделать это, используя встроенный profiler, я думаю.

Ответ 5

Посмотрите sys.setprofile: он позволяет вам установить функцию профилирования.

Его использование подробно описано в http://docs.python.org/library/profile.html#profile, для перехода в начало здесь.

Если вы не можете профилировать свое приложение, вы будете привязаны к подходу к привязке.

Еще одна вещь, на которую вы могли бы обратить внимание, - это декораторы, вы можете написать отладка decorator и применить его к набору функций, которые вы подозреваете. Возьмите alook здесь, чтобы узнать, как применить декоратор ко всему модулю.

Вы также можете посмотреть график вызовов python, в то время как он не будет генерировать то, что вы хотите, он показывает вам, как часто одна функция вызывает другое:

Если ваш код работает на пользовательском вводе, это будет сложно, так как вам придется моделировать "типичное" использование.

Вам не о чем рассказать, просто запомните profiling как ключевое слово.

Ответ 6

Pylint иногда дает предупреждения, которые (после тщательного рассмотрения) не оправданы. В этом случае полезно использовать специальные #pylint: disable=X0123 комментарии (где X0123 является номер фактического номера ошибки/предупреждения), если код не может быть реорганизован, чтобы не вызывать предупреждение.

Я хотел бы упомянуть упоминание Hardbyte об использовании журналов управления источником, чтобы узнать, какие файлы чаще всего меняются.

Если вы работаете с системой, в которой установлены find, grep и sort, следующим способом является проверка того, какой файл импортирует:

find . -name '*.py' -exec grep -EH '^import|^from .* import' {} \+| sort |less

Чтобы найти самый популярный импорт во всех файлах,

find . -name '*.py' -exec grep -Eh '^import|^from .* import' {} \+ | sort | less

Эти две команды помогут вам найти наиболее используемые модули из вашего проекта.