Skip to main content

Script to track python project complexity

Project description

Анализ сложности проектов на python

Идея описана в статье моего блога - Управление простотой.

Кратко

Утилита для скоринга относительной сложности проекта. Сравнивать между собой проекты с её помощью не имеет большого смысла, идея в отслеживании динамики усложнения проекта в процессе его жизненного цикла. Комплексная метрика - попугаи.

Формат вывода

Запуск на самого себя. Если null в тестах это проблема - надо писать тесты, а не ныть.

app:
  lines: 437
  files: 5
  dependencies: 0
  directories: 0
  max_directory_depth: 0
  web:
    html:
      lines: 150
      files: 3
    css:
      lines: 200
      files: 1
    js:
      lines: 156
      files: 3
  functions:
    count: 34
    size_stats:
      min: 1
      mean: 10
      p90: 21
      p95: 27
      max: 31
  classes:
    count: 10
    size_stats:
      min: 2
      mean: 40
      p90: 295
      p95: 295
      max: 295
  imports:
    count: 26
    size_stats:
      min: 2
      mean: 5
      p90: 11
      p95: 11
      max: 11
tests:
  lines: 0
  files: 0
  dependencies: 0
  directories: 0
  max_directory_depth: 0
  functions:
    count: 0
    size_stats: null
  classes:
    count: 0
    size_stats: null
  imports:
    count: 0
    size_stats: null
logical:
  api_endpoints: 0
  event_subscriptions: 0
  periodic_tasks: 0
  integrated_systems: 0
complexity_score: 172

Длинно

Писалось по такому ТЗ (обвесил комментариями и отметил нереализованные пункты).

  1. Анализ физической структуры проекта:

    • Подсчёт строк кода (LOC) раздельно для основного кода и тестов
    • Подсчёт количества файлов (.py) раздельно для app и tests
    • Подсчёт количества директорий раздельно для app и tests
    • Определение максимальной глубины вложенности директорий (кажется почти бесполезным).
    • Подсчёт строк кода и количества файлов для веб-ресурсов (HTML, CSS, JS, Jinja2) в секции app.web
  2. Анализ кодовой базы:

    • Подсчёт количества классов раздельно для app и tests
    • Подсчёт количества функций раздельно для app и tests
    • Расчёт статистики размеров (min, mean, p90, p95, max) для классов и функций (p90, p95 и max совпадают в небольших проектах и не имеют значения).
    • Определение максимальной глубины наследования классов (кажется почти бесполезным).
  3. Анализ зависимостей:

    • Определение зависимостей из pyproject.toml
      • PEP 621
      • Poetry
    • Анализ requirements.txt, requirements-dev.txt, requirements-test.txt
    • Разделение зависимостей на основные (app) и тестовые (tests)
  4. Анализ логической структуры:

    • Обнаружение API эндпоинтов (FastAPI)
    • Подсчёт асинхронных событий (FastStream)
    • Выявление подписок на события (FastStream)
    • Обнаружение периодических задач (FastStream - оказалось ненужным).
    • Определение интеграций с внешними системами
      • PostgreSQL, Redis и др. (кажется почти бесполезным)
      • HTTP-клиенты / SDK в микросервисной архитектуре
  5. Расчёт комплексной метрики:

    • Вычисление единого коэффициента сложности проекта
    • Использование логарифмического масштабирования метрик
    • Жёстко заданные весовые коэффициенты для разных аспектов сложности, которые можно поправить "под себя", но я бы не стал. Всё равно это попугаи.
    • Учёт метрик веб-ресурсов (HTML, CSS, JS) при расчёте коэффициента сложности
  6. Фильтрация и игнорирование:

    • Автоматическое использование .gitignore
    • Автоматическое разделение на основной код и тесты по шаблонам имён
    • Пропуск бинарных и не-Python/веб файлов
  7. Обработка ошибок:

    • Устойчивость к синтаксическим ошибкам в коде
    • Обработка проблем с кодировкой файлов
  8. Вывод результатов:

    • Машинно- и человеко-читаемый YAML-подобный вывод.
    • Разделение метрик на логические группы (app, tests, logical, complexity_score).
    • Включение всех рассчитанных метрик
    • Чёткое отделение финального коэффициента сложности
    • Отображение метрик веб-ресурсов только в секции app, не в tests
  9. Производительность:

    • Никаких требований, но работает быстро.
  10. Интерфейс:

    • Принимает только один обязательный аргумент: путь к директории проекта
  11. Поддержка технологий:

    • Совместимость с FastAPI и FastStream
    • Поддержка Poetry и стандартных requirements.txt
    • Распознавание async/await функций
    • Поддержка HTML, CSS, JavaScript и Jinja2-шаблонов
  12. Статистическая обработка:

    • Корректная обработка пустых выборок
    • Устойчивость к выбросам в данных
  13. Архитектура:

    • Решил отклониться от "один python-скрипт без зависимостей"
    • "Плагинная" архитектура - достаточно докинуть новых файлов в plugins для поддержки других фреймворков, в том числе и самопальных/корпоративных.
  14. Практическая полезность:

    • Выявление "раздутых" компонентов (большие классы/функции)
    • Возможность сравнения динамики усложнения проекта (см /contrib/git-retrospective).

Например мой проект умного дома:

$ git-retrospective ../mqtt-automator/
1749975046 234
1740035384 232
1739383604 232
1738518493 232
1736532815 230
1735987780 228
1735918929 227
1735265996 219
1735189505 219
1735149143 216
1726594246 214
1726510704 214
1722049469 214
1716868950 214
1716783122 213
1716610147 211
1716539087 204
1716310019 201
1716027458 200
1715889436 191
1715882189 191

Эти данные можно использовать для отгрузки в какой-нибудь InfluxDB + добавить такое сканирование при каждом коммите и потом любоваться на графике в Grafana тем, как сложность проекта неуклонно ползла вверх и никакие рефакторинги этому не помогали.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

complexity_meter-0.0.2.tar.gz (14.3 kB view details)

Uploaded Source

File details

Details for the file complexity_meter-0.0.2.tar.gz.

File metadata

  • Download URL: complexity_meter-0.0.2.tar.gz
  • Upload date:
  • Size: 14.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.12

File hashes

Hashes for complexity_meter-0.0.2.tar.gz
Algorithm Hash digest
SHA256 cec11c44e0a9929eb01034be154525927688138769df162425f72492f980fd28
MD5 23d7f14a2505115ffdedc6a02ae677a2
BLAKE2b-256 57b00e93ce2a0ff9cbe1266b1306d50c347a3fdf85d0f6bb583c9964d6f86cf2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page