fix: исправлена сериализация format и text в SendMessage/EditMessage#91
Conversation
- format.value → format: убран .value, так как TextFormat наследует StrEnum и сериализуется как строка автоматически (send_message.py, edit_message.py) - text: null не отправляется когда text is None (send_message.py) - устранён двойной DeprecationWarning для parse_mode в bot.send_message и bot.edit_message — передаётся parse_mode=None после resolve_format
| json["notify"] = self.notify | ||
| if self.format is not None: | ||
| json["format"] = self.format.value | ||
| json["format"] = self.format |
There was a problem hiding this comment.
Замечание такое же, как к упомянутому ранее PR: нужны тесты с прямой передачей текста в качестве значения (не enum, а именно текста)
Регрессионные тесты для SendMessage и EditMessage, проверяющие что format="html" (строка) корректно сериализуется в JSON без AttributeError. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
PR направлен на исправление сериализации параметров форматирования/текста при отправке и редактировании сообщений, а также на устранение дублирующего DeprecationWarning при использовании parse_mode.
Changes:
SendMessage/EditMessage:formatсериализуется без.value,text=Noneбольше не отправляется в JSON.Bot.send_message/Bot.edit_message: устранено двойное предупреждение дляparse_modeза счёт передачиparse_mode=Noneв методы послеresolve_format.- Дополнительно внесены изменения в обработку update/context и логирование (не отражены в описании PR).
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_format_parameter.py | Добавлены регрессионные тесты на поддержку строкового format. |
| maxapi/methods/send_message.py | Условное добавление text в JSON и сериализация format без .value. |
| maxapi/methods/edit_message.py | Сериализация format без .value. |
| maxapi/bot.py | Изменена прокидка parse_mode (для предупреждений), добавлен __repr__. |
| maxapi/types/updates/user_added.py | get_ids() теперь возвращает user_id добавленного пользователя. |
| maxapi/types/updates/user_removed.py | get_ids() теперь возвращает user_id удалённого пользователя. |
| maxapi/utils/updates.py | Добавлен logger (пока не используется). |
| maxapi/dispatcher.py | Добавлено debug-логирование при LRU-вытеснении контекстов. |
| maxapi/context/context.py | MemoryContext.get_data() возвращает копию данных контекста. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| from __future__ import annotations | ||
|
|
||
| import logging | ||
| from typing import TYPE_CHECKING |
There was a problem hiding this comment.
В модуле добавлен logger = logging.getLogger(__name__), но он нигде не используется. Лучше убрать его (и импорт logging), либо начать реально использовать для логирования внутри enrich_event()/_resolve_*, чтобы не оставлять мёртвый код.
| пользователя. | ||
| """ | ||
|
|
||
| return self.chat_id, self.admin_id | ||
| return self.chat_id, self.user.user_id |
There was a problem hiding this comment.
Изменение get_ids() на (chat_id, removed_user_id) меняет ключ контекста в Dispatcher.handle() для события USER_REMOVED. При этом в maxapi/utils/updates.py::_resolve_from_user() для UserRemoved отправителем считается admin_id (если он есть), и раньше get_ids() был согласован с этим. Сейчас from_user (админ) и context.user_id (удалённый пользователь) будут расходиться, что может ломать state/context-логику обработчиков. Нужна единая семантика: либо возвращать admin_id когда он задан, либо обновить _resolve_from_user()/документацию так, чтобы from_user и get_ids() соответствовали одному и тому же пользователю.
| if self.text is not None: | ||
| json["text"] = self.text |
There was a problem hiding this comment.
Поведение изменилось: при text=None поле text больше не включается в JSON (и это важно для отправки «только вложения»). В текущих тестах файла уже проверяется сериализация format, но нет теста на то, что ключ text отсутствует при text=None. Стоит добавить регрессионный тест, чтобы это поведение не сломалось в будущем.
| def __repr__(self) -> str: | ||
| return "Bot(token='***')" | ||
|
|
There was a problem hiding this comment.
Описание PR сфокусировано на сериализации format/text и устранении двойного DeprecationWarning, но в diff также есть несвязанные изменения (например, Bot.__repr__, копирование данных контекста, логирование LRU-вытеснения, изменение get_ids() у update-моделей). Лучше отразить эти изменения в описании или вынести их в отдельный PR, чтобы ревью и релиз-ноты были прозрачнее.
- str(self.format) handles plain string without AttributeError - text=None no longer included in JSON body (SendMessage) - removed unused logger import from utils/updates.py - added tests: format as string, text=None regression Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
…t_ids Covers 3 lines missing from Codecov patch coverage report on PR love-apples#91: - Bot.__repr__ — verifies token is masked as '***' - UserAdded.get_ids() — verifies returns (chat_id, user.user_id) - UserRemoved.get_ids() — verifies returns (chat_id, user.user_id) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Возвращён self.format.value в send_message и edit_message (как на main) - В __init__ добавлена конвертация строки в TextFormat/ParseMode enum для обратной совместимости — пользователь может передать "html" вместо TextFormat.HTML - Добавлен ClassVar[dict] для class-level _USER в test_types.py (RUF012) - Обновлены тесты под новое поведение
Описание
1.
format.value→formatв SendMessage и EditMessageФайлы:
methods/send_message.py,methods/edit_message.pyself.format.valueвызывалAttributeErrorпри передаче строки вместоTextFormatenum. ПосколькуTextFormatнаследуетStrEnum, enum-значение можно использовать напрямую — оно сериализуется как строка автоматически.2.
text: nullбольше не отправляется безусловноФайл:
methods/send_message.pyРанее
json["text"] = self.textвыполнялось безусловно, даже приtext=None. Вedit_message.pyаналогичный код был обёрнут вif self.text is not None:. Приведено к единообразию — при отправке сообщения только с вложениямиtextне включается в тело запроса.3. Устранён двойной
DeprecationWarningдляparse_modeФайлы:
bot.pyПри вызове
bot.send_message(parse_mode=X)предупреждение выводилось дважды: вresolve_format()и вSendMessage.__init__(). Причина —parse_modeпередавался вSendMessageпосле того какformatуже был resolved. Теперь передаётсяparse_mode=None.Тестирование