python3 system/scripts/audit_imports.py
Выведет сводку и детали найденных проблем.
# Справка
bash system/scripts/audit_imports_quick.sh help
# Полный аудит
bash system/scripts/audit_imports_quick.sh run
# Только ошибки
bash system/scripts/audit_imports_quick.sh errors
# Только неиспользуемые импорты
bash system/scripts/audit_imports_quick.sh unused
# Статистика по модулям
bash system/scripts/audit_imports_quick.sh stats
# Файлы с наибольшим количеством ошибок
bash system/scripts/audit_imports_quick.sh files
# Поиск ошибок для конкретного модуля
bash system/scripts/audit_imports_quick.sh module telegram
echo "Ошибки по типам:"
cut -d, -f1 audit_imports_report.csv | tail -n +2 | sort | uniq -c | sort -rn
# Вывод:
# 1704 ERROR_MODULE_NOT_FOUND
# 1154 WARNING_UNUSED
# 0 WARNING_DEPRECATED
# 0 ERROR_SYNTAX
# Ошибки в файле infra/@messenger.service/run.py
grep "infra/@messenger.service/run.py" audit_imports_report.csv
# Вывод:
# ERROR_MODULE_NOT_FOUND,infra/@messenger.service/run.py,28,src.bot_service,...
# ERROR_MODULE_NOT_FOUND,infra/@messenger.service/run.py,29,src.webhook_server,...
# ...
# Ошибки с модулем 'telegram'
grep ",telegram" audit_imports_report.csv | head -20
# Вывод файлов с ошибками 'telegram':
grep ",telegram" audit_imports_report.csv | cut -d, -f2 | sort -u
# Файлы с наибольшим количеством ошибок
grep "ERROR_" audit_imports_report.csv | \
cut -d, -f2 | sort | uniq -c | sort -rn | head -20
# Вывод:
# 47 projects/org/lideravto/app/mp1/solution/app/main.py
# 35 infra/@messenger.service/src/bot_service.py
# 28 projects/org/pirotehnika/app/mp1/solution/app/models.py
# Файлы с неиспользуемыми импортами (топ 15)
grep "WARNING_UNUSED" audit_imports_report.csv | \
cut -d, -f2 | sort | uniq -c | sort -rn | head -15
# conftest.py
import subprocess
import pytest
def test_imports_audit():
"""Проверить импорты при запуске тестов"""
result = subprocess.run(
["python3", "system/scripts/audit_imports.py"],
capture_output=True
)
assert result.returncode == 0, "Import audit failed"
# .git/hooks/pre-commit
#!/bin/bash
set -e
echo "Running import audit..."
python3 system/scripts/audit_imports.py
if [ $? -ne 0 ]; then
echo "❌ Fix import errors before committing"
exit 1
fi
echo "✅ Import audit passed"
.PHONY: audit audit-errors audit-stats
audit:
python3 system/scripts/audit_imports.py
audit-errors:
bash system/scripts/audit_imports_quick.sh errors
audit-stats:
bash system/scripts/audit_imports_quick.sh stats
audit-unused:
bash system/scripts/audit_imports_quick.sh unused
Использование:
make audit # полный аудит
make audit-errors # только ошибки
make audit-stats # статистика
make audit-unused # неиспользуемые импорты
# Найти файл с неиспользуемым импортом
grep "WARNING_UNUSED" audit_imports_report.csv | head -1
# WARNING_UNUSED,infra/@mail.service/check_mail.py,12,datetime.datetime,...
# Отредактировать файл и удалить строку 12:
# -from datetime import datetime
# +# datetime not used
# Перепроверить
python3 system/scripts/audit_imports.py | grep check_mail.py
# Проблема: infra/@messenger.service имеет относительные импорты
# Решение: Добавить __init__.py файлы
mkdir -p infra/@messenger.service/src/{adapters,bot,webhook}
touch infra/@messenger.service/__init__.py
touch infra/@messenger.service/src/__init__.py
touch infra/@messenger.service/src/adapters/__init__.py
# Обновить импорты:
# Было:
# from .base import BaseAdapter
# Стало:
# from ..adapters.base import BaseAdapter
# или лучше:
# from src.adapters.base import BaseAdapter
# Перепроверить
python3 system/scripts/audit_imports.py | grep messenger
# Найти недостающий пакет
bash system/scripts/audit_imports_quick.sh module telegram
# Результат: telegram, telegram.ext требуются
# Установить пакет
pip install python-telegram-bot
# Добавить в requirements.txt
echo "python-telegram-bot>=20.0" >> requirements.txt
# Перепроверить
python3 system/scripts/audit_imports.py | grep telegram
import csv
import json
# Прочитать CSV отчёт
errors = []
with open('system/scripts/audit_imports_report.csv') as f:
reader = csv.DictReader(f)
for row in reader:
if row['TYPE'].startswith('ERROR_'):
errors.append(row)
# Экспортировать в JSON
with open('import_errors.json', 'w') as f:
json.dump(errors, f, indent=2)
print(f"Экспортировано {len(errors)} ошибок в import_errors.json")
# Простой анализ циклических импортов
import ast
from collections import defaultdict
deps = defaultdict(set)
# Проанализировать файлы и собрать граф зависимостей
# (детали в ImportAuditor.find_circular_dependencies)
# Найти циклы (DFS алгоритм)
def find_cycles(graph):
visited = set()
rec_stack = set()
cycles = []
def dfs(node, path):
visited.add(node)
rec_stack.add(node)
path.append(node)
for neighbor in graph.get(node, []):
if neighbor not in visited:
dfs(neighbor, path[:])
elif neighbor in rec_stack:
cycle = path[path.index(neighbor):] + [neighbor]
cycles.append(cycle)
rec_stack.remove(node)
for node in graph:
if node not in visited:
dfs(node, [])
return cycles
# Используя graphviz (если установлен)
pip install graphviz
# Создать граф из CSV отчёта
python3 << 'PYTHON'
import csv
edges = set()
with open('system/scripts/audit_imports_report.csv') as f:
reader = csv.DictReader(f)
for row in reader:
if row['TYPE'] == 'ERROR_MODULE_NOT_FOUND':
file = row['FILE'].split('/')[0] # directory
module = row['MODULE'].split('.')[0] # first part
edges.add((file, module))
# Вывести в формате DOT
print("digraph imports {")
for src, dst in sorted(edges)[:50]: # первые 50
print(f' "{src}" -> "{dst}";')
print("}")
PYTHON
# Сохранить в файл и открыть
# dot -Tsvg imports.dot -o imports.svg
# # открыть imports.svg
# .github/workflows/import-audit.yml
name: Import Audit
on: [push, pull_request]
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Run import audit
run: python3 system/scripts/audit_imports.py
- name: Upload report
if: failure()
uses: actions/upload-artifact@v3
with:
name: import-audit-report
path: system/scripts/audit_imports_report.csv
# Проверить что файл существует
ls -la library/connectors/api/ozon/__init__.py
# Добавить __init__.py если нет
touch library/connectors/api/ozon/__init__.py
# Проверить PYTHONPATH
echo $PYTHONPATH
# Добавить в переменную если нужно
export PYTHONPATH=/opt/claude-workspace:$PYTHONPATH
# Дать права на исполнение
chmod +x system/scripts/audit_imports.py
chmod +x system/scripts/audit_imports_quick.sh
# Проверить владельца
ls -la system/scripts/audit_imports.py
# Разбить на части - проверить только library
python3 << 'PYTHON'
from pathlib import Path
import sys
sys.path.insert(0, '/opt/claude-workspace')
from system.scripts.audit_imports import ImportAuditor
workspace = Path('/opt/claude-workspace')
auditor = ImportAuditor(workspace)
auditor.run(['library']) # только library
PYTHON
═════════════════════════════════════════════════════════════════════════════════