discordBot/ISSUES.md

9.9 KiB
Raw Blame History

ISSUES — Задачи и баг-трекер


Открытые задачи

Средний приоритет

  • Отсутствует pyproject.toml — проект использует requirements.txt + requirements-dev.txt без единого файла конфигурации. Рекомендуется pyproject.toml с [project], настройками ruff и pytest

  • Scheduler._task без add_done_callback — если _scheduler_loop завершится unexpectedly (не через CancelledError), это не будет залогировано. Добавить callback для логирования нештатного завершения task

  • Тест test_fetch_weather_http_error_no_fallback — raises bare Exception вместо requests.HTTPError — в реальности raise_for_status() бросает requests.HTTPError, который ловится except requests.RequestException и корректно переходит на fallback. Тест проверяет несуществующий сценарий

Низкий приоритет

  • commands/stats.py — list comprehension вместо generatorlen([ch for ch in guild.channels if ...]) создаёт временный список. Заменить на sum(1 for ch in guild.channels if ...)

  • TextHelpCommand.send_bot_help() — дублирование логики — ветки if cog_or_none is None и else делают одинаковую работу по итерации команд. Объединить в общий цикл

  • commands/morning.py не ловит исключения run_morning — если run_morning выбросит, лог !morning завершен не запишется, а ошибка уйдёт в on_command_error. Добавить try/except для локальной обработки и логирования

  • Файл nul в корне проекта — артефакт Windows (29 байт). Удалить из рабочей директории


Завершено

  • Эмодзи в embed-сообщениях — удалены 🌅, , из utils/morning_runner.py
  • f-string в logger — замена на %-формат в bot.py
  • import time внутри __init__ — перенесён на уровень модуля в bot.py
  • Проверка наличия .env.env в .gitignore, есть .env.example
  • Команда !msg в BotRunner — удалена из проекта
  • Отсутствует .gitignore — файл существует
  • Отсутствует Dockerfile — файл существует
  • Отсутствует .env.example — файл существует
  • Type hints в production-коде — добавлены аннотации ко всем 20 функциям
  • asyncio.iscoroutinefunction deprecated — monkey-patch в bot.py + conftest.py
  • Утечка корутины Scheduler в тестах — mock _start_scheduler вместо asyncio.create_task
  • Graceful shutdown (SIGTERM) — реализован через on_shutdown listener + async with self.bot
  • Пустой __init__ в Morning — удалён
  • Global RateLimiter на модульном уровне — добавлены factory-функции make_*_limiter()
  • Type hints в тестах — добавлены -> None ко всем 140 test-функциям
  • import внутри функций в тестах — вынесены наверх модулей (35 вхождений)
  • Добавить pre-commit хуки.pre-commit-config.yaml (ruff + ruff-format), requirements-dev.txt
  • Интеграционные тесты — 9 тестов загрузок когов, команд и утилит
  • format_weather_for_embed отсутствует в коде — заменено на format_weather_for_message в README.md
  • _WEATHER_MAPPING не отсортирован по убыванию длины ключей — отсортирован список по убыванию len(key), добавлен комментарий (utils/pogoda.py)
  • Глобальные requests.Session не закрываются — добавлена close_all_sessions() в utils/__init__.py, вызов из _on_shutdown в bot.py
  • run_morning fallback может отправить дайджест в несколько каналов — fallback перебирает каналы целевого сервера вместо bot.get_all_channels() (utils/morning_runner.py)
  • !nw: последовательные вызовы API вместо параллельных — заменено на asyncio.gather() (commands/news.py)
  • format_weather_data_for_console выводит None в текст — добавлена явная проверка is None для всех полей (utils/pogoda.py), обновлён тест (tests/test_commands_pg.py)
  • _parse_date хрупкий fallback — валидация формата через regex, ISO даты конвертируются в DD.MM.YYYY (utils/news.py)
  • wmo_to_russian создаёт dict на каждый вызов — вынесен в константу _WMO_MAPPING (utils/pogoda.py)
  • TextHelpCommand пропускает команды без cog — standalone-команды показываются если не hidden (bot.py)
  • translate_weather(" ") возвращает пробелы — добавлен .strip() перед проверкой (utils/pogoda.py)
  • pressure_to_mmhg(mb: Any) — заменён на float | int | str | None (utils/pogoda.py)
  • conftest.py и bot.py дублируют monkey-patch — вынесен в utils/compat.py, оба файла импортируют оттуда
  • RateLimiter тесты зависят от реального времени — добавлен _time_func параметр, все тесты используют контролируемую функцию времени
  • Dockerfile не копирует conftest.pyconftest.py убран из Dockerfile (тестовый файл не нужен в production)
  • requirements.txt без пиннинга версий>= заменён на ~= (compatible release)
  • Закомментированный тест pressure_to_mmhg(0) — удалена устаревшая закомментированная строка
  • format_articles(None) бросает TypeError — добавлена валидация None, graceful fallback с сообщением
  • setup_logging() создаёт дублирующиеся handlers — добавлен root.handlers.clear() (utils/logger.py)
  • Первый logger.info() теряетсяsetup_logging() вызывается до первого лога (bot.py)
  • translate_weather() уязвим к ложным substring-совпадениям — точное совпадение приоритизируется (utils/pogoda.py)
  • fromstring импортирован внутри функции fetch_rss — вынесен на уровень модуля (utils/news.py)
  • Scheduler._start_scheduler() создаёт task синхронно__init__ больше не создаёт task; start() стал async-методом (utils/morning_runner.py, bot.py)
  • Pg.__init__ хранит self.api_url как инстанс-переменную — удалён __init__, используется API_URL_WEATHER напрямую (commands/pg.py)
  • fetch_cat() не передаёт x-api-key — добавлена поддержка CAT_API_KEY из окружения, заголовок x-api-key передаётся при наличии ключа (utils/cat.py)
  • Глобальные экземпляры RateLimiter + factory-функции — дизайн подтверждён: глобальные синглтоны для production, factory-функции для тестов. Добавлен поясняющий комментарий (utils/rate_limiter.py)
  • @pytest.mark.asyncio избыточен — удалены 5 декораторов из tests/test_integration.py (pytest.ini имеет asyncio_mode = auto)
  • Dockerfile не копирует tests/ — отклонено: Docker — production-окружение, тесты туда не нужны
  • Приватные атрибуты на объекте ботаSTART_TIME вынесен на уровень модуля bot.py, self.bot._scheduler удалён (не использовался). Обновлены commands/status.py и тесты
  • Избыточная проверка ctx в on_command_error — удалены проверки ctx and, так как ctx гарантированно передан discord.py (bot.py)
  • ruff format --check падает на 5 файлах — применён ruff format к 7 файлам
  • commands/news.py — дублирование кода для статей и постов — вынесено в _format_feed_section() (commands/news.py)
  • Город захардкожен в API_URL_WEATHER — вынесен в WEATHER_CITY env-переменную, шаблон "Погода: {city}:" (utils/pogoda.py, .env.example)