fix: uptime читается с bot._start_time вместо Cog

Проблема: _start_time хранился в Status Cog, но консольная
команда искала его на объекте bot — всегда получала fallback
time.time() и показывала 0с.

Решение: _start_time устанавливается в BotRunner.__init__ на
объекте bot. Cog и console_command читают getattr(bot, '_start_time').

Изменено: bot.py, commands/status.py, console_commands/status.py,
tests/test_commands_status.py
This commit is contained in:
deadzilla 2026-06-12 16:32:55 +05:00
parent 91f34625a8
commit f2844f0453
4 changed files with 11 additions and 17 deletions

3
bot.py
View File

@ -30,7 +30,10 @@ class BotRunner:
"""Управляет жизненным циклом бота."""
def __init__(self) -> None:
import time
self.bot = commands.Bot(command_prefix="!", intents=intents)
self.bot._start_time = time.time()
self.stop_event = threading.Event()
self.bot_ready = threading.Event()
self.scheduler: SchedulerType | None = None

View File

@ -7,14 +7,12 @@ from discord.ext import commands
class Status(commands.Cog):
"""Команда !status — статус бота, пинг, uptime"""
def __init__(self):
self._start_time = time.time()
@commands.command(name="status")
async def status(self, ctx):
"""Статус бота: пинг к Discord gateway и время работы"""
latency_ms = round(ctx.bot.latency * 1000, 1)
uptime_seconds = time.time() - self._start_time
start_time = getattr(ctx.bot, "_start_time", time.time())
uptime_seconds = time.time() - start_time
uptime_str = self._format_uptime(uptime_seconds)
embed = discord.Embed(

View File

@ -7,7 +7,8 @@ def status(stop_event, bot):
return None
latency_ms = round(bot.latency * 1000, 1)
uptime_seconds = time.time() - getattr(bot, "_start_time", time.time())
start_time = getattr(bot, "_start_time", time.time())
uptime_seconds = time.time() - start_time
uptime_str = _format_uptime(uptime_seconds)
print("\n" + "=" * 40)

View File

@ -8,24 +8,16 @@ from unittest.mock import AsyncMock, MagicMock, patch
class TestStatusCommand:
"""Тесты Discord-команды status."""
def _make_cog(self, start_time=None):
"""Создать Status cog с моком времени."""
from commands.status import Status
cog = Status()
if start_time is not None:
cog._start_time = start_time
return cog
async def test_status_sends_embed(self):
"""Команда status отправляет embed-сообщение."""
from commands.status import Status
mock_ctx = MagicMock()
mock_ctx.bot.latency = 0.042
mock_ctx.bot._start_time = time.time()
mock_ctx.send = AsyncMock(return_value=None)
cog = self._make_cog()
cog = Status()
await cog.status(cog, mock_ctx)
mock_ctx.send.assert_awaited_once()
@ -40,10 +32,10 @@ class TestStatusCommand:
mock_ctx = MagicMock()
mock_ctx.bot.latency = 0.050
mock_ctx.bot._start_time = time.time() - 90061 # 1д 1ч 1м 1с
mock_ctx.send = AsyncMock(return_value=None)
start = time.time() - 90061 # 1д 1ч 1м 1с
cog = self._make_cog(start_time=start)
cog = Status()
await cog.status(cog, mock_ctx)
call_args = mock_ctx.send.call_args