Skip to content

fix: исправлена сериализация format и text в SendMessage/EditMessage#91

Merged
love-apples merged 5 commits intolove-apples:mainfrom
bish-x:fix/message-format-fixes
Apr 11, 2026
Merged

fix: исправлена сериализация format и text в SendMessage/EditMessage#91
love-apples merged 5 commits intolove-apples:mainfrom
bish-x:fix/message-format-fixes

Conversation

@bish-x
Copy link
Copy Markdown
Contributor

@bish-x bish-x commented Apr 8, 2026

Описание

1. format.valueformat в SendMessage и EditMessage

Файлы: methods/send_message.py, methods/edit_message.py

self.format.value вызывал AttributeError при передаче строки вместо TextFormat enum. Поскольку TextFormat наследует StrEnum, enum-значение можно использовать напрямую — оно сериализуется как строка автоматически.

Связано с #89 — данный PR расширяет фикс на edit_message.py, который не был затронут в PR #89.

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.

Тестирование

  • Все существующие тесты проходят
  • ruff check / ruff format — без замечаний

- 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
Comment thread maxapi/methods/edit_message.py Outdated
json["notify"] = self.notify
if self.format is not None:
json["format"] = self.format.value
json["format"] = self.format
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Замечание такое же, как к упомянутому ранее PR: нужны тесты с прямой передачей текста в качестве значения (не enum, а именно текста)

Регрессионные тесты для SendMessage и EditMessage,
проверяющие что format="html" (строка) корректно
сериализуется в JSON без AttributeError.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread maxapi/utils/updates.py
Comment on lines 1 to 4
from __future__ import annotations

import logging
from typing import TYPE_CHECKING
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В модуле добавлен logger = logging.getLogger(__name__), но он нигде не используется. Лучше убрать его (и импорт logging), либо начать реально использовать для логирования внутри enrich_event()/_resolve_*, чтобы не оставлять мёртвый код.

Copilot uses AI. Check for mistakes.
Comment thread maxapi/methods/send_message.py Outdated
Comment thread maxapi/methods/edit_message.py Outdated
Comment on lines 34 to +37
пользователя.
"""

return self.chat_id, self.admin_id
return self.chat_id, self.user.user_id
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Изменение 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() соответствовали одному и тому же пользователю.

Copilot uses AI. Check for mistakes.
Comment on lines +118 to +119
if self.text is not None:
json["text"] = self.text
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Поведение изменилось: при text=None поле text больше не включается в JSON (и это важно для отправки «только вложения»). В текущих тестах файла уже проверяется сериализация format, но нет теста на то, что ключ text отсутствует при text=None. Стоит добавить регрессионный тест, чтобы это поведение не сломалось в будущем.

Copilot uses AI. Check for mistakes.
Comment thread maxapi/bot.py
Comment on lines +203 to +205
def __repr__(self) -> str:
return "Bot(token='***')"

Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Описание PR сфокусировано на сериализации format/text и устранении двойного DeprecationWarning, но в diff также есть несвязанные изменения (например, Bot.__repr__, копирование данных контекста, логирование LRU-вытеснения, изменение get_ids() у update-моделей). Лучше отразить эти изменения в описании или вынести их в отдельный PR, чтобы ревью и релиз-ноты были прозрачнее.

Copilot uses AI. Check for mistakes.
- 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
Copy link
Copy Markdown

codecov Bot commented Apr 9, 2026

Codecov Report

❌ Patch coverage is 90.90909% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
maxapi/methods/edit_message.py 83.33% 1 Missing ⚠️
maxapi/methods/send_message.py 85.71% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

bish-x and others added 2 commits April 9, 2026 19:06
…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)
- Обновлены тесты под новое поведение
@love-apples love-apples merged commit 0e8fefe into love-apples:main Apr 11, 2026
13 checks passed
@bish-x bish-x mentioned this pull request Apr 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants